/*
* Copyright 2016 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 handling workflow actions on form entries
*/
Ext.define('Ametys.plugins.forms.workflow.AbstractFormEntriesWorkflowAction', {
/**
* @private
* @property {Number} _count Counter for processed entries
*/
_count: 0,
/**
* @private
* @property {String[]} _cumulatedEntryIds Array of processed entry ids
*/
_cumulatedEntryIds: [],
/**
* @private
* @property {Ametys.window.DialogBox} _commentBox The pop-up window embedding a simple form with textarea to allow the user to enter a comment on workflow action
*/
_commentBox: null,
/**
* @protected
* Get the form target type
*/
getFormTargetType: function()
{
// To implement
return null;
},
/**
* @protected
* Get the url to do workflow action
* @param {String} actionId the action id
*/
getActionUrl : function(actionId)
{
// To implement
return null;
},
/**
* @protected
* Get role of the mail helper
*/
getMailHelperRole : function()
{
// To implement
return null;
},
/**
* @protected
* Get form entry target type
*/
getFormEntryTargetType : function()
{
// To implement
return null;
},
/**
* Action function to be called by the controller.
* Will execute the workflow action of controller on all contents stored by the controller in controller.contents properties
* @param {Ametys.ribbon.element.ui.ButtonController} controller The clicked button's controller
*/
doAction: function (controller)
{
if (controller.getInitialConfig('comment') == "true")
{
this._showCommentBox (controller);
}
else
{
this._startAction (controller);
}
},
/**
* @private
* Trigger the workflow action
* @param controller the clicked button's controller
* @param comment the comment
*/
_startAction: function(controller, comment)
{
var message = Ametys.message.MessageBus.getCurrentSelectionMessage();
var formTarget = message.getTarget(this.getFormTargetType());
if (!Ext.Object.isEmpty(formTarget))
{
var formId = formTarget.getParameters().id;
if (controller['send-mail'] === 'true')
{
// Show the send mail dialog box to the user
Ametys.plugins.forms.workflow.SendMailDialog.create(formId, controller, comment, this.getMailHelperRole(), Ext.bind(this._doStartAction, this));
}
else
{
this._doStartAction(formId, controller, comment);
}
}
},
/**
* @private
* Execute the workflow action of the controller on all contents stored by the controller in controller.contents properties
* @param {String} formId the id of the form
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #doAction function
* @param {String} comment The comments written by the caller. Can be empty
* @param {String} sendMailInfoJSON the JSON strong containing the needed information to send mails
*/
_doStartAction: function (formId, controller, comment, sendMailInfoJSON)
{
var actionId = controller.getInitialConfig('workflow-action-id');
var entries = controller.entries;
Ametys.data.ServerComm.suspend();
Ext.Array.each(entries, function(entryId) {
Ametys.data.ServerComm.send({
plugin: 'forms',
url: this.getActionUrl(actionId),
parameters: {entryId: entryId, formId: formId, comment: comment, sendMailInfo: sendMailInfoJSON},
priority: Ametys.data.ServerComm.PRIORITY_MAJOR,
callback: {
handler: this._workflowActionCallback,
scope: this,
arguments: {
entryId: entryId,
entryAmount: entries.length,
controller: controller,
formId: formId
}
}
});
}, this);
Ametys.data.ServerComm.restart();
var subtargets = [];
var targetId = this.getFormEntryTargetType();
Ext.Array.each (entries, function(entryId) {
subtargets.push({
id: targetId,
parameters: {
id: entryId,
form: formId
}
})
});
var targets = [];
targets.push ({
id: this.getFormTargetType(),
parameters: {
id: formId
},
subtargets: subtargets
});
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.WORKFLOW_CHANGING,
targets: targets
});
},
/**
* @private
* Callback function called after #_startAction is processed.
* Fires Ametys.message.Message.WORKFLOW_CHANGED message for concerned contents
* @param {Object} response The XML response provided by the {@link Ametys.data.ServerComm}
* @param {Object} args The callback parameters passed to the {@link Ametys.data.ServerComm#send} method
* @param {String} args.entryId the id of the entry
* @param {Number} args.entryAmount the amount of processed form entries
* @param {Ametys.ribbon.element.ui.ButtonController} args.controller the button's controller
* @param {String} args.formId the id of the involved form
*/
_workflowActionCallback: function (response, args)
{
if (Ametys.data.ServerComm.handleBadResponse("{{i18n PLUGINS_FORMS_WORKFLOW_ERROR_DESC}}", response, "Ametys.plugins.forms.workflow.FormEntriesWorkflowAction.doAction"))
{
return;
}
var success = Ext.dom.Query.selectValue ('> ActionResult > success', response) == "true";
var workflowErrors = Ext.dom.Query.select ('> ActionResult > workflowValidation > error', response);
if (!success && workflowErrors.length > 0)
{
var errorMsg = "{{i18n PLUGINS_FORMS_WORKFLOW_ERROR_DESC}}";
errorMsg += '<ul>';
for (var i=0; i < workflowErrors.length; i++)
{
errorMsg += '<li>' + Ext.dom.Query.selectValue("", workflowErrors[i]) + '</li>';
}
errorMsg += '</ul>';
Ametys.Msg.show({
title: "{{i18n PLUGINS_FORMS_WORKFLOW_ERROR_TITLE}}",
msg: errorMsg,
buttons: Ext.Msg.OK,
icon: Ext.Msg.ERROR
});
return;
}
this._cumulatedEntryIds = this._cumulatedEntryIds || [];
this._count = this._count > 0 ? this._count : 0;
this._cumulatedEntryIds.push(args.entryId);
this._count++;
var max = args.entryAmount;
if (this._count == max)
{
var subtargets = [];
var targetId = this.getFormEntryTargetType();
Ext.Array.each (this._cumulatedEntryIds, function(entryId) {
subtargets.push({
id: targetId,
parameters: {
id: entryId,
form: args.formId
}
})
});
var targets = [];
targets.push ({
id: this.getFormTargetType(),
parameters: {
id: args.formId
},
subtargets: subtargets
});
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.WORKFLOW_CHANGED,
targets: targets
});
this._count = 0;
this._cumulatedEntryIds = [];
}
},
/**
* @private
* This function show dialog to enter comment on workflow action
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #doAction function
*/
_showCommentBox: function (controller)
{
if (this._commentBox == null)
{
this._commentBox = Ext.create('Ametys.window.DialogBox', {
title: "{{i18n PLUGINS_FORMS_WORKFLOW_COMMENTS_DIALOG_TITLE}}",
icon: Ametys.getPluginResourcesPrefix("forms") + "/img/edition/mailreceipt_16.png",
width: 450,
height: 250,
scrollable: false,
defaults: {
cls: 'ametys',
labelAlign: 'right',
labelSeparator: '',
labelWidth: 120
},
items: [{
xtype: 'component',
html: "{{i18n PLUGINS_FORMS_WORKFLOW_COMMENTS_DIALOG_MESSAGE}}",
width: '100%'
},
{
xtype: 'textareafield',
label: "{{i18n PLUGINS_FORMS_WORKFLOW_COMMENTS_DIALOG_TEXTAREA}}",
name: 'comment',
id: 'workflow-comment',
ametysDescription: "{{i18n PLUGINS_FORMS_WORKFLOW_COMMENTS_DIALOG_TEXTAREA_DESC}}",
width: '100%',
height: 140
}
],
defaultFocus: 'comment',
closeAction: 'hide',
buttons : [{
text :"{{i18n PLUGINS_FORMS_WORKFLOW_COMMENTS_DIALOG_OK}}",
handler : Ext.bind(this._validateComment, this, [controller])
}, {
text :"{{i18n PLUGINS_FORMS_WORKFLOW_COMMENTS_DIALOG_CANCEL}}",
handler: Ext.bind(function() {this._commentBox.hide();}, this)
}]
});
}
else
{
this._commentBox.down('button').setHandler (Ext.bind(this._validateComment, this, [controller]));
}
this._commentBox.down('#workflow-comment').setValue('');
this._commentBox.show();
},
/**
* @private
* Function handler called when the 'Ok' button of #_commentBox dialog box is pressed
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #doAction function
*/
_validateComment: function (controller)
{
var comment = this._commentBox.down('#workflow-comment').getValue();
this._commentBox.hide();
this._startAction (controller, comment);
}
});