/*
* Copyright 2014 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.
*/
/**
* Singleton class to delete ODF contents
* @private
*/
Ext.define('Ametys.plugins.odf.content.DeleteContentAction', {
singleton: true,
/**
* @readonly
* @property {String} SINGLE_MODE Constant for single deletion mode
*/
SINGLE_MODE : 'single',
/**
* @readonly
* @property {String} STRUCTURE_ONLY_MODE Constant for "structure only" deletion mode
*/
STRUCTURE_ONLY_MODE: 'structure_only',
/**
* @readonly
* @property {String} FULL_MODE Constant for full deletion mode
*/
FULL_MODE: 'full',
/**
* Action function to be called by the controller.
* Will delete the contents registered by the controller.
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
act: function (controller)
{
var contentIdsToDelete = controller.getContentIds();
if (contentIdsToDelete.length > 0)
{
var contentTargets = controller.getMatchingTargets();
controller.serverCall('getStructureInfo', [contentIdsToDelete], Ext.bind(this._getStructureInfoCB, this),
{
arguments: {
controller: controller,
contentIdsToDelete: contentIdsToDelete,
contentTargets: contentTargets
},
waitMessage: true
}
);
}
},
actWithoutStructureCheck: function (controller)
{
var contentIdsToDelete = controller.getContentIds();
var contentTargets = controller.getMatchingTargets();
if (contentIdsToDelete.length > 0)
{
this._showConfirmMsg(controller, contentTargets, this.SINGLE_MODE, contentIdsToDelete, {}, []);
}
},
/**
* Callback function called after #_getContentInfo is processed.
* @param {Object} response The JSON result
* @param {Object} args The callback arguments
* @param {Ametys.ribbon.element.ui.ButtonController} args.controller The controller
* @param {Ametys.message.MessageTarget[]} args.contentTargets The content targets
* @param {String[]} args.contentIdsToDelete The content IDs to delete
* @private
*/
_getStructureInfoCB: function(response, args)
{
var contentTargets = args.contentTargets;
var types = contentTargets[0].getParameters().types;
var chooseOptsFn = this._getChooseOptionsFnByTypes(types);
var contentIdsToDelete = args.contentIdsToDelete;
var atLeastOneContentChildren = false;
var contentsInfo = {};
var pathsToReferencedContents = [];
Ext.Array.each(contentIdsToDelete, function(id) {
var structureInfo = response[id];
contentsInfo[id] = { 'code': structureInfo.code };
if (structureInfo.hasParent)
{
var paths = structureInfo["paths"];
Ext.Array.forEach (paths, function (path) {
pathsToReferencedContents.push({
title: structureInfo.title,
code: structureInfo.code,
path: path.substring(0, path.lastIndexOf('>') + 2)
});
});
}
if (structureInfo.hasChildren)
{
atLeastOneContentChildren = true;
}
});
// If we have at least one content with a children, we display a box to select how to handle it.
if (atLeastOneContentChildren)
{
chooseOptsFn.call(this, args.controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, response.nbOnlyStructureContents, response.nbCourses);
}
else
{
// prepare deletion
this._showConfirmMsg(args.controller, contentTargets, this.SINGLE_MODE, contentIdsToDelete, contentsInfo, pathsToReferencedContents);
}
},
/**
* @private
* Get the function to display options to user
* @param {String[]} types The content's types
* @return {Function} The function
*/
_getChooseOptionsFnByTypes: function (types)
{
if (Ext.Array.contains(types, "org.ametys.plugins.odf.Content.course"))
{
return this._showCourseDialog;
}
else if (Ext.Array.contains(types, "org.ametys.plugins.odf.Content.courseList"))
{
return this._showCourseListDialog;
}
else
{
return this._showProgramPartDialog;
}
},
/**
* @private
* Open the dialog to choose options of deletion for program parts
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
* @param {Ametys.message.MessageTarget[]} contentTargets The content targets
* @param {String[]} contentIdsToDelete The content IDs to delete
* @param {Object} contentsInfo information retrieved by the server organized by content id
* @param {Array} pathsToReferencedContents List of all the path referencing any of the content to delete
* @param {Integer} nbOnlyStructureContents The number of child contents in the structure concerned by deletion
* @param {Integer} nbCourses The number of child ELPs concerned by deletion
*/
_showProgramPartDialog: function(controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses)
{
this._drawDeleteProgramPartDialog(controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses);
this._deleteProgramPartBox.show();
},
/**
* @private
* Open the dialog to choose options of deletion for course lists
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
* @param {Ametys.message.MessageTarget[]} contentTargets The content targets
* @param {String[]} contentIdsToDelete The content IDs to delete
* @param {Object} contentsInfo information retrieved by the server organized by content id
* @param {Array} pathsToReferencedContents List of all the path referencing any of the content to delete
* @param {Integer} nbOnlyStructureContents The number of child contents in the structure concerned by deletion
* @param {Integer} nbCourses The number of child ELPs concerned by deletion
*/
_showCourseListDialog: function(controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses)
{
this._drawDeleteCourseListDialog(controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses);
this._deleteCourseListBox.show();
},
/**
* @private
* Open the dialog to choose options of deletion for courses
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
* @param {Ametys.message.MessageTarget[]} contentTargets The content targets
* @param {String[]} contentIdsToDelete The content IDs to delete
* @param {Object} contentsInfo information retrieved by the server organized by content id
* @param {Array} pathsToReferencedContents List of all the path referencing any of the content to delete
* @param {Integer} nbOnlyStructureContents The number of child contents in the structure concerned by deletion
* @param {Integer} nbCourses The number of child ELPs concerned by deletion
*/
_showCourseDialog: function(controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses)
{
this._drawDeleteCourseDialog(controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses);
this._deleteCourseBox.show();
},
/**
* Draw the delete course list dialog box
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
* @param {Ametys.message.MessageTarget[]} contentTargets The content targets
* @param {String[]} contentIdsToDelete The content IDs to delete
* @param {Object} contentsInfo information retrieved by the server organized by content id
* @param {Array} pathsToReferencedContents List of all the path referencing any of the content to delete
* @param {Integer} nbOnlyStructureContents The number of child contents in the structure concerned by deletion
* @param {Integer} nbCourses The number of child ELPs concerned by deletion
* @private
*/
_drawDeleteCourseListDialog: function (controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses)
{
let fullHint = Ext.String.format("{{i18n PLUGINS_ODF_CONTENT_DELETE_MSGBOX_RADIO_NB_CONTENT_HINT}}", nbOnlyStructureContents + nbCourses + contentIdsToDelete.length); // add the size of selected contents to be deleted
if (this._deleteCourseListBox == null)
{
this._deleteCourseListBox = Ext.create('Ametys.window.DialogBox', {
title :"{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_TITLE}}",
iconCls : 'ametysicon-delete30',
width : 500,
items : [{
xtype: 'component',
html: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_HINT1}}",
cls: 'a-text'
},
{
xtype: 'form',
items: [{
xtype: 'radiofield',
hideLabel: true,
checked: true,
boxLabel: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_RADIO_SINGLE_LABEL}}",
ametysDescription: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_RADIO_SINGLE_DESC}}",
name: 'mode',
inputValue: this.SINGLE_MODE,
itemId: "courselist-single",
style: {
marginLeft: '15px'
}
},
{
xtype: 'radiofield',
hideLabel: true,
boxLabel: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_RADIO_CHILD_LABEL}}<br/>" + fullHint,
ametysDescription: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_RADIO_CHILD_DESC}}",
name: 'mode',
inputValue: this.FULL_MODE,
itemId: "courselist-full",
style: {
marginLeft: '15px'
}
}]
},
{
xtype: 'component',
html: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_HINT2}}",
cls: 'a-text'
}
],
closeAction: 'hide',
defaultButton: 'validate',
buttonAlign: 'center',
buttons : [ {
itemId: 'validate',
reference: 'validate',
text :"{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_OK}}",
handler : function () { this._validateDelete(controller, this._deleteCourseListBox, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents); },
scope: this
},
{
itemId: 'cancel',
reference: 'cancel',
text :"{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_CANCEL}}",
handler : function () { this._deleteCourseListBox.close(); },
scope: this
}]
});
}
else
{
this._deleteCourseListBox.down("#validate").setHandler(function () { this._validateDelete(controller, this._deleteCourseListBox, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents); });
this._deleteCourseListBox.down("#courselist-full").setBoxLabel("{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_RADIO_CHILD_LABEL}}<br/>" + fullHint);
}
},
/**
* Draw the delete course dialog box
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
* @param {Ametys.message.MessageTarget[]} contentTargets The content targets to delete
* @param {String[]} contentIdsToDelete The content IDs to delete
* @param {Object} contentsInfo information retrieved by the server organized by content id
* @param {Array} pathsToReferencedContents List of all the path referencing any of the content to delete
* @param {Integer} nbOnlyStructureContents The number of child contents in the structure concerned by deletion
* @param {Integer} nbCourses The number of child ELPs concerned by deletion
* @private
*/
_drawDeleteCourseDialog: function (controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses)
{
let fullHint = Ext.String.format("{{i18n PLUGINS_ODF_CONTENT_DELETE_MSGBOX_RADIO_NB_CONTENT_HINT}}", nbOnlyStructureContents + nbCourses + contentIdsToDelete.length); // add the size of selected contents to be deleted
if (this._deleteCourseBox == null)
{
this._deleteCourseBox = Ext.create('Ametys.window.DialogBox', {
title :"{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_TITLE}}",
iconCls : 'ametysicon-delete30',
width : 400,
items : [{
xtype: 'component',
html: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_HINT1}}",
cls: 'a-text'
},
{
xtype: 'form',
items: [{
xtype: 'radiofield',
hideLabel: true,
checked: true,
boxLabel: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_RADIO_SINGLE_LABEL}}",
ametysDescription: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_RADIO_SINGLE_DESC}}",
name: 'mode',
inputValue: this.SINGLE_MODE,
itemId: "course-single",
style: {
marginLeft: '15px'
}
},
{
xtype: 'radiofield',
hideLabel: true,
boxLabel: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_RADIO_CHILD_LABEL}}<br/>" + fullHint,
ametysDescription: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_RADIO_CHILD_DESC}}",
name: 'mode',
inputValue: this.FULL_MODE,
itemId: "course-full",
style: {
marginLeft: '15px'
}
}]
},
{
xtype: 'component',
html: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_HINT2}}",
cls: 'a-text'
}
],
closeAction: 'hide',
defaultButton: 'validate',
buttonAlign: 'center',
buttons : [ {
itemId: 'validate',
reference: 'validate',
text :"{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_OK}}",
handler : function () { this._validateDelete(controller, this._deleteCourseBox, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents); },
scope: this
},
{
itemId: 'cancel',
reference: 'cancel',
text :"{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_CANCEL}}",
handler : function () { this._deleteCourseBox.close(); },
scope: this
}]
});
}
else
{
this._deleteCourseBox.down("#validate").setHandler(function () { this._validateDelete(controller, this._deleteCourseBox, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents); });
this._deleteCourseBox.down("#course-full").setBoxLabel("{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_RADIO_CHILD_LABEL}}<br/>" + fullHint);
}
},
/**
* Draw the delete program dialog box
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
* @param {Ametys.message.MessageTarget[]} contentTargets The content targets to delete
* @param {String[]} contentIdsToDelete The content IDs to delete
* @param {Object} contentsInfo information retrieved by the server organized by content id
* @param {Array} pathsToReferencedContents List of all the path referencing any of the content to delete
* @param {Integer} nbOnlyStructureContents The number of child contents in the structure concerned by deletion
* @param {Integer} nbCourses The number of child ELPs concerned by deletion
* @private
*/
_drawDeleteProgramPartDialog: function (controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses)
{
let structureOnlyHint = Ext.String.format("{{i18n PLUGINS_ODF_CONTENT_DELETE_MSGBOX_RADIO_NB_CONTENT_HINT}}", nbOnlyStructureContents + contentIdsToDelete.length); // add the size of selected contents to be deleted
let fullHint = Ext.String.format("{{i18n PLUGINS_ODF_CONTENT_DELETE_MSGBOX_RADIO_NB_CONTENT_HINT}}", nbOnlyStructureContents + nbCourses + contentIdsToDelete.length); // add the size of selected contents to be deleted
if (this._deleteProgramPartBox == null)
{
this._deleteProgramPartBox = Ext.create('Ametys.window.DialogBox', {
title :"{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_TITLE}}",
iconCls : 'ametysicon-delete30',
width : 600,
items : [{
xtype: 'component',
html: "{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_HINT1}}",
cls: 'a-text'
},
{
xtype: 'form',
items: [{
xtype: 'radiofield',
hideLabel: true,
checked: true,
boxLabel: "{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_RADIO_SINGLE_LABEL}}",
ametysDescription: "{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_RADIO_SINGLE_DESC}}",
name: 'mode',
inputValue: this.SINGLE_MODE,
itemId: "program-part-single",
style: {
marginLeft: '15px'
}
},
{
xtype: 'radiofield',
hideLabel: true,
boxLabel: "{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_RADIO_STRUCTURE_LABEL}}<br/>" + structureOnlyHint,
ametysDescription: "{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_RADIO_STRUCTURE_DESC}}",
name: 'mode',
inputValue: this.STRUCTURE_ONLY_MODE,
itemId: "program-part-structure-only",
style: {
marginLeft: '15px'
}
},
{
xtype: 'radiofield',
hideLabel: true,
boxLabel: "{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_RADIO_ALL_LABEL}}<br/>" + fullHint,
ametysDescription: "{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_RADIO_ALL_DESC}}",
name: 'mode',
inputValue: this.FULL_MODE,
itemId: "program-part-full",
style: {
marginLeft: '15px'
}
}]
},
{
xtype: 'component',
html: "{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_HINT2}}",
cls: 'a-text'
}
],
closeAction: 'hide',
defaultButton: 'validate',
buttonAlign: 'center',
buttons : [ {
itemId: 'validate',
reference: 'validate',
text :"{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_OK}}",
handler : function () { this._validateDelete(controller, this._deleteProgramPartBox, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents); },
scope: this
},
{
itemId: 'cancel',
reference: 'cancel',
text :"{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_CANCEL}}",
handler : function () { this._deleteProgramPartBox.close(); },
scope: this
}]
});
}
else
{
this._deleteProgramPartBox.down("#validate").setHandler(function () { this._validateDelete(controller, this._deleteProgramPartBox, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents); });
this._deleteProgramPartBox.down("#program-part-structure-only").setBoxLabel("{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_RADIO_STRUCTURE_LABEL}}<br/>" + structureOnlyHint);
this._deleteProgramPartBox.down("#program-part-full").setBoxLabel("{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_RADIO_ALL_LABEL}}<br/>" + fullHint);
}
},
/**
* Function invoked when validating the dialog box
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
* @param {Ametys.window.DialogBox} box The dialog box
* @param {Ametys.message.MessageTarget[]} contentTargets The content targets
* @param {String[]} contentIdsToDelete The content IDs to delete
* @param {Object} contentsInfo information retrieved by the server organized by content id
* @param {Array} pathsToReferencedContents List of all the path referencing any of the content to delete
* @private
*/
_validateDelete: function (controller, box, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents)
{
var deleteMode = box.down('form').getForm().findField("mode").getGroupValue();
box.close();
this._showConfirmMsg(controller, contentTargets, deleteMode, contentIdsToDelete, contentsInfo, pathsToReferencedContents);
},
/**
* Show confiramtion before deletion
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
* @param {Ametys.message.MessageTarget[]} contentTargets The content targets to delete
* @param {String} deleteMode the deletion mode
* @param {String[]} contentIdsToDelete The content IDs to delete
* @param {Object} contentInfo information retrieved by the server organized by content id
* @param {Array} pathsToReferencedContents List of all the path referencing any of the content to delete
* @private
*/
_showConfirmMsg: function(controller, contentTargets, deleteMode, contentIdsToDelete, contentsInfo, pathsToReferencedContents)
{
var contentDescriptions = this._getContentDescriptions(contentTargets, contentIdsToDelete, contentsInfo);
var intro = "";
switch (deleteMode)
{
case this.STRUCTURE_ONLY_MODE:
intro = contentDescriptions.length == 1 ? "{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_STRUCTURE_ONLY_MODE_MSGBOX_SINGLE}}": "{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_STRUCTURE_ONLY_MODE_MSGBOX_SEVERAL}}";
break;
case this.FULL_MODE:
intro = contentDescriptions.length == 1 ? "{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_FULL_MODE_MSGBOX_SINGLE}}": "{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_FULL_MODE_MSGBOX_SEVERAL}}";
break;
case this.SINGLE_MODE:
default:
intro = contentDescriptions.length == 1 ? "{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_SINGLE_MODE_MSGBOX_SINGLE}}": "{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_SINGLE_MODE_MSGBOX_SEVERAL}}";
break;
}
var contentList = "<ul>";
var idx = 0;
var maxItems = Ext.Array.min([contentDescriptions.length, 5]);
while (idx < maxItems)
{
if (idx < 4 || contentDescriptions.length == 5)
{
contentList += "<li>" + contentDescriptions[idx] + "</li>";
}
else
{
contentList += "<li>" + Ext.String.format("{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_MSGBOX_MORE}}", contentDescriptions.length - 4) + "</li>";
}
idx++;
}
contentList += "</ul>";
var items = [
{
xtype: 'component',
html: intro,
cls: 'a-text'
},
{
xtype: 'component',
html: contentList,
border: true,
cls: 'a-text',
scrollable: true,
maxHeight: 300
},
];
if (pathsToReferencedContents.length > 0)
{
var message = "<ul>\n";
pathsToReferencedContents.forEach(function(path, idx, paths) {
message += '<li>' + path.path + ' <strong>' + path.title + '</strong> (' + path.code + ')</li>\n';
});
message += "</ul>\n"
items.push(
{
xtype: 'component',
html: contentDescriptions.length == 1 ? "{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_MSGBOX_REFERENCED_SINGLE}}" : Ext.String.format("{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_MSGBOX_REFERENCED_SEVERAL}}", contentTargets.length),
cls: 'a-text'
}
);
items.push(
{
xtype: 'component',
html: message,
border: true,
cls: 'a-text',
scrollable: true,
maxHeight: 150
}
);
}
var box = Ext.create('Ametys.window.DialogBox', {
title :"{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_MSGBOX_TITLE}}",
iconCls : 'ametysicon-sign-question',
width : 650,
maxHeight: 500,
items : items,
defaultButton: 'validate',
closeAction: 'destroy',
buttonAlign: 'center',
buttons : [ {
itemId: 'validate',
reference: 'validate',
text :"{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_MSGBOX_YES_BTN}}",
handler : function () { box.close(); this._deleteConfirmed(controller, contentTargets, deleteMode, contentIdsToDelete); },
scope: this
},
{
itemId: 'cancel',
reference: 'cancel',
text :"{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_MSGBOX_NO_BTN}}",
handler : function () { box.close(); },
scope: this
}]
});
box.show();
},
_getContentDescriptions: function(contentTargets, contentIdsToDelete, contentsInfo)
{
var contentDescriptions = [];
contentTargets.forEach(function(target, _idx, _targets) {
if (Ext.Array.contains(contentIdsToDelete, target.getParameters().id))
{
if (contentsInfo[target.getParameters().id])
{
contentDescriptions.push("<strong>" + target.getParameters().title + "</strong> (" + contentsInfo[target.getParameters().id].code + ")");
}
else
{
contentDescriptions.push("<strong>" + target.getParameters().title + "</strong>");
}
}
});
return contentDescriptions;
},
/**
* Callback function invoked after the _showConfirmMsg box is closed
* @param {String} answer Id of the button that was clicked
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
* @param {Ametys.message.MessageTarget[]} contentTargets The content targets
* @param {String} deleteMode The deletion mode
* @param {String[]} contentIdsToDelete The content IDs to delete
* @private
*/
_deleteConfirmed: function(controller, contentTargets, deleteMode, contentIdsToDelete)
{
controller.serverCall('deleteContents', [contentIdsToDelete, { "mode": deleteMode }], Ext.bind(this._deleteCb, this),
{
priority: Ametys.data.ServerComm.PRIORITY_LONG_REQUEST,
arguments: {
contentTargets: contentTargets,
contentIdsToDelete: contentIdsToDelete
},
errorMessage: {
msg: "{{i18n PLUGINS_ODF_CONTENT_DELETE_MSGBOX_ERROR_MSG}}",
category: 'Ametys.plugins.odf.content.DeleteContentAction'
},
waitMessage: false
}
);
},
/**
* Callback function called after #act is processed.
* @param {Object} response The JSON result
* @param {Object} args The arguments
* @param {Ametys.message.MessageTarget[]} args.contentTargets The content targets
* @param {String[]} args.contentIdsToDelete The content IDs to delete
* @private
*/
_deleteCb: function (response, args)
{
var contentIdsToDelete = args.contentIdsToDelete;
var contentTargets = args.contentTargets;
var allInitialDeletedContents = [];
var deletedContentTargets = [];
for (var k in contentIdsToDelete)
{
var contentId = contentIdsToDelete[k];
var deletedContents = response[contentId]['deleted-contents'];
var initialContent = response[contentId]['initial-content'];
for (var i=0; i < deletedContents.length; i++)
{
var deletedContentId = deletedContents[i].id;
if (deletedContentId == initialContent.id)
{
allInitialDeletedContents.push(initialContent);
}
// Remove content from navigation history
Ametys.navhistory.HistoryDAO.removeEntry (deletedContentId);
var contentTarget = this._getTargetFromId(contentTargets, deletedContentId);
if (contentTarget)
{
deletedContentTargets.push(contentTarget);
}
}
}
// Fires deleted event
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.DELETED,
// All ODF contents are trashable
parameters : {trashed : true},
targets: deletedContentTargets
});
this._showReport(response, contentIdsToDelete, allInitialDeletedContents);
},
/**
* Get the target from the content id
* @param {Ametys.message.MessageTarget[]} contentTargets The content targets
* @param {String} contentId The content ID
* @private
*/
_getTargetFromId: function (contentTargets, contentId)
{
var target = null;
Ext.Array.forEach (contentTargets, function (localContentTarget) {
if (contentId == localContentTarget.getParameters().id)
{
target = localContentTarget;
return false; // stop iteration;
}
});
return target;
},
/**
* Display report after deletion
* @param {Object} response The JSON result
* @param {String[]} contentIdsToDelete The content IDs to delete
* @param {Object[]} allInitialDeletedContents The initial deleted contents
* @private
*/
_showReport: function(response, contentIdsToDelete, allInitialDeletedContents)
{
var referencedContents = response["all-referenced-contents"];
var lockedContents = response["all-locked-contents"];
var unauthorizedContents = response["all-unauthorized-contents"];
var undeletedContents = response["all-undeleted-contents"];
for (var i in contentIdsToDelete)
{
var contentIdToDelete = contentIdsToDelete[i];
var contentInfo = response[contentIdToDelete];
// If check before deletion failed, the initial content is no deleted because some contents are referenced, locked or unauthorized
if (contentInfo['check-before-deletion-failed'])
{
if (contentInfo['referenced-contents'].length > 0 || contentInfo['unauthorized-contents'].length > 0 || contentInfo['locked-contents'].length > 0)
{
undeletedContents.push(contentInfo['initial-content']);
}
}
}
// Prerequisites for deletion are not met, display an error message
if (undeletedContents.length > 0 || lockedContents.length > 0 || unauthorizedContents.length > 0 || referencedContents.length > 0)
{
var message = Ametys.cms.content.ContentDAO._buildErrorMessage(message, undeletedContents, "{{i18n plugin.cms:CONTENT_DELETE_FAILED_CONTENTS}}<strong>", "</strong>");
if (lockedContents.length > 0 || unauthorizedContents.length > 0 || referencedContents.length > 0)
{
// If there are some undeleted contents, we add this message to explain the following reasons
if (undeletedContents.length > 0)
{
message += "<br/><br/>{{i18n plugin.odf:PLUGINS_ODF_CONTENT_DELETE_CONTENTS_ERROR_START}}";
}
message = Ametys.cms.content.ContentDAO._buildErrorMessage(message, lockedContents, "{{i18n plugin.odf:PLUGINS_ODF_CONTENT_DELETE_LOCKED_CONTENTS}}<strong>", "</strong>");
message = Ametys.cms.content.ContentDAO._buildErrorMessage(message, unauthorizedContents, "{{i18n plugin.cms:CONTENT_DELETE_UNAUTHORIZED_CONTENTS}}<strong>", "</strong>");
message = Ametys.cms.content.ContentDAO._buildErrorMessage(message, referencedContents, "{{i18n plugin.cms:CONTENT_DELETE_REFERENCED_CONTENTS}}<strong>", "</strong>.<br/>{{i18n plugin.cms:CONTENT_DELETE_REFERENCED_CONTENTS_END}}");
}
// Notify error in content deletion
Ametys.notify({
type: 'error',
iconGlyph: 'ametysicon-text70',
title: "{{i18n plugin.cms:CONTENT_DELETE_LABEL}}",
description: message
});
}
if (allInitialDeletedContents.length > 0)
{
var message = '';
if (allInitialDeletedContents.length > 1)
{
var msgPart1 = Ext.String.format("{{i18n plugin.odf:PLUGINS_ODF_CONTENT_DELETE_CONTENTS_OK_MSG_SEVERAL_PART1}}", allInitialDeletedContents.length);
message = Ametys.cms.content.ContentDAO._buildErrorMessage(message, allInitialDeletedContents, msgPart1 + "<strong>", "</strong>{{i18n plugin.odf:PLUGINS_ODF_CONTENT_DELETE_CONTENTS_OK_MSG_SEVERAL_PART2}}");
}
else
{
message = Ametys.cms.content.ContentDAO._buildErrorMessage(message, allInitialDeletedContents, "{{i18n plugin.odf:PLUGINS_ODF_CONTENT_DELETE_CONTENTS_OK_MSG_SINGLE_PART1}}<strong>", "</strong>{{i18n plugin.odf:PLUGINS_ODF_CONTENT_DELETE_CONTENTS_OK_MSG_SINGLE_PART2}}");
}
// Notify content deletion
Ametys.notify({
type: 'info',
iconGlyph: 'ametysicon-text70',
title: "{{i18n plugin.cms:PLUGINS_CMS_NOTIFICATION_DELETE_CONTENT_TITLE}}",
description: message
});
}
}
});