/*
* Copyright 2023 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.
*/
/**
* Action for creating a new right
*/
Ext.define('Ametys.plugins.coreui.rights.ManageRightAction', {
singleton: true,
/**
* @private
* @property {String[]} _unavailableIds list of used rights ids
*/
/**
* @private
* @property {Ametys.window.DialogBox} _dialogBox the creation dialog box for rights
*/
/**
* @private
* @property {Ametys.window.DialogBox} _deletionDialogBox the deletion dialog box for rights
*/
/**
* Initialize dialog box for adding a right
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
addRight: function(controller)
{
Ametys.data.ServerComm.callMethod({
role: "org.ametys.core.ui.right.ExternalRightsDAO",
methodName: "getRightsIds",
parameters: [],
callback: {
handler: this._getRightsIdsCB,
scope: this
},
waitMessage: true,
errorMessage: { msg: "{{i18n PLUGINS_CORE_UI_MANAGE_RIGHT_SERVER_ERROR}}" }
});
},
/**
* @private
* Callback of getRightsIds, set unavailableIds, reset fields and show dialogBox
* @param {String[]} response the list of unavailable ids
*/
_getRightsIdsCB: function(response)
{
this._unavailableIds = response;
if (!this._dialogBox)
{
this._createDialogBox()
}
this._initializeForm();
this._dialogBox.show();
},
/**
* @private
* Initialize form fields
*/
_initializeForm: function()
{
this._idChanged = false;
this._dialogBox.getComponent('id').reset();
this._dialogBox.getComponent('label').reset();
this._dialogBox.getComponent('description').reset();
},
/**
* @private
* Validator for id field
* @param {String} id the id value to check
* @returns {Object} true if pass validation, error msg if not
*/
_idValidator: function(id)
{
return this._unavailableIds.includes(id)
? "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_DIALOG_ID_ERROR}}"
: true;
},
/**
* @private
* Create a dialog box
*/
_createDialogBox()
{
this._dialogBox = Ext.create('Ametys.window.DialogBox', {
title : "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_DIALOG_TITLE}}",
iconCls: "ametysicon-add64",
width:400,
layout: 'anchor',
defaults:
{
msgTarget: "side",
cls: 'ametys',
padding: 5,
anchor: '100%',
labelAlign: "top",
labelSeparator: "",
labelStyle: "font-weight:bold",
},
items : [
{
name: 'label',
itemId: 'label',
xtype:'textfield',
fieldLabel: "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_DIALOG_LABEL}} *",
ametysDescription: "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_DIALOG_LABEL_DESC}}",
allowBlank: false
},
{
name: 'description',
itemId: 'description',
xtype:'textfield',
fieldLabel: "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_DIALOG_DESCRIPTION}} *",
ametysDescription: "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_DIALOG_DESCRIPTION_DESC}}",
allowBlank: false
},
{
xtype: "textfield",
name: 'id',
itemId: 'id',
allowBlank: false,
fieldLabel: "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_DIALOG_ID}} *",
ametysDescription: "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_DIALOG_ID_DESC}}",
enableKeyEvents: true,
regex: /^[a-zA-Z\_]*$/,
regexText: "{{i18n PLUGINS_CORE_UI_INVALID_CHARACTER_RIGHT_ID_ERROR}}",
validator: Ext.bind(this._idValidator, this)
},
{
xtype: "combobox",
name: 'category',
itemId: 'category',
fieldLabel: "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_DIALOG_CATEGORY_LABEL}} *",
ametysDescription: "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_DIALOG_CATEGORY_DESC}}",
store: this._getCategoriesStore(),
queryMode: 'local',
allowBlank: false,
displayField: 'label',
valueField: 'id',
editable: false
}
],
defaultFocus: 'label',
selectDefaultFocus: true,
closeAction: 'hide',
referenceHolder: true,
defaultButton: 'validate',
buttons : [
{
reference: 'validate',
text: "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_DIALOG_OK_BTN}}",
handler: Ext.bind(this._ok, this)
},
{
text: "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_DIALOG_CANCEL_BTN}}",
handler: Ext.bind(this._hideDialogBox, this)
}
]
});
var labelField = this._dialogBox.getComponent('label');
var idField = this._dialogBox.getComponent('id');
labelField.addListener("change", function(field, value)
{
if (!this._idChanged && value && Object.values(value).length > 0)
{
var id = (Ext.String.deemphasize(value)).replace(/[^a-zA-Z]/gi, "_");
idField.setValue(id);
}
}, this);
idField.addListener("keyup", function(field, value)
{
this._idChanged = true;
}, this);
},
/**
* @private
* Get the category combobox's store data
* @returns {Ext.data.Store} the category store
*/
_getCategoriesStore: function()
{
var store = Ext.create('Ext.data.Store', {
fields: ['id', 'label'],
autoload: true,
sorters: [{
property: 'label',
direction: 'ASC'
}],
proxy: {
type: 'ametys',
role: 'org.ametys.core.ui.right.ExternalRightsDAO',
methodName: 'getRightsCategories',
methodArguments: [],
reader: {
type: 'json',
rootProperty: 'data'
}
},
autoLoad: true,
sortOnLoad: true
})
return store;
},
/**
* @private
* Add the right to server
*/
_ok: function ()
{
if (this._hasInvalid(this._dialogBox))
{
return;
}
var id = this._dialogBox.getComponent('id').getValue();
var label = this._dialogBox.getComponent('label').getValue();
var description = this._dialogBox.getComponent('description').getValue();
var category = this._dialogBox.getComponent('category').getValue();
Ametys.data.ServerComm.callMethod({
role: "org.ametys.core.ui.right.ExternalRightsDAO",
methodName: "addRight",
parameters: [
id,
label,
description,
category
],
callback: {
handler: this._okCB,
scope: this
},
waitMessage: true,
errorMessage: { msg: "{{i18n PLUGINS_CORE_UI_MANAGE_RIGHT_SERVER_ERROR}}" }
});
},
/**
* @private
* Callback of _ok, show message of success or failure
* @param {Object} response the server response
* @param {String} response.message an error message, can be undefined when success
* @param {String} response.id id of the right added, can be undefined when failure
*/
_okCB: function(response)
{
if(!response.message)
{
Ext.create('Ametys.message.Message', {
type: Ametys.message.Message.CREATED,
targets: {
id: Ametys.message.MessageTarget.RIGHT,
parameters: {id: response.id}
}
});
Ametys.notify({
type: 'info',
title: "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_SUCCESS_TITLE}}",
description: "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_SUCCESS}}",
icon: Ext.Msg.INFO
});
}
else
{
var msg = response.message == "duplicate-id"
? "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_ERROR_DUPLICATE}}"
: "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_ERROR}}";
Ametys.notify({
type: 'error',
title: "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_ERROR_TITLE}}",
description: msg,
icon: Ext.Msg.ERROR
});
}
this._dialogBox.hide();
},
/**
* @private
* Hide the creation dialog box
*/
_hideDialogBox: function ()
{
this._dialogBox.hide();
},
/**
* @private
* Return true if a field is invalid
* @param {Ametys.window.DialogBox} box the dialog box
*/
_hasInvalid: function(box)
{
var fields = box.query("[isFormField]");
var hasInvalid = false;
for (let field of fields)
{
if (!field.isValid())
{
hasInvalid = true;
}
}
return hasInvalid;
},
/**
* Initialize and open dialog box to delete a right
*/
removeRight: function()
{
if (!this._deletionDialogBox)
{
this._createDeletionDialogBox()
}
var comboRights = this._deleteRightsPanel.getComponent("rights");
var me = this;
comboRights.reset();
comboRights.getStore().load({
callback: function(){
var rights = comboRights.getStore().getData().items;
if (rights.length == 0)
{
me._deleteRightsPanel.mask("{{i18n PLUGINS_CORE_UI_REMOVE_RIGHT_DIALOG_INTRO_NO_RIGHT}}", "ametys-mask-unloading");
me._deletionDialogBox.down("#validate").disable();
}
else
{
me._deleteRightsPanel.unmask();
me._deletionDialogBox.down("#validate").enable();
}
me._deletionDialogBox.show();
}
});
},
/**
* @private
* Create a dialog box for deleting a right
*/
_createDeletionDialogBox()
{
this._deleteRightsPanel = Ext.create('Ext.Container', {
layout: 'anchor',
border: false,
width:400,
defaults:
{
msgTarget: "side",
cls: 'ametys',
padding: 5,
anchor: '100%',
labelAlign: "top",
labelSeparator: "",
labelStyle: "font-weight:bold",
},
items: [
{
xtype: 'component',
cls: 'a-text',
itemId: 'deleteRightsIntro',
html: "{{i18n PLUGINS_CORE_UI_REMOVE_RIGHT_DIALOG_INTRO}}"
},
{
xtype: "combobox",
name: 'rights',
itemId: 'rights',
fieldLabel: "{{i18n PLUGINS_CORE_UI_REMOVE_RIGHT_DIALOG_RIGHTS_LABEL}} *",
ametysDescription: "{{i18n PLUGINS_CORE_UI_REMOVE_RIGHT_DIALOG_RIGHTS_DESC}}",
store: this._getRightsToDeleteStore(),
queryMode: 'local',
allowBlank: false,
displayField: 'label',
valueField: 'id',
editable: false
}
],
});
this._deletionDialogBox = Ext.create('Ametys.window.DialogBox', {
title : "{{i18n PLUGINS_CORE_UI_REMOVE_RIGHT_DIALOG_TITLE}}",
iconCls: "ametysicon-delete30",
layout: 'fit',
items : [
this._deleteRightsPanel
],
defaultFocus: 'label',
selectDefaultFocus: true,
closeAction: 'hide',
referenceHolder: true,
defaultButton: 'validate',
buttons : [
{
itemId: 'validate',
reference: 'validate',
text: "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_DIALOG_OK_BTN}}",
handler: Ext.bind(this._confirmDeletion, this)
},
{
text: "{{i18n PLUGINS_CORE_UI_ADD_RIGHT_DIALOG_CANCEL_BTN}}",
handler: Ext.bind(function() {this._deletionDialogBox.hide();}, this)
}
]
});
},
/**
* @private
* Get the rights combobox's store data
* @returns {Ext.data.Store} the rights store
*/
_getRightsToDeleteStore: function()
{
var store = Ext.create('Ext.data.Store', {
fields: ['id', 'label'],
sorters: [{
property: 'label',
direction: 'ASC'
}],
proxy: {
type: 'ametys',
role: 'org.ametys.core.ui.right.ExternalRightsDAO',
methodName: 'getRightsToDelete',
methodArguments: [],
reader: {
type: 'json',
rootProperty: 'data'
}
},
autoLoad: true,
sortOnLoad: true
})
return store;
},
/**
* @private
* Send confirmation message for deletion
*/
_confirmDeletion: function()
{
if (this._hasInvalid(this._deletionDialogBox))
{
return;
}
var rightCombobox = this._deleteRightsPanel.getComponent('rights'),
rightId = rightCombobox.getValue(),
rightLabel = rightCombobox.getDisplayValue();
var msg = Ext.String.format("{{i18n PLUGINS_CORE_UI_REMOVE_RIGHT_DIALOG_CONFIRM}}", rightLabel);
Ametys.Msg.confirm("{{i18n PLUGINS_CORE_UI_REMOVE_RIGHT_LABEL}}",
msg,
Ext.bind(this._doRemove, this, [rightId], 1),
this
);
},
/**
* @private
* Proceed to the right removal
* @param {String} btn The pressed button. Can only be 'yes'/'no'
* @param {String} rightId The id of the right to remove.
*/
_doRemove: function(btn, rightId)
{
if (btn == 'yes')
{
Ametys.data.ServerComm.callMethod({
role: "org.ametys.core.ui.right.ExternalRightsDAO",
methodName: "removeRight",
parameters: [
rightId
],
callback: {
handler: this._doRemoveCB,
scope: this
},
waitMessage: true,
errorMessage: { msg: "{{i18n PLUGINS_CORE_UI_MANAGE_RIGHT_SERVER_ERROR}}" }
});
}
},
/**
* @private
* Callback of _doRemove, show message of success or failure
* @param {Object} response the server response
* @param {String} response.message an error message, can be undefined
* @param {String} response.id id of the deleted right, can be null when deletion failed
*/
_doRemoveCB: function(response)
{
if(!response.message)
{
Ext.create('Ametys.message.Message', {
type: Ametys.message.Message.DELETED,
targets: {
id: Ametys.message.MessageTarget.RIGHT,
parameters: {id: response.id}
}
});
Ametys.notify({
type: 'info',
title: "{{i18n PLUGINS_CORE_UI_REMOVE_RIGHT_SUCCESS_TITLE}}",
description: "{{i18n PLUGINS_CORE_UI_REMOVE_RIGHT_SUCCESS}}",
icon: Ext.Msg.INFO
});
}
else
{
var msg = response.message == "rigth-used"
? "{{i18n PLUGINS_CORE_UI_REMOVE_RIGHT_ERROR_USED}}"
: "{{i18n PLUGINS_CORE_UI_REMOVE_RIGHT_ERROR}}";
Ametys.notify({
type: 'info',
title: "{{i18n PLUGINS_CORE_UI_REMOVE_RIGHT_ERROR_TITLE}}",
description: msg,
icon: Ext.Msg.ERROR
});
}
this._deletionDialogBox.hide();
},
});