/*
* Copyright 2018 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.
*/
/**
* Helper for tag
* @private
*/
Ext.define('Ametys.plugins.cms.tag.TagHelper', {
singleton: true,
/**
* Function called to add a new tag
* @param {String} parentId id of the parent of the tag to create
* @param {Ext.form.Panel} formPanel The form panel
* @param {String} targetId The target id
* @param {String} tagDAO The tag DAO class
* @param {String} boxTitle The box title
* @param {String} boxIcon The box icon
* @param {Function} callback the callback after creation
*/
add: function(parentId, formPanel, targetId, tagDAO, boxTitle, boxIcon, callback)
{
this._mode = "new";
this._cbFn = callback;
this._targetId = targetId;
this._tagDAO = tagDAO;
if (!this._delayedInitialize(formPanel))
{
return;
}
this._initCreateForm(parentId, boxTitle, boxIcon);
},
/**
* Function called to edit a tag
* @param {String} id id of the tag to edit
* @param {Ext.form.Panel} formPanel The form panel
* @param {String} targetId The target id
* @param {String} tagDAO The tag DAO class
* @param {String} boxTitle The box title
* @param {String} boxIcon The box icon
* @param {Function} callback the callback after edition
*/
edit: function(id, formPanel, targetId, tagDAO, boxTitle, boxIcon, callback)
{
this._mode = "edit";
this._cbFn = callback;
this._targetId = targetId;
this._tagDAO = tagDAO;
if (!this._delayedInitialize(formPanel))
{
return;
}
this._initEditForm(id, boxTitle, boxIcon);
},
/**
* Initialize the dialog box to create or edit a tag.
* This method does nothing but returning if the dialog box is already initialized
* @param {Ext.form.Panel} formPanel The form panel
* @return {Boolean} return true on success.
* @private
*/
_delayedInitialize: function(formPanel)
{
this._form = formPanel.getForm();
if (this._initialized)
{
var oldFormPanel = this._box.items.getAt(0);
if (oldFormPanel !== formPanel)
{
this._box.remove(oldFormPanel, {destroy: false});
this._box.add(formPanel);
}
return true;
}
this._box = Ext.create('Ametys.window.DialogBox', {
title: "{{i18n PLUGINS_CMS_HANDLE_TAGS_CREATE}}",
iconCls: 'ametysicon-tag25 decorator-ametysicon-add64',
layout: 'fit',
width: 400,
items: [ formPanel ],
defaultFocus: 'title',
selectDefaultFocus: true,
referenceHolder: true,
defaultButton: 'validate',
closeAction: 'hide',
buttons: [{
reference: 'validate',
text: "{{i18n PLUGINS_CMS_HANDLE_DIALOG_BUTTON_OK}}",
handler : Ext.bind(this._ok, this, []),
scope: this
}, {
text: "{{i18n PLUGINS_CMS_HANDLE_DIALOG_BUTTON_CANCEL}}",
handler : this._cancel,
scope: this
}]
});
this._initialized = true;
return true;
},
/**
* Called when pressing the Ok button on the dialog box
* @private
*/
_ok: function ()
{
if (this._form.isValid())
{
var params = this._form.getValues();
if (this._mode === 'new')
{
Ametys.data.ServerComm.callMethod({
role: this._tagDAO,
methodName: "createTag",
parameters: [params.parentID, params.name, params.title, params.description, params, Ametys.getAppParameters()],
callback: {
scope: this,
handler: Ext.bind(this._addTagCb, this, [], 1)
},
waitMessage: {
target: this._box,
msg: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_LOADMASK_DEFAULT_MESSAGE}}"
},
errorMessage: {
msg: "{{i18n PLUGINS_CMS_HANDLE_TAGS_ADD_TAG_ERROR}}",
category: this.self.getName()
}
});
}
else
{
Ametys.data.ServerComm.callMethod({
role: this._tagDAO,
methodName: "updateTag",
parameters: [params.id, params.title, params.description, params],
callback: {
scope: this,
handler: Ext.bind(this._editTagCb, this, [], 1)
},
waitMessage: {
target: this._box,
msg: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_LOADMASK_DEFAULT_MESSAGE}}"
},
errorMessage: {
msg: "{{i18n PLUGINS_CMS_HANDLE_TAGS_EDIT_TAG_ERROR}}",
category: this.self.getName()
}
});
}
}
},
/**
* Callback invoked after adding a tag
* @param {Object[]} response The JSON response from the server
* @private
*/
_addTagCb: function(response)
{
this._box.hide();
var tagId = response['tagId'];
var tagParentId = response['tagParentId'];
var tagName = response['tagName'];
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.CREATED,
targets: {
id: this._targetId,
parameters: {
id: tagId,
parentId: tagParentId,
name: tagName
}
}
});
if (Ext.isFunction(this._cbFn))
{
this._cbFn (tagId, tagName, tagParentId);
}
},
/**
* Callback invoked after editing a tag
* @param {Object[]} response The JSON response from the server
* @private
*/
_editTagCb: function(response)
{
this._box.hide();
var tagId = response['id'];
var tagName = response['name'];
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.MODIFIED,
targets: {
id: this._targetId,
parameters: {
id: tagId,
name: tagName
}
}
});
if (Ext.isFunction(this._cbFn))
{
this._cbFn (tagId, tagName);
}
},
/**
* Called when pressing the Cancel button on the dialog box
* @private
*/
_cancel: function ()
{
this._box.hide();
if (Ext.isFunction(this._cbFn))
{
this._cbFn ();
}
},
/**
* Fill the dialog box when creating a new tag
* @param {String} parentId The id of parent tag for creation mode. Can not be null.
* @param {String} boxTitle The box title
* @param {String} boxIcon The box icon
* @private
*/
_initCreateForm: function (parentId, boxTitle, boxIcon)
{
this._box.setTitle(boxTitle);
this._box.setIconCls(boxIcon);
this._form.reset();
this._form.findField('parentID').setValue(parentId);
this._form.findField('title').setValue("{{i18n PLUGINS_CMS_HANDLE_TAGS_TITLE_NEW}}");
var val = this._getAutoKey (this._form.findField('title').getValue());
this._form.findField('name').setValue(val);
this._box.getDockedItems('toolbar[dock="bottom"]')[0].items.get(0).setDisabled(false);
this._box.show();
},
/**
* Fill the dialog box when editing a tag.
* @param {String} id The id of tag to edit. Can not be null.
* @param {String} boxTitle The box title
* @param {String} boxIcon The box icon
* @private
*/
_initEditForm: function (id, boxTitle, boxIcon)
{
this._box.setTitle(boxTitle);
this._box.setIconCls(boxIcon);
this._form.reset();
this._box.show();
Ametys.data.ServerComm.callMethod({
role: this._tagDAO,
methodName: "getTag",
parameters: [id],
callback: {
scope: this,
handler: this._getTagCb
},
waitMessage: {
target: this._box,
msg: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_LOADMASK_DEFAULT_MESSAGE}}"
}
});
},
/**
* Callback for #_initForm in edition mode.
* @param {Object[]} response The JSON response from the server, containing the tag informations
* @private
*/
_getTagCb: function (response)
{
if (response == null)
{
Ametys.log.ErrorDialog.display({
title: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_SERVERCOMM_BADRESPONSE_TITLE}}",
text: "{{i18n PLUGINS_CMS_HANDLE_TAGS_EDIT_TAG_UNKNOWN_TAG}}",
details: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_SERVERCOMM_BADRESPONSE_DESC}} ",
category: this.self.getName()
});
this._box.getDockedItems('toolbar[dock="bottom"]')[0].items.get(0).setDisabled(true);
return;
}
this._box.getDockedItems('toolbar[dock="bottom"]')[0].items.get(0).setDisabled(false);
for (var key in response)
{
var field = this._form.findField(key);
if (field)
{
field.setValue(response[key]);
}
}
this._form.findField('parentID').setValue('');
},
/**
* Delete the tag
* @param {String} tagId The tag id to delete
* @param {String} targetId The target id
* @param {String} tagDAO The tag DAO class
* @param {String} boxTitle The box title
* @param {String} boxMsg The box msg
* @private
*/
remove: function(tagId, targetId, tagDAO, boxTitle, boxMsg)
{
this._targetId = targetId;
this._tagDAO = tagDAO;
Ametys.Msg.confirm(boxTitle,
boxMsg,
Ext.bind(this._doDelete, this, [tagId], 1)
);
},
/**
* Called in delete mode, delete the tag if the user pressed the "Ok" button
* @param {String} button The ID of the button pressed
* @param {String} tagId The tag id to delete
* @private
*/
_doDelete: function (button, tagId)
{
if (button == "yes")
{
Ametys.data.ServerComm.callMethod({
role: this._tagDAO,
methodName: "deleteTag",
parameters: [tagId, Ametys.getAppParameters()],
callback: {
scope: this,
handler: Ext.bind(this._deleteTagCb, this, [], 1)
},
errorMessage: {
msg: "{{i18n PLUGINS_CMS_HANDLE_TAGS_DELETE_TAG_ERROR}}",
category: this.self.getName()
}
});
}
},
/**
* Callback invoked after deleting a tag
* @param {Object} response The JSON server response
* @private
*/
_deleteTagCb: function (response)
{
// get from response
var id = response['id'];
var name = response['name'];
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.DELETED,
targets: {
id: this._targetId,
parameters: {
id: id,
name: name
}
}
});
},
/**
* Function called to move one or more tags.
* @param {String} target The target id for the move action.
* @param {String[]} ids The IDs of the tags to move.
* @param {String} tagDAO The tag DAO class
* @param {String} targetId The target id
* @param {Function} callback A callback function to call when the move is done. Can be null. The arguments are:
* @param {String} callback.target The id of target for the move action.
* @param {String[]} callback.ids The id of moved tags
*/
move: function (target, ids, tagDAO, targetId, callback)
{
Ametys.data.ServerComm.callMethod({
role: tagDAO,
methodName: "moveTags",
parameters: [ target, ids ],
callback: {
handler: Ext.bind(this._moveCb, this, [targetId, callback], true),
ignoreOnError: false
},
waitMessage: {
msg: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_LOADMASK_DEFAULT_MESSAGE}}"
},
errorMessage: {
msg: "{{i18n PLUGINS_CMS_HANDLE_TAGS_MOVE_ERROR}}"
}
});
},
/**
* Callback function after moving tags
* @param {Object} response The JSON response from the server, containing the tags informations
* @param {String} response.target The target id for the move action
* @param {String[]} response.movedTags The ids of moved tags
* @param {Object} args The callback arguments
* @param {String} targetId The target id
* @param {Function} callback A callback function to call when the move is done. Can be null.
* @private
*/
_moveCb: function (response, args, targetId, callback)
{
if (!response)
{
if (Ext.isFunction(callback))
{
callback([]);
}
return;
}
var movedTags = response.movedTags || [];
if (Ext.isFunction(callback))
{
callback(response.target, movedTags, targetId);
}
},
/**
* Listener that fill the name field based on the input in the title field.
* Does nothing in edit mode.
*/
autoFillKey: function (input, event)
{
var idField = Ametys.plugins.cms.tag.TagHelper._form.findField('id');
if (idField === undefined || idField.getValue() === "")
{
var val = Ametys.plugins.cms.tag.TagHelper._getAutoKey (input.getValue());
Ametys.plugins.cms.tag.TagHelper._form.findField('name').setValue(val);
}
},
/**
* Generate a valid unique name from the user input in the title field
* @return {String} valid name
* @private
*/
_getAutoKey: function (value)
{
var re_a = new RegExp('[áàâäã]','gi');
var re_e = new RegExp('[éèêë]','gi');
var re_i = new RegExp('[íìîï]','gi');
var re_o = new RegExp('[óòôöõ]','gi');
var re_u = new RegExp('[úùûü]','gi');
var re_y = new RegExp('[ýÿ]','gi');
var re_c = new RegExp('[ç]','gi');
var re_n = new RegExp('[ñ]','gi');
var re_nalnum = new RegExp('[^a-zA-Z0-9]','gi');
var re_start = new RegExp('^[^a-zA-Z]');
value = value.replace(re_a,"a");
value = value.replace(re_e,"e");
value = value.replace(re_i,"i");
value = value.replace(re_o,"o");
value = value.replace(re_u,"u");
value = value.replace(re_y,"y");
value = value.replace(re_c,"c");
value = value.replace(re_n,"n");
value = value.replace(re_nalnum,"_");
if (re_start.test(value))
{
value = 'x_' + value;
}
value = value.toUpperCase();
return value;
}
});