/*
* 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.
*/
/**
* @private
* Singleton gathering forms-related action and the grid listing the forms of a selection of contents
*/
Ext.define('Ametys.plugins.forms.content.tool.FormsActions' , {
singleton: true,
/**
* @private
* @property {Boolean} _initialized is the form initialized ?
*/
/**
* @private
* @property {Ametys.window.DialogBox} _box the dialog box
*/
/**
* @private
* @property {Ext.grid.Panel} _grid the forms grid
*/
/**
* @private
* @property {Function} _callback the callback function
*/
/**
* Export the selected form to XLS format
* @param {Ametys.ribbon.element.ui.ButtonController} controller the controller calling this function
*/
'export': function(controller)
{
var contentFormTarget = controller.getMatchingTargets()[0];
if (contentFormTarget.length == 0)
{
Ametys.Msg.show({
title: '{{i18n PLUGINS_FORMS_CHOOSE_FORM_DIALOG_CAPTION}}',
msg: '{{i18n PLUGINS_FORMS_CHOOSE_FORM_DIALOG_NO_FORM_SELECTED}}',
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.INFO
});
return;
}
var formId = contentFormTarget.getParameters().id;
var formLabel = contentFormTarget.getParameters().label;
Ametys.openWindow(Ametys.getPluginDirectPrefix('forms') + '/' + Ametys.getAppParameter('siteName') + '/export/' + formId + '.xls');
},
/**
* Display the selected form in a grid
* @param {Ametys.ribbon.element.ui.ButtonController} controller the controller calling this function
*/
show: function(controller)
{
this._act(controller, "{{i18n PLUGINS_FORMS_CHOOSE_FORM_DIALOG_TITLE_SHOW}}", this._showForm)
},
/**
* Open the selected form
* @param {Ametys.ribbon.element.ui.ButtonController} controller the controller calling this function
*/
openForm: function(controller)
{
var contentFormTarget = controller.getMatchingTargets()[0];
var params = contentFormTarget.getParameters();
this._showForm(params.id, params.name, params.workflowName, params.contentId);
},
/**
* @private
* Display the selected form
* @param {String} id the id of the form
* @param {String} label the label of the form
* @param {String} workflowName the name of the workflow used for this form's entries
* @param {String} contentId the id of content holding the form
*/
_showForm: function(id, label, workflowName, contentId)
{
Ametys.tool.ToolsManager.openTool('uitool-form-content-entries', { id: id, label: label, workflowName: workflowName, contentId: contentId});
},
/**
* @private
* Displays a dialog box listing forms
* @param {Ametys.ribbon.element.ui.ButtonController} controller the button's controller
* @param {String} title the title of the dialog box
* @param {Function} callback the callback invoked when clicking the 'Ok' button, can either be an XLS export or the display of the forms values in a grid
*/
_act: function(controller, title, callback)
{
var contentTargets = controller.getMatchingTargets();
var contentIds = [];
for (var i=0; i < contentTargets.length; i++)
{
contentIds.push(contentTargets[i].getParameters().id);
}
this._currentForm = null;
this._callback = callback;
if (!this._delayedInitialize())
{
return;
}
this._box.setTitle(title);
this._getForms(contentIds);
},
/**
* @private
* Initialize the panel
* @param {String} title the title of the dialog box
*/
_delayedInitialize: function ()
{
if (this._initialized)
{
return true;
}
this._grid = Ext.create('Ext.grid.Panel', {
id: 'select-form-list',
scrollable: false,
columns:
[
{header: "{{i18n PLUGINS_FORMS_UI_NAME}}", width: 380, menuDisabled: true, sortable: true, dataIndex: 'displayName', doNotEscapeHtml: true}
],
store: Ext.create('Ext.data.Store', {
fields: [
{id: 'id', name: 'name', label: 'label', displayName: 'displayName', workflowName: 'workflowName', contentId: 'contentId'}
]
}),
hideHeaders : true
});
this._box = Ext.create('Ametys.window.DialogBox',
{
iconCls: "ametysicon-list6",
width: 420,
height: 300,
scrollable: true,
border: false,
items: [ this._grid ],
referenceHolder: true,
defaultButton: 'okButton',
closeAction: 'hide',
buttons: [{
reference: 'okButton',
text: "{{i18n PLUGINS_FORMS_CHOOSE_FORM_DIALOG_BUTTON_OK}}",
handler: this._ok,
scope: this
},
{
text: "{{i18n PLUGINS_FORMS_CHOOSE_FORM_DIALOG_BUTTON_CANCEL}}",
handler: this._cancel,
scope: this
}]
});
this._initialized = true;
return true;
},
/**
* @private
* Load the grid
* @param {String[]} contentIds the ids of the selected contents
*/
_getForms: function(contentIds)
{
var pageTarget = Ametys.message.MessageBus.getCurrentSelectionMessage().getTarget(Ametys.message.MessageTarget.PAGE);
var lang = pageTarget != null ? pageTarget.getParameters().lang : Ametys.cms.language.LanguageDAO.getCurrentLanguage();
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.forms.content.table.FormTableManager",
methodName: "getContentForms",
parameters: [contentIds, lang],
callback: {
scope: this,
handler: this._getFormsCb
},
errorMessage: "{{i18n PLUGINS_FORMS_CHOOSE_FORM_DIALOG_FORM_LIST_ERROR}}"
});
},
/**
* @private
* Callback function for the forms retrieving process
* Adds the forms into the grid
* @param {Object} contents the contents and theirs forms
* @param {Object} args The arguments received from the serverCall
*/
_getFormsCb: function(contents, args)
{
var me = this;
me._grid.getStore().removeAll();
var formsAmount = 0;
Ext.Array.each (contents, function (content) {
var forms = content.forms;
Ext.Array.each (forms, function (form) {
me._grid.getStore().add({
id: form.id,
label: form.label,
workflowName: form.workflowName,
displayName: Ext.String.escapeHtml(form.label) + ' <em>(' + Ext.String.escapeHtml(content.title) + ')</em>',
contentId: content.id
});
});
formsAmount += forms.length;
});
if (formsAmount == 0)
{
Ametys.Msg.show({
title: "{{i18n PLUGINS_FORMS_CHOOSE_FORM_DIALOG_CAPTION}}",
msg: "{{i18n PLUGINS_FORMS_CHOOSE_FORM_DIALOG_NORESULT}}",
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.INFO
});
}
if (formsAmount == 1)
{
// Do not bother displaying a selection pop-up when there is only one form to select
// Select the first form "artificially", since the list view is never going to be rendered
var firstRecord = this._grid.getStore().getAt(0);
this._grid.setSelection(firstRecord);
this._ok();
}
if (formsAmount > 1)
{
this._box.show();
// Select the first record of the grid when the view is ready
if (!this._grid.rendered)
{
this._grid.on('viewready', this._selectAndFocusFirstRow, this);
}
else
{
this._selectAndFocusFirstRow();
}
}
},
/**
* @private
* Select the first row of the grid as well as focusing it
*/
_selectAndFocusFirstRow: function()
{
var nodeToFocus = this._grid.getStore().getAt(0);
this._grid.getSelectionModel().select(0);
var gridView = this._grid.getView();
Ext.defer(gridView.focusNode, 1, gridView, [nodeToFocus], false);
},
/**
* @private
* Handler invoked when clicking the 'ok' button
*/
_ok: function()
{
if (this._callback != null)
{
var selection = this._grid.getSelection();
if (selection.length == 0 || selection.length > 1)
{
Ametys.Msg.show({
title: "{{i18n PLUGINS_FORMS_CHOOSE_FORM_DIALOG_CAPTION}}",
msg: "{{i18n PLUGINS_FORMS_CHOOSE_FORM_DIALOG_NO_FORM_SELECTED}}",
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.INFO
});
return;
}
this._box.hide();
var formId = selection[0].id;
var formLabel = selection[0].get('label');
var workflowName = selection[0].get('workflowName');
var contentId = selection[0].get('contentId');
this._callback(formId, formLabel, workflowName, contentId);
}
else
{
this._box.hide();
}
},
/**
* @private
* Handler invoked when clicking the 'cancel' button.Closes the dialog box
*/
_cancel: function ()
{
this._box.hide();
},
// -----------------------------------------------------------------------------
/**
* Delete the selected entries of the current selected form
* @param {Ametys.ribbon.element.ui.ButtonController} controller the controller calling this function
*/
deleteEntry: function(controller)
{
var formTarget = controller.getMatchingTargets()[0];
if (formTarget != null)
{
var entryTargets = formTarget.getSubtargets(Ametys.message.MessageTarget.CONTENT_FORM_ENTRY);
if (entryTargets.length)
{
var ids = [];
Ext.Array.each (entryTargets, function (target) {
ids.push (target.getParameters().id);
})
Ametys.Msg.confirm ("{{i18n PLUGINS_FORMS_DELETE_ENTRY_CONFIRM_TITLE}}",
"{{i18n PLUGINS_FORMS_DELETE_ENTRY_CONFIRM}}",
function (answer)
{
if (answer == 'yes')
{
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.forms.content.table.FormTableManager",
methodName: "deleteEntry",
parameters: [Ametys.getAppParameter('siteName'), formTarget.getParameters().id, ids],
callback: {
scope: this,
handler: this._deleteEntryCb,
arguments: {
ids: ids,
form: formTarget.getParameters().id
}
},
errorMessage: "{{i18n PLUGINS_FORMS_DELETE_ENTRY_ERROR}}"
});
}
},
this
);
}
}
},
/**
* Callback after deleting one or more entries
* @param {String} response The response from the server
* @param {Object} args The arguments received from the serverCall
* @private
*/
_deleteEntryCb: function (response, args)
{
var targets = [];
Ext.Array.each (args.ids, function (id) {
targets.push({
id: Ametys.message.MessageTarget.CONTENT_FORM_ENTRY,
parameters: {
id: id,
form: args.form
}
});
})
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.DELETED,
targets: targets
});
},
// -----------------------------------------------------------------------------
/**
* Clear all entries of the selected form
* @param {Ametys.ribbon.element.ui.ButtonController} controller the controller calling this function
*/
clearEntries: function (controller)
{
var contentFormTargets = controller.getMatchingTargets();
if (contentFormTargets.length > 0)
{
var formIds = [],
formLabels = [];
Ext.each(contentFormTargets, function(contentFormTarget){
formIds.push(contentFormTarget.getParameters().id);
formLabels.push(contentFormTarget.getParameters().label);
});
Ametys.Msg.confirm ("{{i18n PLUGINS_FORMS_CLEAR_ENTRIES_CONFIRM_TITLE}}",
"{{i18n PLUGINS_FORMS_CLEAR_ENTRIES_CONFIRM}}",
function (answer)
{
if (answer == 'yes')
{
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.forms.content.table.FormTableManager",
methodName: "clearEntries",
parameters: [Ametys.getAppParameter('siteName'), formIds],
callback: {
scope: this,
handler: this._clearEntriesCb,
arguments: {
formIds: formIds,
formLabels: formLabels
}
},
errorMessage: "{{i18n PLUGINS_FORMS_CLEAR_ENTRIES_ERROR}}"
});
}
},
this
);
}
},
/**
* @private
* Callback function invoked after clearing all the entries of a form
* @param {String} response The response from the server
* @param {Object} args The arguments received from the serverCall
* @param {Object} args.formIds The ids of the forms whose entries have been removed
* @param {Object} args.formLabels The labels of the forms whose entries have been removed
*/
_clearEntriesCb: function (response, args)
{
var formIds = args.formIds;
var formLabels = args.formLabels;
var targets = [];
Ext.each(formIds, function(formId, idx){
targets.push({
id: Ametys.message.MessageTarget.CONTENT_FORM,
parameters: {
id: formId,
label: formLabels[idx],
hasEntries: false
}
});
});
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.MODIFIED,
targets: targets
});
},
// -----------------------------------------------------------------------------
/**
* View the SELECT statement used to list the entries of the form from the database
* @param {Ametys.ribbon.element.ui.ButtonController} controller the controller calling this function
*/
viewSelectStatement: function(controller)
{
var formTarget = controller.getMatchingTargets()[0];
if (formTarget != null)
{
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.forms.content.table.FormTableManager",
methodName: "getSelectStatement",
parameters: [Ametys.getAppParameter('siteName'), formTarget.getParameters().id],
callback: {
scope: this,
handler: this._getSelectStatementCb,
arguments: {
form: formTarget.getParameters().id
}
},
errorMessage: "{{i18n PLUGINS_FORMS_GET_SELECT_STATEMENT_ERROR}}"
});
}
},
/**
* @private
* Callback invoked after retrieving the SELECT query
* @param {Object} response The data received from the server
* @param {String} response.tableName The SQL table name
* @param {String} response.query The SELECT query
*/
_getSelectStatementCb: function (response)
{
if (!this._selectStatementDelayedInitialize())
{
return;
}
this._initSelectStatementForm(response);
this._selectStatementBox.show();
},
/**
* @private
* Creates the dialog if necessary
* @return {Boolean} true if the initialization is complete
*/
_selectStatementDelayedInitialize: function ()
{
if (this._selectStatementInitialized)
{
return true;
}
this._selectStatementForm = Ext.create('Ext.form.Panel', {
border: false,
defaults : {
cls: 'ametys',
labelWidth: 100,
anchor:'90%',
xtype: 'textfield'
},
items : [{
readOnly: true,
name: "tableName",
fieldLabel: "{{i18n PLUGINS_FORMS_GET_SELECT_STATEMENT_DIALOG_TABLENAME_FIELD}}"
},
{
xtype: 'textarea',
readOnly: true,
fieldLabel :"{{i18n PLUGINS_FORMS_GET_SELECT_STATEMENT_DIALOG_REQUEST_FIELD}}",
name: 'query',
height: 140
}
]
});
this._selectStatementBox = Ext.create('Ametys.window.DialogBox',
{
title :"{{i18n PLUGINS_FORMS_GET_SELECT_STATEMENT_DIALOG_TITLE}}",
iconCls: "ametysicon-data110 ametysicon-decorator-question13",
width: 500,
scrollable: true,
border: false,
items : [ this._selectStatementForm ],
referenceHolder: true,
defaultButton: 'okButton',
closeAction: 'hide',
buttons: [{
defaultButton: 'okButton',
text: "{{i18n PLUGINS_FORMS_GET_SELECT_STATEMENT_DIALOG_BUTTON_OK}}",
handler: function () { this._selectStatementBox.close() },
scope: this
}]
});
this._selectStatementInitialized = true;
return true;
},
/**
* @private
* Initialize the form in the dialog with the data received from the server
* @param {Object} data The data
* @param {String} data.tableName The SQL table name
* @param {String} data.query The SELECT query
*/
_initSelectStatementForm: function (data)
{
var form = this._selectStatementForm.getForm();
form.findField("tableName").setValue(data.tableName);
form.findField("query").setValue(data.query);
},
/**
* Delete the selection of orphan tables
* @param {Ametys.ribbon.element.ui.ButtonController} controller the controller calling this function
*/
removeTables: function(controller)
{
var severalTables = controller.getMatchingTargets().length > 1;
Ametys.Msg.confirm(
"{{i18n PLUGINS_FORMS_ADMINISTRATOR_ORPHAN_FORMS_ACTIONS_DELETE_TABLE_TITLE}}",
severalTables ? "{{i18n PLUGINS_FORMS_ADMINISTRATOR_ORPHAN_FORMS_ACTIONS_DELETE_TABLE_TITLE_TEXT_SEVERAL}}"
: "{{i18n PLUGINS_FORMS_ADMINISTRATOR_ORPHAN_FORMS_ACTIONS_DELETE_TABLE_TITLE_TEXT}}",
Ext.bind(this._doRemove, this, [controller], 1),
this
);
},
/**
* Actually remove the selection of orphan tables
* @param {String} button the button clicked
* @param {Ametys.ribbon.element.ui.ButtonController} controller the controller of the button
*/
_doRemove: function (button, controller)
{
if (button == 'yes')
{
var tableTargets = controller.getMatchingTargets();
var tableNames = [];
Ext.each(tableTargets, function(tableTarget){
tableNames.push(tableTarget.getParameters().name);
});
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.forms.content.table.FormTableManager",
methodName: "removeTables",
parameters: [tableNames],
callback: {
scope: this,
handler: this._doRemoveCb,
arguments: {
tableNames: tableNames
}
},
errorMessage: "{{i18n PLUGINS_FORMS_ADMINISTRATOR_ORPHAN_FORMS_ACTIONS_DELETE_TABLE_ERROR}}"
});
}
},
/**
* Callback for the orphan tables removal process
* @param {Object} response the server's response
* @param {Object} args the callback arguments
* @param {Object} args.tableNames The table names
*/
_doRemoveCb: function (response, args)
{
var targets = [];
Ext.each(args.tableNames, function(tableName){
targets.push({
id: Ametys.message.MessageTarget.TABLE,
parameters: {
name: tableName
}
});
});
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.DELETED,
targets: targets
});
}
});