/*
* Copyright 2024 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.
*/
/**
* Rule actions
* @private
*/
Ext.define('Ametys.plugins.odf.pilotage.actions.RuleActions', {
singleton: true,
/**
* Opens the thematics tool for a given program.
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function.
*/
preview: function(controller)
{
var target = controller.getMatchingTargets()[0];
var params = {
id: target.getParameters().id,
title: target.getParameters().title
};
Ametys.tool.ToolsManager.openTool('uitool-rules', params);
},
/**
* Action function to be called by the controller.
* Will open the dialog box to edit additional thematics
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
editAdditionalThematics: function(controller)
{
var contentTarget = controller.getMatchingTargets()[0];
var containerId = contentTarget.getParameters().id;
Ametys.cms.content.ContentDAO.getContent(containerId, Ext.bind(this._editAdditionalThematicsCB, this));
},
/**
* Callback to edit additional thematics
* @param {Content} content The content to edit
*/
_editAdditionalThematicsCB: function(content)
{
var openParams = {
content: content,
editWorkflowActionId: 2,
workflowName: "container",
viewName: "thematics-edition",
width: Math.min(1000, window.innerWidth * 0.9),
dialogConfig: {
height: window.innerHeight * 0.90,
}
}
Ametys.cms.uihelper.EditContent.open(openParams, null, this);
},
/**
* Will add an additional rule to the selected thematic
* @param {String} containerId The container id
* @param {String} thematicId The thematic id
*/
addRule: function (containerId, thematicId)
{
this._containerId = containerId;
this._thematicId = thematicId;
this._ruleId = null;
this._ruleForm = this._ruleForm || this._createRuleForm();
this._ruleBox = this._ruleBox || this._createRuleDialogBox();
this._ruleForm.reset();
this._ruleBox.show();
},
/**
* Will edit an additional rule to the selected thematic
* @param {String} containerId The container id
* @param {String} thematicId The thematic id
* @param {String} ruleId The rule id
*/
editRule: function (containerId, thematicId, ruleId)
{
this._containerId = containerId;
this._thematicId = thematicId;
this._ruleId = ruleId;
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.odfpilotage.rule.RulesManager",
methodName: "getRuleValues",
parameters: [this._containerId, this._ruleId],
callback: {
handler: this._editRuleCB,
scope: this
},
waitMessage: true
});
},
/**
* @private
* Callback to edit rule after getting values
* @param {Object} response the response
* @param {Object} response.values the rule values
*/
_editRuleCB: function(response)
{
this._ruleForm = this._ruleForm || this._createRuleForm();
this._ruleBox = this._ruleBox || this._createRuleDialogBox();
this._ruleForm.reset();
this._ruleForm.setValues(response);
this._ruleBox.show();
},
/**
* @private
* Create the rule form
*/
_createRuleForm: function()
{
var elementsConfiguration = {
text: this._richTextConfiguration("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_CREATE_RULE_TEXT_LABEL}}", "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_CREATE_RULE_TEXT_DESC}}", "text", true),
motivation: this._richTextConfiguration("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_CREATE_RULE_MOTIVATION_LABEL}}", "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_CREATE_RULE_MOTIVATION_DESC}}", "motivation", false)
}
var form = Ext.create('Ametys.form.ConfigurableFormPanel', this._getConfigurableFormPanelConf("top"));
form.additionalWidgetsConf.contentInfo = {
contentId: this._containerId
};
form.configure(elementsConfiguration);
form.setValues(null);
return form;
},
/**
* @private
* Create the rule dialog box
*/
_createRuleDialogBox: function()
{
return this._createDialogBox(
"{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_CREATE_RULE_DIALOG_TITLE}}",
"ametysicon-desktop-book",
[this._ruleForm],
Ext.bind(this._validateRule, this),
function () {this._ruleBox.close();},
true,
false
)
},
/**
* @private
* Validate the rule
*/
_validateRule: function()
{
if (!this._ruleForm.isValid())
{
return;
}
var text = this._ruleForm.getField('content.input.text').getValue();
var motivation = this._ruleForm.getField('content.input.motivation').getValue();
if (this._ruleId)
{
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.odfpilotage.rule.RulesManager",
methodName: "editAdditionalRule",
parameters: [this._containerId, this._ruleId, text, motivation],
callback: {
handler: this._validateRuleCB,
scope: this
},
waitMessage: true
});
}
else
{
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.odfpilotage.rule.RulesManager",
methodName: "addAdditionalRule",
parameters: [this._containerId, this._thematicId, text, motivation],
callback: {
handler: this._validateRuleCB,
scope: this
},
waitMessage: true
});
}
},
/**
* @private
* Callback after validate rule
* @param {Object} response the response
* @param {Object} response.ruleId the rule id
*/
_validateRuleCB: function(response)
{
if (!this._handleError(response, "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_CREATE_OR_EDIT_RULE_ERROR}}"))
{
this._ruleBox.close();
this._sendMessageBus(this._containerId, this._thematicId, "general", response.ruleId, "additional", false, false);
}
},
/**
* Will delete an additional rule to the selected thematic
* @param {String} containerId The container id
* @param {String} ruleId The rule id
*/
deleteRule: function (containerId, ruleId)
{
this._containerId = containerId;
var ruleId = ruleId;
// Confirm deletion
Ametys.Msg.confirm(
"{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_DELETE_RULE_CONFIRM_DIALOG_TITLE}}",
Ext.String.format("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_DELETE_RULE_CONFIRM_DIALOG_MSG}}", "<strong>" + ruleId + "</strong>"),
function (answer)
{
if (answer == 'yes')
{
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.odfpilotage.rule.RulesManager",
methodName: "deleteRule",
parameters: [this._containerId, ruleId],
callback: {
handler: this._deleteRuleCB,
scope: this
},
waitMessage: true
});
}
},
this
);
},
/**
* @private
* Callback after deleting rule
* @param {Object} response the response
* @param {Object} response.thematicId the thematic id containing the deleted rule
*/
_deleteRuleCB: function(response)
{
if (!this._handleError(response, "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_DELETE_RULE_ERROR}}"))
{
this._sendMessageBus(this._containerId, response.thematicId, "general");
}
},
/**
* Will derogate a rule to the selected thematic
* @param {String} containerId The container id
* @param {String} thematicId The thematic id
* @param {String} ruleId The rule id
*/
derogateRule: function (containerId, thematicId, ruleId)
{
this._containerId = containerId;
this._thematicId = thematicId;
this._ruleId = ruleId;
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.odfpilotage.rule.RulesManager",
methodName: "getRuleInfo",
parameters: [this._containerId, this._thematicId, this._ruleId],
callback: {
handler: this._derogateRuleCB,
scope: this
},
waitMessage: true
});
},
/**
* @private
* Callback calling after getting rule information to derogate the rule
* @param {Object} response the server response
*/
_derogateRuleCB: function (response)
{
this._createDerogateRuleForms();
this._derogateRuleBox = this._derogateRuleBox || this._createDerogateRuleDialogBox();
this._derogateRuleBox.down('#code').update(this._ruleId);
this._derogateRuleBox.down('#text').update(response.text);
this._derogateRuleBox.down('#derogate-msg').update(Ext.String.format("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_DEROGATE_TEXT_LABEL}}", "<strong>" + this._ruleId + "</strong>"));
if (response.helpTextDerogation)
{
this._derogateRuleBox.down('#helpTextDerogation').update(response.helpTextDerogation);
}
if (response.helpTextMotivation)
{
this._derogateRuleBox.down('#helpTextMotivation').update(response.helpTextMotivation);
}
this._formDerogateText.reset();
this._formDerogateText.setValues({values : {
text: response.derogationText || response.text
}});
this._formDerogateMotif.reset();
if (response.derogationMotivation)
{
this._formDerogateMotif.setValues({values : {
motivation: response.derogationMotivation
}});
}
this._derogateRuleBox.show();
},
/**
* @private
* Create the derogate rule forms
*/
_createDerogateRuleForms: function()
{
if (!this._formDerogateText)
{
this._formDerogateText = Ext.create('Ametys.form.ConfigurableFormPanel', this._getConfigurableFormPanelConf("left"));
this._formDerogateText.additionalWidgetsConf.contentInfo = {
contentId: this._containerId
};
this._formDerogateText.configure({
text: this._richTextConfiguration("", "", "text", true)
});
this._formDerogateText.setValues(null);
}
if (!this._formDerogateMotif)
{
this._formDerogateMotif = Ext.create('Ametys.form.ConfigurableFormPanel', this._getConfigurableFormPanelConf("left"));
this._formDerogateMotif.additionalWidgetsConf.contentInfo = {
contentId: this._containerId
};
this._formDerogateMotif.configure({
motivation: this._richTextConfiguration("", "", "motivation", true)
});
this._formDerogateMotif.setValues(null);
}
},
/**
* @private
* Create the rule dialog box to derogate it
*/
_createDerogateRuleDialogBox: function()
{
var items = [
{
xtype: 'component',
cls: 'a-text a-text-rule',
id: "derogate-msg",
html: "",
},
{
xtype: 'panel',
layout: {
type: 'table',
columns: 2,
},
cls: 'rule-table',
items: [
{
xtype: 'component',
cls: 'a-text rule-code',
id: 'code'
},
{
xtype: 'component',
cls: 'a-text rule-text',
id: 'text',
scrollable: true,
height: 150,
},
]
},
{
xtype: 'component',
cls: 'a-text a-text-derogation',
id: 'helpTextDerogation',
html: "<p>{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_DEROGATE_TEXT_HELP_DEFAULT}}</p>"
},
this._formDerogateText,
{
xtype: 'component',
cls: 'a-text a-motivation',
id: 'helpTextMotivation',
html: "<p>{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_DEROGATE_MOTIVATION_HELP_DEFAULT}}</p>"
},
this._formDerogateMotif
];
return this._createDialogBox(
"{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_DEROGATE_DIALOG_TITLE}}",
"ametysicon-desktop-book",
items,
Ext.bind(this._validateDerogateRule, this),
function () {this._derogateRuleBox.close();},
true,
false
)
},
/**
* @private
* Validate the derogation for the rule
*/
_validateDerogateRule: function()
{
if (!this._formDerogateText.isValid() || !this._formDerogateMotif.isValid())
{
return;
}
var text = this._formDerogateText.getField('content.input.text').getValue();
var motivation = this._formDerogateMotif.getField('content.input.motivation').getValue();
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.odfpilotage.rule.RulesManager",
methodName: "derogateRule",
parameters: [this._containerId, this._thematicId, this._ruleId, text, motivation],
callback: {
handler: this._validateDerogateRuleCB,
scope: this
},
waitMessage: true
});
},
/**
* @private
* Callback after validate the derogation for the rule
* @param {Object} response the response
* @param {Object} response.ruleId the derogated rule id
*/
_validateDerogateRuleCB: function(response)
{
if (!this._handleError(response, "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_DEROGATE_RULE_ERROR}}"))
{
this._sendMessageBus(this._containerId, this._thematicId, "general", response.ruleId, "general", true, true);
this._derogateRuleBox.close();
}
},
/**
* Will cancel the derogation for a rule to the selected thematic
* @param {String} containerId The container id
* @param {String} thematicId The thematic id
* @param {String} ruleId The rule id
*/
deleteRuleDerogation: function(containerId, thematicId, ruleId)
{
this._containerId = containerId;
this._thematicId = thematicId;
this._ruleId = ruleId;
// Confirm deletion
Ametys.Msg.confirm(
"{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_DELETE_DEROGATE_CONFIRM_TITLE}}",
Ext.String.format("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_DELETE_DEROGATE_CONFIRM_MSG}}", "<strong>" + this._ruleId + "</strong>"),
function (answer)
{
if (answer == 'yes')
{
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.odfpilotage.rule.RulesManager",
methodName: "deleteRule",
parameters: [this._containerId, this._ruleId],
callback: {
handler: this._deleteRuleDerogationCB,
scope: this
},
waitMessage: true
});
}
},
this
);
},
/**
* @private
* Callback after delete the derogation for an rule
*/
_deleteRuleDerogationCB: function(response)
{
if (!this._handleError(response, "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_DELETE_DEROGATE_RULE_ERROR}}"))
{
this._sendMessageBus(this._containerId, this._thematicId, "general", this._ruleId, "general", true, false);
}
},
/**
* Will copy rule derogation or the additional rule to a container
* @param {String} containerId The container id
* @param {String} thematicId The thematic id
* @param {String} ruleId The rule id
*/
copyRule: function(containerId, thematicId, ruleId)
{
this._containerId = containerId;
this._thematicId = thematicId;
this._ruleId = ruleId;
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.odfpilotage.rule.RulesManager",
methodName: "getRuleInfo",
parameters: [this._containerId, this._thematicId, this._ruleId],
callback: {
handler: this._copyRuleCB,
scope: this
},
waitMessage: true
});
},
/**
* Callback called after getting rule information for copying rule
* @param {Object} response the server response
*/
_copyRuleCB: function(response)
{
this._copyRuleBox = this._createCopyRuleDialogBox(
"{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_RULE_DIALOG_TITLE}}",
"{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_RULE_HINT_MSG}}",
Ext.bind(this._validateCopyRule, this),
true,
false
);
this._clearFilter();
this._copyRuleBox.down('#copy-code').update(this._ruleId);
var html = response.derogationText;
if (response.derogationMotivation)
{
html += "<strong>{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_RULE_DIALOG_MOTIVATION}}</strong><br/>" + response.derogationMotivation;
}
this._copyRuleBox.down('#copy-text').update(html);
let mask = Ametys.mask.GlobalLoadMask.mask("{{i18n plugin.core-ui:PLUGINS_CORE_UI_LOADMASK_DEFAULT_MESSAGE}}");
this._containerStore.load({
callback: Ext.bind(function(){
Ametys.mask.GlobalLoadMask.unmask(mask);
if (this._containerStore.queryRecords().length)
{
this._copyRuleBox.show();
}
else
{
this._copyRuleBox.close();
Ametys.Msg.show({
title: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_RULE_DIALOG_TITLE}}",
msg: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_RULE_DIALOG_NO_CONTAINER_ERROR}}",
buttons: Ext.Msg.OK,
icon: Ext.Msg.INFO
});
}
}, this)
});
},
/**
* @private
* Create the copy rule dialog box
* @param {String} title the title
* @param {String} helpText the help text
* @param {Function} validateFn the validate function
* @param {Boolean} withRule true to get the rule
* @param {Boolean} isComplementary true if the dialog box is for complementary rules
*/
_createCopyRuleDialogBox: function(title, helpText, validateFn, withRule, isComplementary)
{
this._containerStore = this._getGridStore();
this._containerGrid = Ext.create('Ext.grid.Panel', {
store: this._containerStore,
itemId: "container-grid",
columns: [
{ text: '{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_GRID_COLUMN_TITLE}}', dataIndex: 'title', flex: 1, renderer: isComplementary ? Ext.bind(this._renderComplementaryTitle, this) : Ext.bind(this._renderTitle, this) },
{ text: '{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_GRID_COLUMN_CODE}}', dataIndex: 'code'},
],
flex: 1,
selModel:{
checkOnly : true,
mode:'MULTI',
headerWidth: 50
},
selType: 'checkboxmodel',
listeners: {
'cellclick': function (grid, td, cellIndex, record) {
if (cellIndex != 0)
{
var selectionModel = grid.getSelectionModel();
if (selectionModel.isSelected(record))
{
selectionModel.deselect(record)
}
else
{
var selection = selectionModel.getSelection();
selection.push(record);
selectionModel.select(selection);
}
}
}
}
});
var filterText = Ext.create('Ext.form.field.Text', {
cls: 'ametys',
flex: 1,
maxWidth: 300,
itemId: 'search-filter-input',
emptyText: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_FILTER}}",
enableKeyEvents: true,
minLength: 3,
minLengthText: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_FILTER_INVALID}}",
msgTarget: 'qtip',
listeners: {change: Ext.Function.createBuffered(this._searchFilter, 500, this)},
style: {
marginRight: '0px'
}
})
var items = [{
xtype: 'component',
cls: 'a-text',
html: helpText
}];
if (withRule)
{
items.push({
xtype: 'container',
layout: {
type: 'table',
columns: 2,
},
id: 'rule-table',
cls: 'rule-table',
items: [
{
xtype: 'component',
cls: 'a-text rule-code',
id: 'copy-code'
},
{
xtype: 'component',
cls: 'a-text rule-text',
id: 'copy-text',
scrollable: true,
maxHeight: 200,
},
]
});
}
items.push(
{
xtype: 'panel',
cls: 'grid-filter',
style: {
marginTop: '10px'
},
layout: {
type: 'hbox',
},
items: [
{
xtype: 'component',
flex: 0.000001
},
filterText,
{
// Clear filter
xtype: 'button',
tooltip: "{{i18n plugin.web:PLUGINS_WEB_UITOOL_SITEMAP_TREE_CLEAR_FILTER}}",
handler: Ext.bind (this._clearFilter, this),
iconCls: 'a-btn-glyph ametysicon-eraser11 size-16',
},
]
},
this._containerGrid
);
return this._createDialogBox(
title,
"ametysicon-desktop-book",
items,
validateFn,
function () {this._copyRuleBox.close();},
false,
true
);
},
/**
* @private
* Render title for copy
* @param {String} value the value
* @param {Object} grid the grid
* @param {Object} record the record
*/
_renderTitle: function(value, grid, record)
{
return record.data.isDerogated
? value + '<span style="margin-left:5px;" class="ametysicon-sign-caution warning-icon" title="' + "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_RULE_WARNING_MSG}}" + '"></span>'
: value;
},
/**
* @private
* Render title for copy complementary title
* @param {String} value the value
* @param {Object} grid the grid
* @param {Object} record the record
*/
_renderComplementaryTitle: function(value, grid, record)
{
return record.data.hasComplementaryRules
? value + '<span style="margin-left:5px;" class="ametysicon-sign-caution warning-icon" title="' + "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_COMPLEMENTARY_RULE_WARNING_MSG}}" + '"></span>'
: value;
},
/**
* This listener is called on 'change' event on filter input field.
* Filters the tree by text input.
* @param {Ext.form.Field} field The field
* @private
*/
_searchFilter: function (field)
{
var value = new String(field.getValue()).trim();
this._filterField = field;
if (this._filterValue == value)
{
// Do nothing
return;
}
this._filterValue = value;
if (value.length > 2)
{
this._containerStore.clearFilter();
this._containerStore.filterBy(function(record) {
var title = Ext.String.deemphasize(record.get('title').trim().toLowerCase())
var code = Ext.String.deemphasize(record.get('code').trim().toLowerCase())
var val = Ext.String.deemphasize(value.trim().toLowerCase())
return title.indexOf(val) != -1 || code.indexOf(val) != -1;
});
if (this._containerStore.getCount() == 0)
{
this._copyRuleBox.down("#container-grid").getView().mask("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_RULE_DIALOG_NO_CONTAINER_FILTER_MSG}}", 'ametys-mask-unloading');
}
else
{
this._copyRuleBox.down("#container-grid").getView().unmask();
}
}
else
{
this._copyRuleBox.down("#container-grid").getView().unmask();
this._containerStore.clearFilter();
}
},
/**
* @private
* Clear the filter
*/
_clearFilter: function()
{
this._copyRuleBox.down("#search-filter-input").setValue(null);
this._copyRuleBox.down("#container-grid").getView().unmask();
this._containerStore.clearFilter();
},
/**
* @private
* Get the containers grid store
*/
_getGridStore: function()
{
var cfg = {
proxy: {
type: 'ametys',
role: 'org.ametys.plugins.odfpilotage.rule.RulesManager',
methodName: 'getAllowedContainers',
reader: {
type: 'json',
rootProperty: 'containers'
}
},
listeners: {
'beforeload': this._onBeforeLoad,
scope: this
},
sorters: [{property: 'title', direction:'ASC'}],
fields: [
{name: 'id', mapping: 'id'},
{name: 'title', mapping: 'title'},
{name: 'code', mapping: 'code'},
{name: 'isDerogated', mapping: 'isDerogated'}
]
}
return Ext.create('Ext.data.Store', cfg);
},
/**
* @private
* Function called before loading the store
* @param {Ext.data.Store} store The store
* @param {Ext.data.operation.Operation} operation The object that will be passed to the Proxy to load the store
*/
_onBeforeLoad: function(store, operation)
{
operation.setParams( Ext.apply(operation.getParams() || {}, {
ruleId: this._ruleId,
containerId: this._containerId
}));
},
/**
* @private
* Copy the rule
*/
_validateCopyRule: function()
{
var records = this._containerGrid.getSelectionModel().getSelection();
var containerIds = records.map(r => r.data.id);
if (!containerIds.length)
{
Ametys.Msg.show({
title: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_RULE_DIALOG_TITLE}}",
msg: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_RULE_NO_SELECT_MSG}}",
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
return;
}
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.odfpilotage.rule.RulesManager",
methodName: "copyRule",
parameters: [this._containerId, this._thematicId, this._ruleId, containerIds],
callback: {
handler: this._validateCopyRuleCB,
scope: this
},
waitMessage: true
});
},
/**
* @private
* Callback after copying the rule
* @param {Object} response the server response
*/
_validateCopyRuleCB: function(response)
{
if (!this._handleError(response, "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_RULE_ERROR}}"))
{
this._copyRuleBox.close();
if (!this._handleErrorContainers(response))
{
Ametys.Msg.show({
title: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_RULE_OK_TITLE}}",
msg: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_RULE_OK_MSG}}",
buttons: Ext.Msg.OK,
icon: Ext.Msg.INFO
});
}
}
if (response["updated-containers"] && response["updated-containers"].length)
{
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.MODIFIED,
targets: {
id: Ametys.message.MessageTarget.CONTENT,
parameters: { ids: response["updated-containers"].map(c => c.id) }
}
});
}
},
/**
* Action function to be called by the controller.
* Will copy rule derogation, additional rule and complematory rule to a container
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
copyAllRules: function(controller)
{
var contentTarget = controller.getMatchingTargets()[0];
this._containerId = contentTarget.getParameters().id;
this._thematicId = null;
this._ruleId = null;
this._copyRuleBox = this._createCopyRuleDialogBox(
Ext.String.format("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_RULE_DIALOG_TITLE}}", contentTarget.getParameters().title),
"{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_RULE_HINT_MSG}}",
Ext.bind(this._validateCopyAllRules, this),
false,
false
);
this._clearFilter();
let mask = Ametys.mask.GlobalLoadMask.mask("{{i18n plugin.core-ui:PLUGINS_CORE_UI_LOADMASK_DEFAULT_MESSAGE}}");
this._containerStore.load({
callback: Ext.bind(function(){
Ametys.mask.GlobalLoadMask.unmask(mask);
if (this._containerStore.queryRecords().length)
{
this._copyRuleBox.show();
}
else
{
this._copyRuleBox.close();
Ametys.Msg.show({
title: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_RULE_DIALOG_TITLE}}",
msg: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_RULE_DIALOG_NO_CONTAINER_ERROR}}",
buttons: Ext.Msg.OK,
icon: Ext.Msg.INFO
});
}
}, this)
});
},
/**
* @private
* Copy all the rule
*/
_validateCopyAllRules: function()
{
var records = this._containerGrid.getSelectionModel().getSelection();
var containerIds = records.map(r => r.data.id);
if (!containerIds.length)
{
Ametys.Msg.show({
title: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_RULE_DIALOG_TITLE}}",
msg: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_RULE_NO_SELECT_MSG}}",
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
return;
}
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.odfpilotage.rule.RulesManager",
methodName: "copyAllRules",
parameters: [this._containerId, containerIds],
callback: {
handler: this._validateCopyAllRulesCB,
scope: this
},
errorMessage: true,
waitMessage: true
});
},
/**
* @private
* Callback after copying all the rules
* @param {Object} response the server response
*/
_validateCopyAllRulesCB: function(response)
{
if (!this._handleError(response, "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_RULE_ERROR}}"))
{
this._copyRuleBox.close();
if (!this._handleErrorContainers(response))
{
Ametys.Msg.show({
title: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_RULE_OK_TITLE}}",
msg: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_RULE_OK_MSG}}",
buttons: Ext.Msg.OK,
icon: Ext.Msg.INFO
});
}
}
if (response["updated-containers"] && response["updated-containers"].length)
{
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.MODIFIED,
targets: {
id: Ametys.message.MessageTarget.CONTENT,
parameters: { ids: response["updated-containers"].map(c => c.id) }
}
});
}
},
/**
* Will copy all rules from the view
* @param {String} containerTitle The container title
* @param {String} containerId The container id
* @param {String} viewName The view name to copy
*/
copyRulesView: function(containerTitle, containerId, viewName)
{
this._containerId = containerId;
this._thematicId = null;
this._ruleId = null;
var isComplementaryRules = viewName == "thematics-edition";
var boxTitle = Ext.String.format(
isComplementaryRules ? "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_COMPLEMENTARY_RULE_DIALOG_CONTENT_TITLE}}" : "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_SPECIFIC_RULE_DIALOG_CONTENT_TITLE}}",
containerTitle
)
this._copyRuleBox = this._createCopyRuleDialogBox(
boxTitle,
isComplementaryRules ? "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_COMPLEMENTARY_RULE_HINT_MSG}}" : "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_SPECIFIC_RULE_HINT_MSG}}",
Ext.bind(this._validateCopyRulesView, this, [viewName]),
false,
isComplementaryRules
);
this._clearFilter();
let mask = Ametys.mask.GlobalLoadMask.mask("{{i18n plugin.core-ui:PLUGINS_CORE_UI_LOADMASK_DEFAULT_MESSAGE}}");
this._containerStore.load({
callback: Ext.bind(function(){
Ametys.mask.GlobalLoadMask.unmask(mask);
if (this._containerStore.queryRecords().length)
{
this._copyRuleBox.show();
}
else
{
this._copyRuleBox.close();
Ametys.Msg.show({
title: boxTitle,
msg: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_RULE_DIALOG_NO_CONTAINER_ERROR}}",
buttons: Ext.Msg.OK,
icon: Ext.Msg.INFO
});
}
}, this)
});
},
/**
* @private
* Copy all the rule from the view
* @param {String} viewName The view name to copy
*/
_validateCopyRulesView: function(viewName)
{
var records = this._containerGrid.getSelectionModel().getSelection();
var containerIds = records.map(r => r.data.id);
if (!containerIds.length)
{
var isComplementaryRules = viewName == "thematics-edition";
Ametys.Msg.show({
title: isComplementaryRules ? "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_COMPLEMENTARY_RULE_DIALOG_TITLE}}" : "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_SPECIFIC_RULE_DIALOG_TITLE}}",
msg: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_RULE_NO_SELECT_MSG}}",
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
return;
}
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.odfpilotage.rule.RulesManager",
methodName: "copyRulesFromView",
parameters: [this._containerId, containerIds, viewName],
callback: {
handler: Ext.bind(this._validateCopyRulesViewCB, this, [viewName], 1),
scope: this
},
waitMessage: true
});
},
/**
* @private
* Callback after copying all rules from view
* @param {Object} response the server response
* @param {String} viewName The view name to copy
*/
_validateCopyRulesViewCB: function(response, viewName)
{
var isComplementaryRules = viewName == "thematics-edition";
if (!this._handleError(response, isComplementaryRules ? "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_COMPLEMENTARY_RULE_ERROR}}" : "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_SPECIFIC_RULE_ERROR}}"))
{
this._copyRuleBox.close();
if (!this._handleErrorContainers(response))
{
Ametys.Msg.show({
title: isComplementaryRules ? "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_COMPLEMENTARY_RULE_DIALOG_TITLE}}" : "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_SPECIFIC_RULE_DIALOG_TITLE}}",
msg: isComplementaryRules ? "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_COMPLEMENTARY_RULE_OK_MSG}}" : "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ALL_SPECIFIC_RULE_OK_MSG}}",
buttons: Ext.Msg.OK,
icon: Ext.Msg.INFO
});
}
}
if (response["updated-containers"] && response["updated-containers"].length)
{
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.MODIFIED,
targets: {
id: Ametys.message.MessageTarget.CONTENT,
parameters: { ids: response["updated-containers"].map(c => c.id) }
}
});
}
},
/**
* @private
* Handle error containers of response
* @param {Object} response the server response
* @returns true if errors
*/
_handleErrorContainers: function(response)
{
var hasError = false;
if (response["error-containers"])
{
var errorMsg = Ext.String.format("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_COPY_ERROR_MSG}}", response["error-containers"].length, response.size)
errorMsg += "<ul>";
for (var containerMap of response["error-containers"])
{
errorMsg += "<li>" + containerMap.title + " (" + containerMap.code + ")</li>";
}
errorMsg += "</ul>";
Ametys.Msg.show({
title: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_ERROR}}",
msg: errorMsg,
buttons: Ext.Msg.OK,
icon: Ext.Msg.ERROR
});
hasError = true;
}
return hasError;
},
/**
* Action function to be called by the controller.
* Will edit specific rules to a container
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
editSpecificRules: function (controller)
{
var contentTarget = controller.getMatchingTargets()[0];
var containerId = contentTarget.getParameters().id;
Ametys.cms.content.ContentDAO.getContent(containerId, Ext.bind(this._editSpecificRulesCB, this));
},
/**
* Callback to edit specific rules
* @param {Content} content The content to edit
*/
_editSpecificRulesCB: function(content)
{
var openParams = {
content: content,
editWorkflowActionId: 2,
workflowName: "container",
viewName: "specific-rules",
width: Math.min(1000, window.innerWidth * 0.9),
dialogConfig: {
height: window.innerHeight * 0.90,
displayGroupsDescriptions: true
}
}
Ametys.cms.uihelper.EditContent.open(openParams, null, this);
},
/**
* @private
* Handle error of response
* @param {Object} response the server response
* @param {String} errorMsg The error message
* @returns true if errors
*/
_handleError: function(response, errorMsg)
{
var hasError = false;
var error = response.error;
if (error)
{
if (error == "not-exist")
{
Ametys.Msg.show({
title: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_ERROR}}",
msg: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_NOT_EXIST_ERROR_MSG}}",
buttons: Ext.Msg.OK,
icon: Ext.Msg.ERROR
});
}
else
{
Ametys.Msg.show({
title: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_ERROR}}",
msg: errorMsg,
buttons: Ext.Msg.OK,
icon: Ext.Msg.ERROR
});
}
hasError = true;
}
return hasError;
},
/**
* @private
* Send a message bus for a given rule in a thematic
* @param {String} containerId The container id
* @param {String} thematicId The thematic id
* @param {String} thematicType The thematic type
* @param {String} ruleId The rule id. Can be null if no rule selected
* @param {String} type The rule type. Can be null if no rule selected
* @param {Boolean} derogable true if the rule is derogable. Can be null if no rule selected
* @param {Boolean} derogated true if the rule is derogated. Can be null if no rule selected
*/
_sendMessageBus: function(containerId, thematicId, thematicType, ruleId, type, derogable, derogated)
{
var contentTarget = {
id: Ametys.message.MessageTarget.CONTENT,
parameters: {
ids: [containerId]
}
};
var thematicTarget = {
id: Ametys.message.MessageTarget.THEMATIC,
parameters: {
id: thematicId,
type: thematicType
}
};
if (ruleId)
{
var ruleTarget = {
id: Ametys.message.MessageTarget.RULE,
parameters: {
id: ruleId,
derogable: derogable,
derogated: derogated,
type: type
}
};
thematicTarget.subtargets = ruleTarget;
}
contentTarget.subtargets = thematicTarget;
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.MODIFIED,
targets: [contentTarget]
});
},
/**
* @private
* Create a configuration for a rich text
* @param {String} label The rich text label
* @param {String} description The rich text description
* @param {String} name The rich text name
* @param {Boolean} mandatory If the rich text is mandatory
*/
_richTextConfiguration: function(label, description, name, mandatory)
{
return {
label: label,
description: description,
multiple: false,
name: name,
path: name,
validation: {
mandatory: mandatory
},
type: "rich-text",
editableSource: true,
"widget-params": {
height: 200,
resizable: false
}
}
},
/**
* @private
* Get the configurable form panel configuration
* @param {String} labelAlign the label align
*/
_getConfigurableFormPanelConf: function(labelAlign)
{
return {
labelAlign: labelAlign,
bodyStyle : {
padding : 0
},
additionalWidgetsConf: {
standaloneEdition: true, // standalone edition (use case: a popup without ribbon (for example richtext buttons) or FO edition),
category: "content"
},
additionalWidgetsConfFromParams: {
contentType: 'contentType', // some widgets require the contentType configuration
editableSource: false
},
fieldNamePrefix : 'content.input.',
displayGroupsDescriptions: false,
};
},
/**
* @private
* Create a configured dialog box
* @param {String} title the dialog box title
* @param {String} icon the dialog box icon
* @param {Object[]} items the dialog box items
* @param {Function} validateFn the dialog box validate function
* @param {Function} cancelFn the dialog box cancel function
* @param {Boolean} withMargin true to get margin
* @param {Boolean} destroy true to destroy on close
*/
_createDialogBox: function(title, icon, items, validateFn, cancelFn, withMargin, destroy)
{
return Ext.create('Ametys.window.DialogBox', {
title : title,
iconCls : icon,
width: Math.min(1000, window.innerWidth * 0.9),
maxHeight: window.innerHeight * 0.90,
scrollable: true,
layout: {
type: 'vbox',
align: 'stretch'
},
defaultType: 'textfield',
defaults: {
cls: 'ametys',
labelAlign: 'right',
labelSeparator: '',
labelWidth: 130,
style: withMargin ? 'margin-right:' + (Ametys.form.ConfigurableFormPanel.OFFSET_FIELDSET + Ametys.form.ConfigurableFormPanel.PADDING_TAB) + 'px' : ''
},
items: items,
freezeHeight: true,
selectDefaultFocus: true,
closeAction: destroy ? 'destroy' : 'hide',
referenceHolder: true,
defaultButton: 'validate',
buttons : [
{
reference: 'validate',
text: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_OK}}",
handler: validateFn,
scope: this
}, {
text: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_RULES_ACTION_CANCEL}}",
handler: cancelFn,
scope: this
}]
});
},
exportWorkRules: function(controller)
{
this._exportContainerRules(controller, "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TS_RULES_BUTTON_EXPORT_PDF_WORK_RULES_LABEL}}", "work");
},
exportDiffRules: function(controller)
{
this._exportContainerRules(controller, "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TS_RULES_BUTTON_EXPORT_PDF_DIFF_RULES_LABEL}}", "diff");
},
exportFinalRules: function(controller)
{
this._exportContainerRules(controller, "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TS_RULES_BUTTON_EXPORT_PDF_FINAL_RULES_LABEL}}", "final");
},
_exportContainerRules: function(controller, title, mode)
{
var containerId = controller.getMatchingTargets()[0].getParameters().id;
var values = {
"reportId": "org.ametys.plugins.odfpilotage.report.MCCReport",
"programItem": containerId
}
Ametys.plugins.odf.pilotage.helper.ExportHelper.export(
title,
"ametysicon-desktop-book",
`${Ametys.getPluginDirectPrefix('odf-pilotage')}/${mode}/container-rules`,
values,
['pdf', 'doc'],
'pdf'
);
}
});