/*
* 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.
*/
/**
* Singleton class defining the actions related to the welcoming message of the application
* @private
*/
Ext.define('Ametys.plugins.admin.system.SystemActions', {
singleton: true,
/**
* @private
* @property {String} _mode The current mode when opening the edition dialog box {@link #_box}. Can be 'new' or 'edit'.
*/
/**
* @private
* @property {Boolean} _initialized Determine if the dialog box {@link #_box} for editing announce is initialized
*/
/**
* @private
* @property {Ext.form.Panel} _form The form panel in the dialog box {@link #_box} for editing
*/
/**
* @private
* @property {Ametys.window.DialogBox} _box The dialog box for editing
*/
/**
* Activate/deactivate the system announcement
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller
*/
setAnnouncementAvailable: function(controller)
{
var enable = !controller.isPressed();
var disableSchedule = false;
// Do not toggle if current state is scheduled.
// Only remove the schedule
if (controller.state == 'scheduled')
{
enable = !enable;
disableSchedule = true;
}
Ametys.data.ServerComm.callMethod({
role: "org.ametys.runtime.plugins.admin.system.SystemHelper",
methodName: "setAnnouncementAvailable",
parameters: [enable],
callback: {
scope: this,
handler: this._enableAnnoucementCB,
arguments: {
state: enable ? 'on' : 'off',
// Keep the date to initialize the form in case the click was a mistake
startDate: controller.startDate,
endDate: controller.endDate,
disableSchedule: disableSchedule
}
},
errorMessage: {
category: this.self.getName(),
msg: "{{i18n PLUGINS_ADMIN_SYSTEM_ERROR_SAVE}}"
}
});
},
/**
* @private
* Callback called after enabling/disabling system announcement
* @param {Object} response the server's response
* @param {Object} args the callback arguments
*/
_enableAnnoucementCB: function(response, args)
{
Ext.create('Ametys.message.Message', {
type: Ametys.message.Message.MODIFIED,
targets: [{
id: 'system-announcement',
parameters: {
state: args.state,
startDate: args.startDate,
endDate: args.endDate
}
}]
});
if (args.disableSchedule)
{
Ametys.notify({
title: "{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_UNSCHEDULE_NOTIFICATION_TITLE}}",
description: "{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_UNSCHEDULE_NOTIFICATION_DESCRIPTION}}"
});
}
this.forceSystemAnnounceUpdate();
},
/**
* This method send a fake request to server to force the update of system announcement on the local HMI
*/
forceSystemAnnounceUpdate: function()
{
// We need to send a server request (whatever the request) to force the HMI update
Ametys.data.ServerComm.callMethod({
role: "org.ametys.runtime.plugins.admin.system.SystemHelper",
methodName: "isSystemAnnouncementAvailable",
parameters: []
});
},
/**
* Schedule a system announcement
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller
*/
scheduleAnnouncement: function(controller)
{
if (!this._delayInitializeScheduleBox())
{
return;
}
this._scheduleBox.show();
this._initScheduleForm(controller.startDate, controller.endDate);
},
_delayInitializeScheduleBox: function()
{
if (this._scheduledInitialized)
{
return true;
}
this._scheduleForm = Ext.create('Ext.form.Panel', {
border: false,
defaults : {
cls: 'ametys',
msgTarget: 'side',
labelAlign: 'top',
labelSeparator: ''
},
items : [
{
html: "{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_SCHEDULE_DIALOG_CAPTION}}"
},
{
xtype: 'datetime',
fieldLabel :"{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_START_DATE}}",
ametysDescription: "{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_START_DATE_HELP}}",
name: 'start-date',
},
{
xtype: 'datetime',
fieldLabel :"{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_END_DATE}}",
ametysDescription: "{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_END_DATE_HELP}}",
name: 'end-date',
},
]
});
this._scheduleBox = Ext.create('Ametys.window.DialogBox', {
title :"{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_SCHEDULE_DIALOG}}",
iconCls: 'ametysicon-megaphone19',
layout :'fit',
width: 450,
items : [this._scheduleForm],
closeAction: 'hide',
referenceHolder: true,
defaultButton: 'okButton',
buttons : [{
reference: 'okButton',
text :"{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_DIALOG_OK}}",
handler : Ext.bind(this._scheduleOk, this)
}, {
text :"{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_DIALOG_CANCEL}}",
handler : function () {this._scheduleBox.hide();},
scope: this
}]
});
this._scheduledInitialized = true;
return true;
},
_initScheduleForm: function(startDate, endDate)
{
var form = this._scheduleForm.getForm();
form.setValues({"start-date": startDate, "end-date": endDate});
},
_scheduleOk: function()
{
var form = this._scheduleForm.getForm();
if (!form.isValid())
{
return;
}
var startDate = form.findField('start-date').getValue();
var endDate = form.findField('end-date').getValue();
// Check date consistency
if (!Ext.isEmpty(endDate) && !Ext.isEmpty(startDate) && endDate.getTime() - startDate.getTime() <= 0)
{
form.findField('end-date').markInvalid ("{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_SCHEDULE_DIALOG_INTERVAL_ERROR}}");
return;
}
var formValues = form.getValues();
this._scheduleAnnoucement(formValues);
},
_scheduleAnnoucement: function(formValues)
{
Ametys.data.ServerComm.callMethod({
role: "org.ametys.runtime.plugins.admin.system.SystemHelper",
methodName: "scheduleAnnouncement",
parameters: [formValues['start-date'], formValues['end-date']],
callback: {
scope: this,
handler: this._scheduleAnnoucementCB,
arguments: {
state: 'scheduled',
startDate: formValues['start-date'] != "" ? formValues['start-date'] : null,
endDate: formValues['end-date'] != "" ? formValues['end-date'] : null
}
},
errorMessage: {
category: this.self.getName(),
msg: "{{i18n PLUGINS_ADMIN_SYSTEM_ERROR_SAVE}}"
}
});
},
_scheduleAnnoucementCB: function()
{
this._scheduleBox.hide();
this._enableAnnoucementCB.apply(this, arguments);
},
/**
* Add a message
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
addMessage: function(controller)
{
this._mode = 'new';
if (!this._delayedInitialize())
{
return;
}
this._box.show();
this._initForm();
},
/**
* Edit the current selected message
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
editMessage: function (controller)
{
var target = controller.getMatchingTargets()[0];
if (target != null)
{
var targetParameters = target.getParameters();
this._mode = 'edit';
if (!this._delayedInitialize())
{
return;
}
this._box.show();
this._initForm(targetParameters.language, targetParameters.message);
}
},
/**
* Delete the current selected message
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
deleteMessage: function (controller)
{
var target = controller.getMatchingTargets()[0];
if (target != null)
{
Ametys.Msg.confirm ("{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_DELETE_LABEL}}",
"{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_DELETE_CONFIRM}}",
Ext.bind(this._confirmDelete, this, [target.getParameters().language], 1));
}
},
/**
* @private
* The callback after the delete confirmation messagebox
* @param {String} answer If "yes" the process will continue.
* @param {String} lang The message to delete identified by its language code.
*/
_confirmDelete: function (answer, lang)
{
if (answer == 'yes')
{
Ametys.data.ServerComm.callMethod({
role: "org.ametys.runtime.plugins.admin.system.SystemHelper",
methodName: "deleteAnnouncement",
parameters: [lang],
callback: {
scope: this,
handler: this._deleteCb,
arguments: {language: lang}
},
errorMessage: {
category: this.self.getName(),
msg: "{{i18n PLUGINS_ADMIN_SYSTEM_ERROR_SAVE}}"
}
});
}
},
/**
* @private
* Callback for the deletion process
* @param {Object} response the server's response
* @param {Object} args the callback arguments
* @param {String} args.language the deleted language
*/
_deleteCb: function(response, args)
{
Ext.create('Ametys.message.Message', {
type: Ametys.message.Message.DELETED,
targets: [{
id: 'system-announcement-message',
parameters: {
language: args.language
}
}]
});
},
/**
* @private
* Initialize the dialog box
*/
_delayedInitialize: function ()
{
if (this._initialized)
{
return true;
}
this._form = Ext.create('Ext.form.Panel', {
border: false,
defaults : {
cls: 'ametys',
labelWidth: 70,
width: 200,
msgTarget: 'side',
anchor:'90%',
xtype: 'textfield'
},
items : [ {
fieldLabel: "{{i18n PLUGINS_ADMIN_SYSTEM_COL_LANG}}",
ametysDescription: "{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_DIALOG_LANG_HELP}}",
name: 'language',
allowBlank: false,
regex: /^[a-z]{2}$/,
regexText: "{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_DIALOG_ERROR_LANG}}"
},
{
xtype: 'textarea',
fieldLabel :"{{i18n PLUGINS_ADMIN_SYSTEM_COL_MESSAGE}}",
ametysDescription: "{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_DIALOG_MESSAGE_HELP}}",
allowBlank: false,
name: 'message',
height: 80
}
]
});
this._box = Ext.create('Ametys.window.DialogBox', {
title :"{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_DIALOG_CAPTION}}",
iconCls: 'ametysicon-megaphone19',
layout :'fit',
width: 450,
items : [ this._form ],
closeAction: 'hide',
referenceHolder: true,
defaultButton: 'okButton',
buttons : [{
reference: 'okButton',
text :"{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_DIALOG_OK}}",
handler : Ext.bind(this._ok, this)
}, {
text :"{{i18n PLUGINS_ADMIN_SYSTEM_ANNOUNCEMENT_DIALOG_CANCEL}}",
handler : function () {this._box.hide();},
scope: this
}]
});
this._initialized = true;
return true;
},
/**
* @private
* Initialize the form values
* @param {String} [language] the language's values. Can be null.
* @param {String} [message] the HTML message's value. Can be null.
*/
_initForm: function (language, message)
{
var form = this._form.getForm();
var langFd = form.findField("language");
var msgFd = form.findField("message");
if (this._mode == 'new')
{
msgFd.reset();
langFd.setDisabled(false);
langFd.reset();
langFd.focus(true);
}
else
{
msgFd.setValue(Ametys.convertHtmlToTextarea(message));
langFd.setDisabled(true);
langFd.setValue(language);
msgFd.focus(true, 10);
}
},
/**
* @private
* Listener when clicking on the 'Ok' button
*/
_ok: function ()
{
if (!this._form.isValid())
{
return;
}
var lang = this._form.getForm().findField("language").getValue();
var message = Ametys.convertTextareaToHtml(this._form.getForm().findField("message").getValue());
// First click on "Ok" => We check if the language exists on both addition and edition modes
this._editAnnouncement(lang, message, this._mode == 'edit');
},
/**
* @private
* Server call to add/edit the existing announcements
* @param {String} language the language
* @param {String} message the HTML message
* @param {Boolean} [override=false] true to override message if already exist
*/
_editAnnouncement: function(language, message, override)
{
Ametys.data.ServerComm.callMethod({
role: "org.ametys.runtime.plugins.admin.system.SystemHelper",
methodName: "editAnnouncement",
parameters: [language, message, override || false],
callback: {
scope: this,
handler: this._editAnnouncementCb,
arguments: {
language: language,
message: message
} // if the user tries to replace an existing message by clicking on "Add"
},
errorMessage: {
category: this.self.getName(),
msg: "{{i18n PLUGINS_ADMIN_SYSTEM_ERROR_SAVE}}"
}
});
},
/**
* @private
* Function invoked after the user's chose to replace/not replace the existing message for the selected language key
* @param {String} answer 'yes' if the user clicked "Ok"
* @param {String} language the language key of the message
* @param {String} message the message itself
*/
_confirmCb: function(answer, language, message)
{
if (answer == 'yes')
{
this._editAnnouncement(language, message, true);
}
},
/**
* @private
* Callback for the addition/edition process
* @param {Object} response the server's response
* @param {String} response.already-exists true if the language already exists, undefined otherwise
* @param {Object} args the callback arguments
* @param {String} args.language the language typed in by the user
* @param {String} args.message the message typed in by the user
*/
_editAnnouncementCb: function(response, args)
{
if (response['already-exists'])
{
// Ask the user if he wants to replace the existing welcoming language
Ametys.Msg.confirm ("{{i18n PLUGINS_ADMIN_SYSTEM_CONFIRM_DIALOG_TITLE}}",
"{{i18n PLUGINS_ADMIN_SYSTEM_CONFIRM_DIALOG_TEXT}}",
Ext.bind(this._confirmCb, this, [args.language, args.message], 1));
}
else
{
this._box.hide();
Ext.create('Ametys.message.Message', {
type: this._mode == "new" ? Ametys.message.Message.CREATED : Ametys.message.Message.MODIFIED,
targets: [{
id: 'system-announcement-message',
parameters: {
language: args.language,
message: args.message
}
}]
});
this.forceSystemAnnounceUpdate();
}
}
});