/*
* Copyright 2015 Anyware Services
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This helper is used to import a skin from a ZIP file. See #open method.
*/
Ext.define("Ametys.plugins.web.skin.helper.ImportSkinUI", {
singleton: true,
/**
* @private
* @property {Function} _cbFn Callback function to execute after import
*/
/**
* @private
* @property {Ametys.window.DialogBox} _box The dialog box
*/
/**
* @private
* @property {Ext.form.FormPanel} _formPanel The form of the dialog box
*/
/**
* Open the dialog box for import
* @param {Object} config The configuration object
* @param {String} config.url (required) The url to submit form
* @param {Function} config.importFn (required) The function to do import. Parameters are:
* @param {Object} config.importFn.result The import result
* @param {Object} config.importFn.box The import dialog box
* @param {String} [config.importErrorMsg] The error message in case of failure
* @param {Function} [config.existFn] A function to test existence of a file to upload. Parameters are:
* @param {String[]} config.existFn.params Array of parameters. Only contains the filename (without extension) to upload.
* @param {Function} config.existFn.callback The callback function to call after checking existence
* @param {Boolean} config.existFn.callback.exists true if the file exists, false otherwise
* @param {String} [config.existConfirmTitle] The title of confirm dialog if the file already exists
* @param {String} [config.existConfirmDesc] The description of confirm dialog if the file already exists
* @param {String} [config.title] The dialog box title
* @param {String} [config.icon] The dialog box icon
* @param {String} [config.helpMsg] The dialog box hint
*/
open: function (config)
{
this._importFn = config.importFn;
this._url = config.url;
this._errorMsg = config.importErrorMsg || "{{i18n PLUGINS_WEB_ADMINISTRATOR_SKINS_HANDLE_IMPORT_ERROR}}";
this._title = config.title || "{{i18n PLUGINS_WEB_ADMINISTRATOR_IMPORT_DIALOG_CAPTION}}";
this._existFn = config.existFn;
this._existConfirmTitle = config.existConfirmTitle || "{{i18n PLUGINS_WEB_ADMINISTRATOR_IMPORT_TEST_EXIST_ALERT}}";
this._existConfirmDesc = config.existConfirmDesc || "{{i18n PLUGINS_WEB_ADMINISTRATOR_IMPORT_TEST_EXIST_ALERT_DESC}}";
this._delayedInitialize(this._title, config.icon || Ametys.getPluginResourcesPrefix("web") + '/img/administrator/skins/import_16.png', config.helpMsg || "{{i18n PLUGINS_WEB_ADMINISTRATOR_IMPORT_DIALOG_HINT}}");
this._box.show();
},
/**
* Initialize the dialog box
* @param {String} title The title of the dialog box.
* @param {String} icon The full path to icon (16x16 pixels) for the dialog box
* @param {String} helpmessage The message displayed at the top of the dialog box.
* @private
*/
_delayedInitialize: function (title, icon, helpmessage)
{
if (!this._initialized)
{
this._box = Ext.create('Ametys.window.DialogBox', {
title: title,
icon: icon,
width: 430,
scrollable: true,
layout: 'fit',
items: [{
xtype: 'form',
border: false,
defaults: {
cls: 'ametys',
labelAlign: 'top',
labelSeparator: ''
},
items: [{
xtype: 'component',
cls: 'a-text',
html: helpmessage
},
{
xtype: 'filefield',
name: 'importfile',
id: 'importfile-file',
fieldLabel: "{{i18n PLUGINS_WEB_ADMINISTRATOR_IMPORT_DIALOG_FILE}} *",
allowBlank: false,
emptyText: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_FILEUPLOAD_FIELD_EMPTYTEXT}}",
buttonText: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_FILEUPLOAD_FIELD_BUTTONTEXT}}",
width: 370,
listeners: {'change': {fn: this._selectFile, scope: this}}
}
]
}
],
defaultFocus: 'importfile',
closeAction: 'hide',
buttons: [{
text :"{{i18n plugin.core-ui:PLUGINS_CORE_UI_FILEUPLOAD_BOX_OK}}",
disabled: true,
handler : Ext.bind(this._validate, this)
}, {
text :"{{i18n plugin.core-ui:PLUGINS_CORE_UI_FILEUPLOAD_BOX_CANCEL}}",
handler: Ext.bind(function() {this._box.hide();}, this)
}]
});
this._initialized = true;
}
else
{
this._box.down('#importfile-file').reset();
this._box.setIcon(icon);
this._box.setTitle(title);
this._box.down('form').items.get(0).update(helpmessage);
}
},
/**
* Function called when the file input change
* @param {Ext.form.field.File} input The file input
* @param {String} name The file name
* @private
*/
_selectFile: function (input, name)
{
// _uploading boolean is used to prevent to execution of this code twice, because for some reasons, in IE, the
// change event is raised again when the form is submitted (with an empty value)
if (!this._uploading)
{
var disabled = !Ext.String.endsWith(name, '.zip', true);
this._box.getDockedItems('toolbar[dock="bottom"]')[0].items.get(0).setDisabled(disabled);
if (disabled)
{
Ametys.log.ErrorDialog.display({
title: "{{i18n plugin.web:PLUGINS_WEB_ADMINISTRATOR_IMPORT_SUBMIT_ZIP_ERROR}}",
text: "{{i18n plugin.web:PLUGINS_WEB_ADMINISTRATOR_IMPORT_SUBMIT_ZIP_ERROR_DESC}}",
details: "",
category: this.self.getName()
});
}
}
},
/**
* Handler for the 'ok' button of the dialog box
* @private
*/
_validate: function ()
{
var form = this._box.down('form').getForm();
if (!form.isValid())
{
return;
}
// Check existence first
if (Ext.isFunction (this._existFn))
{
var filename = form.findField("importfile").getValue();
filename = filename.substring(0, filename.length - 4);
this._existFn ([filename], this._existCb);
}
else
{
// Submit form
this._submit();
}
},
/**
* @private
* Submit the form
*/
_submit: function ()
{
this._uploading = true;
this._box.down('form').getForm().submit({
url: this._url,
params: {
contextualParameters: Ext.JSON.encode(Ametys.getAppParameters())
},
waitTitle: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_FILEUPLOAD_SUBMITFORM_TITLE}}",
waitMsg: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_FILEUPLOAD_SUBMITFORM_MSG}}",
success: Ext.bind(this._submitSuccess, this),
failure: Ext.bind(this._submitFailure, this)
});
},
/**
* @private
* Callback function invoked after testing existence
* @param {Boolean} exists True if a file with same name already exists
*/
_existCb: function (exists)
{
if (!exists)
{
// Submit form
this._submit();
}
else
{
// Replace existing skin ?
Ametys.Msg.confirm (this._existConfirmTitle,
this._existConfirmDesc,
this._confirmUpdate,
this
);
}
},
/**
* @private
* Callback function invoked after #_existCb confirm dialog box
* @param {String} answer The user answer
*/
_confirmUpdate: function (answer)
{
if (answer == 'yes')
{
this._submit();
}
},
/**
* Callback for the "cancel" button of the dialog. Close the dialog.
* @private
*/
_cancel: function ()
{
this._box.hide();
},
/**
* The function to call when {@link #_submit} succeeded.
* @param {Ext.form.Basic} form The form that requested the submit action
* @param {Ext.form.action.Action} action The Action class.
*/
_submitSuccess: function (form, action)
{
this._uploading = false;
if (this._importFn)
{
this._box.hide();
Ext.Function.defer (this._importFn, 0, null, [action.result]);
}
},
/**
* The function to call when {@link #_submit} failed.
* @param {Ext.form.Basic} form The form that requested the submit action
* @param {Ext.form.action.Action} action The Action class.
*/
_submitFailure: function (form, action)
{
this._uploading = true;
if (action.result.error == "rejected")
{
Ametys.log.ErrorDialog.display({
title: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_FILEUPLOAD_ERROR_MSG}}",
text: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_FILEUPLOAD_ERROR_FILEREJECTED}}",
details: "",
category: this.self.getName()
});
}
else
{
Ametys.log.ErrorDialog.display({
title: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_FILEUPLOAD_ERROR_MSG}}",
text: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_FILEUPLOAD_ERROR_ON_SERVER}}",
details: action.result.error ? action.result.error.message + "\n" + action.result.error.stacktrace : "",
category: this.self.getName()
});
}
}
});