/*
* Copyright 2017 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 helper provides a dialog box to copy an odf content as a new content.
* The dialog box brings the duplication mode for the odf content.
* See #open method.
* @private
*/
Ext.define('Ametys.plugins.odf.content.helper.CopyODFContent', {
singleton: true,
/**
* @readonly
* @property {String} SINGLE_MODE Constant for single duplication mode
*/
SINGLE_MODE : 'single',
/**
* @readonly
* @property {String} STRUCTURE_ONLY_MODE Constant for "structure only" duplication mode
*/
STRUCTURE_ONLY_MODE: 'structure_only',
/**
* @readonly
* @property {String} FULL_MODE Constant for full duplication mode
*/
FULL_MODE: 'full',
/**
* @property {Ametys.window.DialogBox} _box The dialog box
* @private
*/
/**
* @property {String} _content The copied content.
* @private
*/
/**
* @property {Number} [_workflowInitActionId=111] The id of the workflow action to initialize the duplicated content. Can be null to use the default value.
* @private
*/
/**
* @property {Number} [_workflowEditActionId=2] The id of the workflow action to edit the target content. Can be null to use the default value.
* @private
*/
/**
* @property {String} [_viewName="default-edition"] The name of the view to be displayed in attributes tree. Can be null to use the default value.
* @private
*/
/**
* @property {String} [_fallbackViewName="main"] The fallback view to be displayed in attributes tree. Used (for legacy purpose) when _viewName is not found.
* @private
*/
/**
* @property {String} [_viewMode="edition"] The mode of the view to be displayed in attributes tree Can be null to use the default value.
* @private
*/
/**
* @property {Object} _parentContentTarget The parent content of the copied content. Can be null
* @private
*/
/**
* @property {Boolean} _hasChildren True if the content to be copied has children
* @private
*/
/**
* @property {Function} _cbFn The callback function to be called after copy process
* @property {Object} _cbFn.report The copy report
* @private
*/
/**
* @property {Object} _scope The scope of the callback function. Can be null.
* @private
*/
/**
* Open a dialog box to select duplication mode to copy content as a new content
* @param {Object} config The configuration options. Has the following parameters:
* @param {Ametys.cms.content.Content} config.content (required) The content to copied
* @param {String} [config.icon] The full path to icon (16x16) for the dialog box
* @param {String} [config.title] The title of the dialog box.
* @param {String} [config.helpMsg] The message displayed at the top of the dialog box.
* @param {Number} [config.workflowInitActionId=111] The workflow action id for copy content as a new content
* @param {Number} [config.workflowEditActionId=2] The workflow action id for editing the target content
* @param {String} [config.viewName="default-edition"] The view name
* @param {String} [config.fallbackViewName="main"] The fallback view name
* @param {String} [config.viewMode="edition"] The view mode ('view' or 'edition')
* @param {Object} config.parentContentTarget The parent content of the copied content.
* @param {Boolean} config.hasChildren True if the content to be copied has children
* @param {Function} config.callback Callback function called after the dialog box is closed and the copy is processed.
* @param {Object} config.callback.report The copy report
* @param {Object} [config.scope] The callback scope.
*/
open: function(config)
{
if (!config.content)
{
Ametys.Msg.show({
title: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENTVALUES_ERROR_TITLE}}",
msg: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_NO_COPIED_CONTENT}}",
buttons: Ext.Msg.OK,
icon: Ext.Msg.ERROR
});
return;
}
this._cbFn = config.callback || Ext.emptyFn;
this._scope = config.scope;
this._content = config.content;
this._viewName = config.viewName || 'default-edition';
this._fallbackViewName = config.fallbackViewName || 'main';
this._viewMode = config.viewMode || 'edition';
this._workflowInitActionId = config.workflowInitActionId || 111;
this._workflowEditActionId = config.workflowEditActionId || 2;
this._parentContentTarget = config.parentContentTarget || null;
this._hasChildren = config.hasChildren || false;
// Check the user rights by retrieve the content type
var me = this;
var contentTypes = Ametys.cms.content.ContentTypeDAO.getContentTypes().createFiltered(function(contentType) {
return me._content.getTypes().indexOf(contentType.getId()) != -1
&& contentType.hasRight()
&& !contentType.isMixin()
&& !contentType.isAbstract();
});
if (contentTypes.count() != this._content.getTypes().length)
{
Ametys.Msg.show({
title: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENTVALUES_ERROR_TITLE}}",
msg: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_NO_RIGHT_MSG}}",
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
return;
}
var types = this._content.getTypes();
if (!this._hasChildren)
{
this._drawDuplicateDefaultBox('ametysicon-clipboard99',
"{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_LABEL}}",
"{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_DIALOG_HELPMESSAGE1}}" + "<b>'" + this._content.getTitle() + "'</b>.");
}
else if (Ext.Array.contains(types, "org.ametys.plugins.odf.Content.course"))
{
this._drawDuplicateCourseBox('ametysicon-clipboard99',
"{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_LABEL}}",
"{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_DIALOG_HELPMESSAGE1}}" + "<b>'" + this._content.getTitle() + "'</b>.");
}
else if (Ext.Array.contains(types, "org.ametys.plugins.odf.Content.courseList"))
{
this._drawDuplicateCourseListBox('ametysicon-clipboard99',
"{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_LABEL}}",
"{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_DIALOG_HELPMESSAGE1}}" + "<b>'" + this._content.getTitle() + "'</b>.");
}
else
{
this._drawDuplicateProgramPartBox('ametysicon-clipboard99',
"{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_LABEL}}",
"{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_DIALOG_HELPMESSAGE1}}" + "<b>'" + this._content.getTitle() + "'</b>.");
}
},
/**
* Creates the duplicate dialog box if it is not already created. Only for odf content with no children, we don't ask for duplication mode.
* @param {String} iconCls The css classname to display an icon (with a glyph for example)
* @param {String} title The title of the dialog box.
* @param {String} helpMsg The message displayed at the top of the dialog box.
* @private
*/
_drawDuplicateDefaultBox: function(iconCls, title, helpMsg)
{
if (this._duplicateDefaultBox == null)
{
this._duplicateDefaultBox = Ext.create('Ametys.window.DialogBox', {
title: title,
iconCls: iconCls,
width: 600,
scrollable: false,
items: this._getDefaultItems(helpMsg),
closeAction: 'hide',
defaultFocus: 'content-title',
selectDefaultFocus: true,
referenceHolder: true,
defaultButton: 'validate',
buttons : [{
reference: 'validate',
text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_BTN_OK}}",
handler: function() {this._ok(this._duplicateDefaultBox)},
scope: this,
itemId: 'btn-ok'
}, {
text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_BTN_CANCEL}}",
handler: Ext.bind(function() {this._duplicateDefaultBox.close();}, this)
}]
});
}
else
{
this._duplicateDefaultBox.setIconCls(iconCls);
this._duplicateDefaultBox.setTitle(title);
this._duplicateDefaultBox.items.getAt(0).update(helpMsg);
}
this._duplicateDefaultBox.down('#content-title').setValue(this._content.getTitle() + "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_TITLE_SUFFIX}}");
this._duplicateDefaultBox.show();
},
/**
* Creates the duplicate dialog box for course if it is not already created.
* @param {String} iconCls The css classname to display an icon (with a glyph for example)
* @param {String} title The title of the dialog box.
* @param {String} helpMsg The message displayed at the top of the dialog box.
* @private
*/
_drawDuplicateCourseBox: function(iconCls, title, helpMsg)
{
if (this._duplicateCourseBox == null)
{
var items = this._getDefaultItems(helpMsg);
items.push({
xtype: 'form',
items: [
this._createRadioField(this.STRUCTURE_ONLY_MODE, "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_COURSE_RADIO_FIELD_SINGLE_LABEL}}", false),
this._createRadioField(this.FULL_MODE, "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_COURSE_RADIO_FIELD_FULL_LABEL}}", true)
]
});
this._duplicateCourseBox = Ext.create('Ametys.window.DialogBox', {
title: title,
iconCls: iconCls,
width: 600,
scrollable: false,
items: items,
closeAction: 'hide',
defaultFocus: 'content-title',
selectDefaultFocus: true,
referenceHolder: true,
defaultButton: 'validate',
buttons : [{
reference: 'validate',
text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_BTN_OK}}",
handler: function() {this._ok(this._duplicateCourseBox)},
scope: this,
itemId: 'btn-ok'
}, {
text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_BTN_CANCEL}}",
handler: Ext.bind(function() {this._duplicateCourseBox.close();}, this)
}]
});
}
else
{
this._duplicateCourseBox.setIconCls(iconCls);
this._duplicateCourseBox.setTitle(title);
this._duplicateCourseBox.items.getAt(0).update(helpMsg);
}
this._duplicateCourseBox.down('#content-title').setValue(this._content.getTitle() + "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_TITLE_SUFFIX}}");
this._duplicateCourseBox.show();
},
/**
* Creates the duplicate dialog box for course list if it is not already created
* @param {String} iconCls The css classname to display an icon (with a glyph for example)
* @param {String} title The title of the dialog box.
* @param {String} helpMsg The message displayed at the top of the dialog box.
* @private
*/
_drawDuplicateCourseListBox: function(iconCls, title, helpMsg)
{
if (this._duplicateCourseListBox == null)
{
var items = this._getDefaultItems(helpMsg);
items.push({
xtype: 'form',
items: [
this._createRadioField(this.SINGLE_MODE, "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_COURSE_LIST_RADIO_FIELD_SINGLE_LABEL}}", false),
this._createRadioField(this.FULL_MODE, "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_COURSE_LIST_RADIO_FIELD_FULL_LABEL}}", true)
]
});
this._duplicateCourseListBox = Ext.create('Ametys.window.DialogBox', {
title: title,
iconCls: iconCls,
width: 600,
scrollable: false,
items: items,
closeAction: 'hide',
defaultFocus: 'content-title',
selectDefaultFocus: true,
referenceHolder: true,
defaultButton: 'validate',
buttons : [{
reference: 'validate',
text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_BTN_OK}}",
handler: function() {this._ok(this._duplicateCourseListBox)},
scope: this,
itemId: 'btn-ok'
}, {
text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_BTN_CANCEL}}",
handler: Ext.bind(function() {this._duplicateCourseListBox.close();}, this)
}]
});
}
else
{
this._duplicateCourseListBox.setIconCls(iconCls);
this._duplicateCourseListBox.setTitle(title);
this._duplicateCourseListBox.items.getAt(0).update(helpMsg);
}
this._duplicateCourseListBox.down('#content-title').setValue(this._content.getTitle() + "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_TITLE_SUFFIX}}");
this._duplicateCourseListBox.show();
},
/**
* Creates the duplicate dialog box for program part if it is not already created
* @param {String} iconCls The css classname to display an icon (with a glyph for example)
* @param {String} title The title of the dialog box.
* @param {String} helpMsg The message displayed at the top of the dialog box.
* @private
*/
_drawDuplicateProgramPartBox: function(iconCls, title, helpMsg)
{
if (this._duplicateProgramPartBox == null)
{
var items = this._getDefaultItems(helpMsg);
items.push({
xtype: 'form',
items: [
this._createRadioField(this.SINGLE_MODE, "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_PROGRAM_PART_RADIO_FIELD_SINGLE_LABEL}}", false),
this._createRadioField(this.STRUCTURE_ONLY_MODE, "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_PROGRAM_PART_RADIO_FIELD_STRUCTURE_LABEL}}", true),
this._createRadioField(this.FULL_MODE, "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_PROGRAM_PART_RADIO_FIELD_FULL_LABEL}}", false)
]
});
this._duplicateProgramPartBox = Ext.create('Ametys.window.DialogBox', {
title: title,
iconCls: iconCls,
width: 600,
scrollable: false,
items: items,
closeAction: 'hide',
defaultFocus: 'content-title',
selectDefaultFocus: true,
referenceHolder: true,
defaultButton: 'validate',
buttons : [{
reference: 'validate',
text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_BTN_OK}}",
handler: function() {this._ok(this._duplicateProgramPartBox)},
scope: this,
itemId: 'btn-ok'
}, {
text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_BTN_CANCEL}}",
handler: Ext.bind(function() {this._duplicateProgramPartBox.close();}, this)
}]
});
}
else
{
this._duplicateProgramPartBox.setIconCls(iconCls);
this._duplicateProgramPartBox.setTitle(title);
this._duplicateProgramPartBox.items.getAt(0).update(helpMsg);
}
this._duplicateProgramPartBox.down('#content-title').setValue(this._content.getTitle() + "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_TITLE_SUFFIX}}");
this._duplicateProgramPartBox.show();
},
/**
* Creates one radio field item
* @param {String} inputValue the input value
* @param {String} label The label of the radio field
* @param {Boolean} checked True if the radio field is checked
* @private
*/
_createRadioField: function(inputValue, label, checked)
{
return {
xtype: 'radiofield',
hideLabel: true,
checked: checked,
boxLabel: label,
name: 'mode',
inputValue: inputValue,
style: {
marginLeft: '15px'
}
};
},
/**
* Get the default item of duplicate dialog box : the help message with the new title field
* @param {String} helpMsg The message displayed at the top of the dialog box.
* @private
*/
_getDefaultItems: function(helpMsg)
{
return [{
xtype: 'component',
cls: 'a-text',
html: helpMsg
},
{
xtype: 'container',
style: {
marginTop: '5px',
marginBottom: '5px'
},
items: {
xtype: 'textfield',
width: 340,
labelAlign: 'right',
labelWidth: 70,
cls: 'ametys',
name: 'contentTitle',
fieldLabel: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_TITLE_LABEL}}",
ametysDescription: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_TITLE_DESC}}",
itemId: 'content-title',
allowBlank: false,
msgTarget: 'side',
validator: function (value) {
var s = Ext.String.deemphasize(value);
if (/^([0-9\-]*|[0-9\-]+.*)[a-z].*$/i.test(s))
{
return true;
}
else
{
return "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_TITLE_INVALID}}";
}
}
},
}];
},
/**
* This function is called when validating the dialog box.
* Aggregate the parameters to make the server request.
* Run the duplication action on the server.
* @param {Ametys.window.DialogBox} box The dialog box
* @private
*/
_ok: function(box)
{
// Title
var titleField = box.down('#content-title');
if (!titleField.isValid())
{
return null;
}
var baseContentId = this._content.getId();
var newContentTitle = titleField.getValue();
var viewName = this._viewName;
var fallbackViewName = this._fallbackViewName;
var viewMode = this._viewMode;
var duplicationMode = box.down('form') != null ? box.down('form').getForm().findField("mode").getGroupValue() : null;
var parentContentId = this._parentContentTarget != null ? this._parentContentTarget.getParameters().id : null;
Ametys.data.ServerComm.callMethod({
role: "org.ametys.core.ui.RibbonControlsManager",
id: "org.ametys.odf.content.PasteContent",
methodName: "createContentByCopy",
priority: Ametys.data.ServerComm.PRIORITY_LONG_REQUEST,
parameters: [baseContentId, newContentTitle, viewName, fallbackViewName, viewMode, this._workflowInitActionId, this._workflowEditActionId, duplicationMode, parentContentId],
callback: {
scope: this,
handler: this._okCb,
ignoreOnError: false
},
errorMessage: {
category: Ext.getClassName(this) + '._ok'
}
});
Ametys.Msg.show({
title: "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_LABEL}}",
msg: "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_WAIT_INFO}}",
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.INFO
});
box.close();
},
/**
* Callback function called after copy is processed.
* Fires Ametys.message.Message.CREATED message for new created content
* @param {Object} response The JSON result from server :
* @param {String} response.mainContentId The id of main created content
* @param {String[]} response.contentIds The id of created contents
* @param {Object} response.report The copy report
* @param {Object[]} args The callback parameters passed to the {@link Ametys.data.ServerComm#callMethod} method
* @private
*/
_okCb: function(response, args)
{
if (response != null)
{
var contentIds = response.contentIds ? Object.values(response.contentIds) : [];
if (contentIds.length > 0 && contentIds[0] != '')
{
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.CREATED,
targets: {
id: Ametys.message.MessageTarget.CONTENT,
parameters: { ids: contentIds }
}
});
if (this._parentContentTarget != null)
{
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.MODIFIED,
targets: {
id: Ametys.message.MessageTarget.CONTENT,
parameters: { ids: [this._parentContentTarget.getParameters().id] }
}
});
}
}
this._cbFn.call(this._scope, response);
// CMS-5137 Open directly the main created content after copied
var mainContentId = response.mainContentId;
if (mainContentId)
{
Ametys.tool.ToolsManager.openTool('uitool-content', {id: mainContentId});
}
}
}
});