/*
* 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.
*/
/**
* Singleton class defining actions related to the ODF root
* @private
*/
Ext.define('Ametys.plugins.odf.web.root.ODFRootActions', {
singleton: true,
/**
* @private
* @property {Boolean} _initialized Indicates if the dialog box has been initialized
*/
/**
* @private
* @property {Ametys.form.ConfigurableFormPanel} _formPanel The form panel
*/
/**
* @private
* @property {Ametys.window.DialogBox} _box The dialog box
*/
/**
* @private
* @property {String} _pageId Identifier of the current page
*/
/**
* @private
* @property {String} _defaultFirstLevel The default value for the first level combo
*/
/**
* @private
* @property {String} _defaultSecondLevel The default value for the second level combo
*/
/**
* @private
* @property {Ametys.ribbon.element.ui.ButtonController} _controller The button controller that initialized the action
*/
/**
* @private
* @property {Object} _rootPageInfo Object containing the info related to the odf root status of the current page
*/
/**
* Action function to be called by the controller.
* Allow an user to add or remove an ODF root from the current page
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
addOrRemove: function (controller)
{
var pageTarget = controller.getMatchingTargets()[0],
pageId;
if (pageTarget)
{
pageId = pageTarget.getParameters().id;
controller.serverCall('getOdfRootPageInfo', [pageId], Ext.bind(this._getPageInfoCb, this), {
errorMessage: true,
arguments: {
pageId: pageId,
defaultFirstLevel: controller.getInitialConfig('default-first-level'),
defaultSecondLevel: controller.getInitialConfig('default-second-level'),
controller: controller
}
});
}
},
/**
* Callback once root page properties are retrieved
* @param {Object} properties the root page properties
* @param {Object} arguments The callback arguments
*/
_getPageInfoCb: function(properties, arguments)
{
if (properties.noCatalog === true)
{
Ametys.Msg.show({
title: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_TITLE}}",
msg: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_NO_CATALOG}}",
buttons: Ext.Msg.OK,
icon: Ext.Msg.ERROR
});
return;
}
this._pageId = arguments.pageId;
this._defaultFirstLevel = arguments.defaultFirstLevel;
this._defaultSecondLevel = arguments.defaultSecondLevel;
this._controller = arguments.controller;
this._rootPageInfo = properties;
this._createDialogBox(properties);
this._initForm();
},
/**
* @private
* Create the dialog box if necessary
* @param {Object} properties Properties for the different field of the dialogbox
*/
_createDialogBox: function(properties)
{
if (this._initialized)
{
return;
}
this._form = Ext.create('Ext.form.Panel', {
border: false,
layout: {
type: 'vbox',
align: 'stretch'
},
defaults: {
cls: 'ametys',
labelWidth: 170,
labelAlign: 'right',
labelSeparator: '',
msgTarget: 'side'
},
items: this._getFormItemsCfg(properties)
});
this._box = Ext.create('Ametys.window.DialogBox', {
title: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_CHOICE_TITLE}}",
iconCls: 'ametysicon-website38 decorator-odficon-blackboard',
width: 530,
items : [ this._form ],
referenceHolder: true,
// FIXME default button does not seems to work...
defaultButton: 'validate',
closeAction: 'hide',
buttons : [{
reference: 'validate',
text : "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_CHOICE_OK_BUTTON}}",
handler : this._validate,
scope: this
}, {
reference: 'remove',
text: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_CHOICE_DELETE_BUTTON}}",
disabled: true,
handler: this._remove,
scope: this
}, {
reference: 'cancel',
text :"{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_CHOICE_CANCEL_BUTTON}}",
handler: this._cancel,
scope: this
}]
});
this._initialized = true;
return;
},
/**
* Provide the items configuration of the form panel
* @param {Object} properties Properties for the different field of the dialogbox
* @return {Object/Object[]} the items configuration of the form panel
*/
_getFormItemsCfg: function(properties)
{
var catalogStore = this._getCatalogStoreCfg(),
firstLevelStore = this._getLevelStoreCfg(Ext.bind(this._onFirstLevelLoad, this)),
secondLevelStore = this._getLevelStoreCfg(Ext.bind(this._onSecondLevelLoad, this));
return [{
xtype: 'component',
cls: 'a-text',
html: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_CHOOSE_CATALOG}}"
}, {
xtype: 'combobox',
reference: 'catalog',
name: 'catalog',
fieldLabel: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_CHOICE_CATALOG}}",
ametysDescription: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_CHOICE_CATALOG_DESC}}",
editable: false,
forceSelection: true,
allowBlank: false,
queryMode: 'local',
valueField: 'code',
displayField: 'label',
store: catalogStore
}, {
xtype: 'component',
cls: 'a-text',
html: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_LEVEL_HINT}}"
}, {
xtype: 'combobox',
reference: 'firstLevel',
name: 'firstLevel',
fieldLabel: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_CHOICE_FIRST_LEVEL}}",
ametysDescription: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_CHOICE_FIRST_LEVEL_DESC}}",
editable: false,
forceSelection: true,
queryMode: 'local',
valueField: 'name',
displayField: 'label',
store: firstLevelStore,
listeners: {'change': {fn: this._onFirstLevelChange, scope: this}}
}, {
xtype: 'combobox',
reference: 'secondLevel',
name: 'secondLevel',
fieldLabel: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_CHOICE_SECOND_LEVEL}}",
ametysDescription: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_CHOICE_SECOND_LEVEL_DESC}}",
editable: false,
forceSelection: true,
queryMode: 'local',
valueField: 'name',
displayField: 'label',
store: secondLevelStore,
listeners: {'change': {fn: this._onSecondLevelChange, scope: this}}
}, {
xtype: 'component',
cls: 'a-text',
html: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_CHILDREN_INDEXATION}}"
}, {
xtype: "checkbox",
fieldLabel: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_ARE_CHILDREN_INDEXABLE}}",
ametysDescription: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_CHILDREN_INDEXATION}}",
reference: 'areChildrenIndexable',
name: 'areChildrenIndexable',
/*style: {
marginLeft: '125px'
}*/
}]
},
/**
* Catalog store config getter
* @return {Object} the catalog store config
*/
_getCatalogStoreCfg: function()
{
return {
type: 'store',
proxy: {
type: 'ametys',
plugin: 'odf-web',
url: 'catalogs/list.json',
reader: {
type: 'json'
}
},
fields: [
'code',
{name: 'label', type: 'string'}
],
sortOnLoad: true,
sorters: [{property: 'label', direction:'ASC'}],
listeners: {
'beforeload': Ext.bind(this._onCatalogBeforeLoad, this),
'load': Ext.bind(this._onCatalogLoad, this)
}
}
},
/**
* Lvel store config getter
* @param {Function} loadListener A specific load listener for the store
* @return {Object} the level store config
*/
_getLevelStoreCfg: function(loadListener)
{
return {
type: 'store',
proxy: {
type: 'ametys',
plugin: 'odf-web',
url: 'eligible-metadata/list.json',
reader: {
type: 'json'
}
},
fields: [
'name',
{name: 'label', type: 'string'}
],
sortOnLoad: true,
sorters: [{property: 'label', direction:'ASC'}],
listeners: {
'load': loadListener
}
}
},
/**
* @private
* Listener when first level has changed
* @param {Ext.form.field.ComboBox} field the field
* @param {String} newValue the new value
* @param {String} oldValue the old value
*/
_onFirstLevelChange: function(field, newValue, oldValue)
{
var secondLevelValue = this._form.getForm().findField('secondLevel').getValue();
if (!Ext.isEmpty(newValue))
{
if (newValue == secondLevelValue)
{
field.markWarning("{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_SAME_LEVELS_WARN}}");
}
else
{
field.clearWarning();
}
}
else
{
field.clearWarning();
}
},
/**
* @private
* Listener when second level has changed
* @param {Ext.form.field.ComboBox} field the field
* @param {String} newValue the new value
* @param {String} oldValue the old value
*/
_onSecondLevelChange: function(field, newValue, oldValue)
{
if (!Ext.isEmpty(newValue))
{
var firstLevelValue = this._form.getForm().findField('firstLevel').getValue();
if (newValue == firstLevelValue)
{
field.markWarning("{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_SAME_LEVELS_WARN}}");
}
else
{
field.clearWarning();
}
}
else
{
field.clearWarning();
}
},
/**
* @private
* Initialize the box form
*/
_initForm: function ()
{
this._form.reset();
// remove button status
this._box.lookupReference('remove').setDisabled(this._rootPageInfo.isOdfRootPage !== true);
this._box.lookupReference('catalog').getStore().load();
this._box.lookupReference('firstLevel').getStore().load();
this._box.lookupReference('secondLevel').getStore().load();
this._box.lookupReference('areChildrenIndexable').setValue(this._rootPageInfo.areChildrenIndexable);
},
/**
* @private
* Called before the catalog store is loaded in order to set the current page id for the load request.
* @param {Ext.data.Store} store The catalog store
* @param {Ext.data.operation.Operation} operation The Ext.data.operation.Operation object that will be passed to the Proxy to load the Store
*/
_onCatalogBeforeLoad: function(store, operation)
{
var params = operation.getParams() || {};
operation.setParams(Ext.apply(params, {
id: this._pageId
}));
},
/**
* @private
* Called whenever the catalog store reads the remote data.
* Used to update the catalog field state (value, disabled...)
* @param {Ext.data.Store} store The catalog store
* @param {Ext.data.Model[]} records An array of records
* @param {Boolean} successful True if the operation was successful
*/
_onCatalogLoad: function(store, records, successful)
{
var catalogField = this._box.lookupReference('catalog');
catalogField.setReadOnly(true);
if (!successful)
{
return;
}
if (records.length == 0)
{
Ametys.Msg.show({
title: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_TITLE}}",
msg: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_NO_MORE_ADD}}",
buttons: Ext.Msg.OK,
icon: Ext.Msg.INFO
});
return;
}
if (records.length == 1)
{
catalogField.setValue(records[0].get('code'));
}
else
{
catalogField.setReadOnly(false); // enable the field
if (this._rootPageInfo.isOdfRootPage === true)
{
catalogField.setValue(this._rootPageInfo.catalog);
}
}
// box is shown once catalog list is correct
this._box.show();
},
/**
* @private
* Called whenever the level store reads the remote data.
* Used to update the catalog field state (value, disabled...)
* @param {Ext.data.Store} store The catalog store
* @param {Ext.data.Model[]} records An array of records
* @param {Boolean} successful True if the operation was successful
*/
_onFirstLevelLoad: function(store, records, successful)
{
if (!successful)
{
return;
}
store.add({name: '', label: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_NONE_OPTION}}"});
var firstLevel = this._box.lookupReference('firstLevel');
if (this._rootPageInfo.isOdfRootPage === true)
{
firstLevel.setValue(this._rootPageInfo.firstLevel);
}
else
{
firstLevel.setValue(this._defaultFirstLevel);
}
},
/**
* @private
* Called whenever the level store reads the remote data.
* Used to update the catalog field state (value, disabled...)
* @param {Ext.data.Store} store The catalog store
* @param {Ext.data.Model[]} records An array of records
* @param {Boolean} successful True if the operation was successful
*/
_onSecondLevelLoad: function(store, records, successful)
{
if (!successful)
{
return;
}
store.add({name: '', label: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_NONE_OPTION}}"});
var secondLevel = this._box.lookupReference('secondLevel');
if (this._rootPageInfo.isOdfRootPage === true)
{
secondLevel.setValue(this._rootPageInfo.secondLevel);
}
else
{
secondLevel.setValue(this._defaultSecondLevel);
}
},
/**
* @private
* Validate button handler function
*/
_validate: function()
{
var form = this._form.getForm();
if (!form.isValid())
{
return;
}
var values = form.getValues();
if (values.secondLevel != "" && values.firstLevel == "")
{
form.findField('firstLevel').markInvalid("{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_NO_FIRST_LEVEL_ERROR}}");
return;
}
Ametys.MessageBox.show({
title: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_LABEL}}",
message: "{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_CONFIRM}}",
buttons: Ext.Msg.YESNO,
icon: Ext.Msg.WARNING,
fn: function (btn) {
if (btn == 'yes')
{
var values = form.getValues();
var params = [
this._pageId,
values.catalog,
values.firstLevel,
values.secondLevel,
values.areChildrenIndexable == 'on'
];
this._controller.serverCall('addOrUpdateOdfRootProperty', params, Ext.bind(this._successCb, this), {
waitMessage: this._box,
errorMessage: true,
priority: Ametys.data.ServerComm.PRIORITY_LONG_REQUEST
});
}
},
scope: this
});
},
/**
* @private
* remove button handler function
*/
_remove: function()
{
Ametys.Msg.confirm(
"{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_DELETE_TITLE}}",
"{{i18n plugin.odf-web:PLUGINS_ODFWEB_ODF_ROOT_PAGE_DELETE_CONFIRM}}",
this._removeAfterConfirm,
this
);
},
/**
* Callback called after the user confirm or cancel the remove action
* @private
* @param {String} answer 'yes' if the user confirmed the remove action
*/
_removeAfterConfirm: function(answer)
{
if (answer == 'yes')
{
this._controller.serverCall('removeOdfRootPage', [this._pageId], Ext.bind(this._successCb, this), {
waitMessage: this._box,
errorMessage: true
});
}
},
/**
* @private
* Success callback function, called after a validate or remove operation
* @param {Object} response The server response
* @param {Object} arguments The arguments
*/
_successCb: function()
{
Ext.create('Ametys.message.Message', {
type: Ametys.message.Message.MODIFIED,
parameters: {major: true},
targets: [{
id: Ametys.message.MessageTarget.PAGE,
parameters: {
ids: [this._pageId]
}
}]
});
this._box.close();
},
/**
* The cancel button handler
* @private
*/
_cancel: function()
{
this._box.close();
}
});