/*
* 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.
*/
/**
* This class is a singleton class to open a dialog box for adding or edting a group directory
* @private
*/
Ext.define('Ametys.plugins.coreui.groupdirectories.EditGroupDirectoryHelper', {
singleton: true,
/**
* @private
* @property {String} _mode The mode. Can only be 'add' or 'edit.
*/
/**
* @private
* @property {String} _groupDirectoryId If in edition mode, the id of the group directory being edited.
*/
/**
* @private
* @property {Function} _callback The callback function called when the group directory is created/modified.
*/
/**
* @private
* @property {Ametys.window.DialogBox} _box The dialog box.
*/
/**
* @private
* @property {String[]} _knownIds The array containing the ids of the existing group directories. Thus, a new directory cannot have an id contained in this array.
*/
/**
* @private
* @property {String} _separator The separator for the {@link Ametys.form.ConfigurableFormPanel}s of the dialog box
*/
_separator: '/',
/**
* @private
* @property {RegExp} _idRegex The regular expression the id of a group directory must match
*/
_idRegex: /^[a-z][a-z0-9_-]*$/,
/**
* Open the helper for creating/editing a group directory
* @param {Object} [valuesToFill] If in edit mode, an object containing the data to fill the form
* @param {String} [mode] The edition mode for the dialog box. Can only be 'add' (for creation) or 'edit' (for edition).
* @param {String} [groupDirectoryId] If in edition mode, the id of the group directory being edited.
* @param {Function} [callback] A callback function called when the group directory is created/modified.
*/
open: function(valuesToFill, mode, groupDirectoryId, callback)
{
this._mode = mode || 'add';
this._groupDirectoryId = groupDirectoryId;
this._callback = callback;
if (mode == 'add')
{
// We need to know the existing ids for checking the id given by the user is not used
this._getKnownIds();
}
else
{
// We need to know fields needed for the creation of a directory, draw and show the box
this._getFields(null, [valuesToFill]);
}
},
/**
* @private
* Asks the server the ids of the existing group directories
*/
_getKnownIds: function()
{
Ametys.plugins.core.groupdirectories.GroupDirectoryDAO.getGroupDirectoriesIds([], this._getFields, {scope: this});
},
/**
* @private
* Asks the server the data needed for creating/editing a group directory.
* @param {String[]} response The server response. It is an array of ids of the directories of the application. Can be null in 'edit' mode.
* @param {Object[]} arguments The callback arguments
*/
_getFields: function(response, arguments)
{
if (this._mode == 'add')
{
this._knownIds = response;
Ametys.plugins.core.groupdirectories.GroupDirectoryDAO.getEditionConfiguration([], this._getFieldsCb, {scope: this});
}
else
{
var valuesToFill = arguments[0];
Ametys.plugins.core.groupdirectories.GroupDirectoryDAO.getEditionConfiguration([], this._getFieldsCb, {scope: this, arguments: [valuesToFill]});
}
},
/**
* @private
* After retrieving from server the fields needed for the creation of a group directory, draw and show the box
* @param {Object} response The server response
* @param {Object[]} arguments The callback arguments
*/
_getFieldsCb: function(response, arguments)
{
this._box = Ext.create('Ametys.window.DialogBox', {
title: this._mode == 'add' ? "{{i18n PLUGINS_CORE_UI_GROUP_DIRECTORIES_DIALOG_ADD_TITLE}}" : "{{i18n PLUGINS_CORE_UI_GROUP_DIRECTORIES_DIALOG_EDIT_TITLE}}",
iconCls: 'ametysicon-multiple25 decorator-ametysicon-agenda3',
width: 650,
layout: {
type: "vbox",
align: "stretch"
},
defaultFocus: 'form',
items: this._getItems(response.groupDirectoryModels),
referenceHolder: true,
defaultButton: 'validate',
buttons: [{
reference: 'validate',
itemId: 'button-validate',
text: "{{i18n PLUGINS_CORE_UI_GROUP_DIRECTORIES_DIALOG_ACTIONS_VALIDATE}}",
handler: Ext.bind(this.validate, this)
}, {
itemId: 'button-cancel',
text: "{{i18n PLUGINS_CORE_UI_GROUP_DIRECTORIES_DIALOG_ACTIONS_CANCEL}}",
handler: Ext.bind(this.cancel, this)
}]
});
this._box.show();
if (this._mode == 'edit')
{
var valuesToFill = arguments[0];
this._fillFields(valuesToFill);
}
else
{
this._getFormPanel().setValues(); // setValues must always be called for configurable form panel in order to complete its initialization
}
},
/**
* @private
* Gets the items of the box
* @param {Object} groupDirectoryModels An object containing information about group directory creation
* @return {Ext.Component[]} The items of the dialog box
*/
_getItems: function(groupDirectoryModels)
{
var chooseModelFieldId = "modelId";
var data = {
label: {
label: "{{i18n PLUGINS_CORE_UI_GROUP_DIRECTORIES_DIALOG_LABEL_LABEL}}",
description: "{{i18n PLUGINS_CORE_UI_GROUP_DIRECTORIES_DIALOG_LABEL_DESC}}",
type: 'string',
validation: {
mandatory: true
},
'widget-params': {
listeners: {
'change': Ext.bind(this._updateIdField, this)
}
}
},
id: {
label: "{{i18n PLUGINS_CORE_UI_GROUP_DIRECTORIES_DIALOG_ID_LABEL}}",
description: "{{i18n PLUGINS_CORE_UI_GROUP_DIRECTORIES_DIALOG_ID_DESC}}",
type: 'STRING',
validation: {
mandatory: true,
regexp: this._idRegex,
regexText: "{{i18n PLUGINS_CORE_UI_GROUP_DIRECTORIES_DIALOG_ID_INVALID}}"
},
'widget-params': {
disabled: this._mode == 'edit',
validator: Ext.bind(this._validateIdField, this)
}
}
};
data[chooseModelFieldId] = {
label: "{{i18n PLUGINS_CORE_UI_GROUP_DIRECTORIES_DIALOG_MODEL_LABEL}}",
description: "{{i18n PLUGINS_CORE_UI_GROUP_DIRECTORIES_DIALOG_MODEL_DESCRIPTION}}",
multiple: false,
type: 'STRING',
enumeration: [],
validation: {
mandatory: true
}
};
this._createData(data, groupDirectoryModels, chooseModelFieldId);
var formPanel = Ext.create('Ametys.form.ConfigurableFormPanel', {
itemId: 'form',
defaultPathSeparator: this._separator,
scrollable: true,
flex: 1
});
formPanel.configure(data);
return [
{
xtype: "component",
html: "{{i18n PLUGINS_CORE_UI_GROUP_DIRECTORIES_DIALOG_HINT}}"
},
formPanel
];
},
/**
* @private
* Action called when the value of the label field changed in order to modify the id field in 'add' mode
* @param {Ext.form.field.Text} labelField The label field which changed
*/
_updateIdField: function(labelField)
{
if (this._mode == 'add')
{
var idField = this._box.getComponent('form').getField('id');
var idValue = this._labelToId(labelField.getValue());
idField.setValue(idValue);
}
},
/**
* @private
* Transforms a label into a valid id
* @param {String} value The label value to transform
* @return {String} The computed id value
*/
_labelToId: function(value)
{
// toLowerCase -> trim -> deemphasize -> all non valid characters become '-'
// -> multiple '-' replaced by one -> do not start with '-'
value = Ext.String.deemphasize(value.toLowerCase().trim()).replace(/\W/g, "-").replace(/-+/g, "-").replace(/^-/g, "");
var i = 2;
var suffixedValue = value;
while (Ext.Array.contains(this._knownIds, suffixedValue))
{
suffixedValue = value + i;
i++;
}
return suffixedValue;
},
/**
* @private
* Validator function for the directory id field.
* @param {String} val The id to check
* @return {Boolean/String} true if the value is valid, an error message otherwise.
*/
_validateIdField: function(val)
{
if (this._mode == 'edit' || !Ext.Array.contains(this._knownIds, val))
{
return true;
}
else
{
return "{{i18n PLUGINS_CORE_UI_GROUP_DIRECTORIES_DIALOG_ID_EXISTING}}";
}
},
/**
* @private
* Create data for the configurable form panel
* @param {Object} data The data object to modify for configuring the {@link Ametys.form.ConfigurableFormPanel}
* @param {Object[]} models An array of object containing the information for the fields
* @param {String} chooseModelFieldId The name of the field for choosing the type (some fields are disabled depending on the value of this field)
*/
_createData: function(data, models, chooseModelFieldId)
{
Ext.Array.forEach(models, function(model) {
// Add an entry into the combobox for selecting the model
data[chooseModelFieldId].enumeration.push({
label: model.label,
value: model.id
});
// Add the fields for each parameter
Ext.Object.each(model.parameters, function(parameterId, parameter) {
// Add a disable condition
Ametys.form.Widget.addDisableCondition(parameter, chooseModelFieldId, "neq", model.id, true);
// The field is ready
data[parameterId] = parameter;
}, this);
}, this);
},
/**
* Handler when clicking on 'cancel' button
*/
cancel: function()
{
this._box.hide();
},
/**
* Handler for 'Ok' action
*/
validate: function()
{
var isValidForm = this._getFormPanel().isValid();
if (!isValidForm)
{
return;
}
var values = this._getFormValues();
if (this._mode == 'add')
{
Ametys.plugins.core.groupdirectories.GroupDirectoryDAO.add([values.id, values.label, values.modelId, values.params], this._validateCb, {scope: this});
}
else
{
Ametys.plugins.core.groupdirectories.GroupDirectoryDAO.edit([this._groupDirectoryId, values.label, values.modelId, values.params], this._validateCb, {scope: this});
}
},
/**
* @private
* Gets the configurable form panel of the dialog box.
* @return {Ametys.form.ConfigurableFormPanel} The configurable form panel
*/
_getFormPanel: function()
{
return this._box.items.getByKey('form');
},
/**
* @private
* Gets the values of the form
* @return {Object} The form values
*/
_getFormValues: function()
{
var result = {};
var values = this._getFormPanel().getValues();
// Extract label, id and model id
result['label'] = values.label;
result['id'] = values.id;
result['modelId'] = values.modelId;
// The parameters are the remaining entries
delete values['label'];
delete values['id'];
delete values['modelId'];
result['params'] = values;
return result;
},
/**
* @private
* Callback function called after the 'Ok' action is processed. Close the dialog box if no error.
* @param {Object} response The server response
*/
_validateCb: function(response)
{
if (!response.error)
{
this._box.close();
if (Ext.isFunction(this._callback))
{
this._callback(response.id);
}
}
},
/**
* @private
* Fills the forms of the dialog box with values.
* @param {Object} valuesToFill The data to fill
*/
_fillFields: function(valuesToFill)
{
var values = {};
var modelId = valuesToFill['modelId'];
values['label'] = valuesToFill['label'];
values['id'] = valuesToFill['id'];
values['modelId'] = modelId;
Ext.Object.each(valuesToFill['params'], function(paramName, paramValue) {
values[paramName] = paramValue;
}, this);
this._getFormPanel().setValues({values: values});
}
});