/*
* 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 class provides a widget to select one or more content types.<br>
* This embeds a drop down list with content types name and content types tree selection through a dialog box.<br>
*/
Ext.define('Ametys.cms.form.widget.SelectContentTypes', {
extend: 'Ametys.form.AbstractQueryableComboBox',
/**
* @cfg {Object} buttonConfig The configuration object for the button to open content types tree dialog box.
*/
/**
* @cfg {String} [buttonText=""] the text of the content types tree button.
*/
buttonText: '',
/**
* @cfg {String} buttonIcon The button icon path for the content types tree button.
*/
buttonIcon: null,
/**
* @cfg {String} buttonIconCls The CSS class to the content types tree button.
*/
buttonIconCls: 'ametysicon-squares36',
/**
* @cfg {String} buttonTooltip The button icon tooltip for the content types tree button.
*/
buttonTooltip: "{{i18n PLUGIN_CMS_WIDGET_SELECTCONTENTTYPES_TOOLTIP_BUTTON}}",
/**
* @cfg {String} contentTypesDialogTitle Title of the dialog box to choose content type(s). See {@link Ametys.cms.form.widget.ChooseContentTypes#open}.
*/
contentTypesDialogTitle: "{{i18n PLUGIN_CMS_WIDGET_SELECTCONTENTTYPES_DIALOG_TITLE}}",
/**
* @cfg {String} contentTypesDialogIconCls The full icon path for the dialog box to choose content type(s). See {@link Ametys.cms.form.widget.ChooseContentTypes#open}.
*/
contentTypesDialogIconCls: 'ametysicon-squares36',
/**
* @cfg {String} chooseContentTypesDialogHint The help message to display on top of dialog box to choose content type(s). See {@link Ametys.cms.form.widget.ChooseContentTypes#open}.
*/
chooseContentTypesDialogHint: "{{i18n PLUGIN_CMS_WIDGET_SELECTCONTENTTYPES_DIALOG_HINT}}",
/**
* @cfg {Object} enumeration The list of available values.
*/
/**
* @cfg {Boolean/String} [naturalOrder=false] True to sort drop down list by natural order. By default alphabetical order is applied to the store.
*/
/**
* @cfg {Object} enumerationConfig The configuration of enumerator :
* @cfg {Boolean/String} [enumerationConfig.excludePrivate=false] True to exclude private content types. By default excludePrivate is false.
* @cfg {Boolean/String} [enumerationConfig.excludeReferenceTable=true] True to exclude reference table content types. By default excludeReferenceTable is true.
* @cfg {Boolean/String} [enumerationConfig.excludeAbstract=false] True to exclude abstract content types. By default excludeAbstract is false.
* @cfg {Boolean/String} [enumerationConfig.excludeMixin=false] True to exclude mixin content types. By default excludeMixin is false.
* @cfg {Boolean/String} [enumerationConfig.includeMixinOnly=false] True to only include mixin content types. By default includeMixinOnly content type is false.
* @cfg {String[]|String} [enumerationConfig.strictContentTypes] The strict content types id separated by comma or in an array
* @cfg {String[]|String} [enumerationConfig.contentTypes] The parent content types id separated by comma separated by comma or in an array
*/
/**
* @private
* @property {Boolean} _excludeReferenceTable If true, reference table will be excluded
*/
/**
* @private
* @property {Boolean} _excludePrivate If true, private content types will be excluded
*/
/**
* @private
* @property {Boolean} _excludeAbstract If true, abstract content types will be excluded
*/
/**
* @private
* @property {Boolean} _excludeMixin If true, mixin content types will be excluded
*/
/**
* @private
* @property {Boolean} _includeMixinOnly If true, only mixin content types will be available
*/
/**
* @private
* @property {String[]} _strictContentTypes If not null nor empty, the widget will be restricted only to theses content types
*/
/**
* @private
* @property {String[]} _contentTypes If not null nor empty, the widget will be restricted only to theses content types and their subtypes
*/
/**
* @private
* @property {Ext.data.Store} _store The store of drop down list.
*/
queryMode: 'local',
initComponent: function()
{
var enumerationConfig = Ext.applyIf(this.enumerationConfig || {}, {
excludeReferenceTable: false,
excludeMixin: false,
excludeAbstract: false,
excludePrivate: false,
includeMixinOnly: false,
includeSupertype: false
});
this.multiple = this.multiple === true || this.multiple == 'true';
this._excludeReferenceTable = enumerationConfig.excludeReferenceTable !== false && enumerationConfig.excludeReferenceTable != 'false';
this._excludeMixin = enumerationConfig.excludeMixin === true || enumerationConfig.excludeMixin == 'true';
this._excludeAbstract = enumerationConfig.excludeAbstract === true || enumerationConfig.excludeAbstract == 'true';
this._excludePrivate = enumerationConfig.excludePrivate === true || enumerationConfig.excludePrivate == 'true';
this._includeMixinOnly = enumerationConfig.includeMixinOnly === true || enumerationConfig.includeMixinOnly == 'true';
this._strictContentTypes = enumerationConfig.strictContentTypes === undefined ? null : Ext.isArray(enumerationConfig.strictContentTypes) ? enumerationConfig.strictContentTypes : enumerationConfig.strictContentTypes.split(',');
this._contentTypes = enumerationConfig.contentTypes === undefined ? null : Ext.isArray(enumerationConfig.contentTypes) ? enumerationConfig.contentTypes : enumerationConfig.contentTypes.split(',');
this.callParent(arguments);
},
getItems: function()
{
var items = this.callParent(arguments);
if (!this.readOnly)
{
var buttonConfig = this.buttonConfig || {};
Ext.applyIf(buttonConfig, {
text: this.buttonText,
icon: this.buttonIcon,
iconCls: this.buttonIcon ? null : this.buttonIconCls,
tooltip: this.buttonTooltip,
handler: this._chooseContentTypes,
scope: this
});
items.push(Ext.create('Ext.button.Button', buttonConfig));
}
return items;
},
/**
* @private
* Open a dialog box to select content type(s).
*/
_chooseContentTypes: function()
{
var config = {
title: this.contentTypesDialogTitle,
iconCls: this.contentTypesDialogIconCls,
helpMessage: this.chooseContentTypesDialogHint,
excludeReferenceTable: this._excludeReferenceTable,
excludeMixin: this._excludeMixin,
excludeAbstract: this._excludeAbstract,
excludePrivate: this._excludePrivate,
includeMixinOnly: this._includeMixinOnly,
strictContentTypes: this._strictContentTypes,
contentTypes: this._contentTypes,
multiple: this.multiple,
values: Ext.clone(this.getValue()),
callback: Ext.bind(this._chooseContentTypesCb, this)
}
Ametys.cms.form.widget.ChooseContentTypes.open(config);
},
/**
* @private
* Callback function called after selecting content types in a tree.
* Update the field value.
* @param {String[]} contentTypeIds The ids of selected content types
*/
_chooseContentTypesCb: function(contentTypeIds)
{
this.setValue(contentTypeIds);
},
getStore: function()
{
if (!this._store)
{
if (this.getInitialConfig().enumeration)
{
var storeCfg = {
fields: [ this.valueField, {name: this.displayField, type: 'string'}],
data: this.getInitialConfig().enumeration
};
this.queryMode = 'local';
this.naturalOrder = Ext.isBoolean(this.naturalOrder) ? this.naturalOrder : this.naturalOrder == 'true';
if (!this.naturalOrder)
{
storeCfg.sorters = [{property: this.displayField, direction:'ASC'}]; // default order
}
this._store = Ext.create('Ext.data.ArrayStore', storeCfg);
}
else
{
this._store = Ext.create('Ext.data.Store', this._getRemoteStoreCfg());
}
}
return this._store;
},
/**
* Get the remote store.
* @return {Ext.data.Store} the remote store.
*/
_getRemoteStoreCfg: function()
{
var cfg = {
autoLoad: true,
proxy: {
type: 'ametys',
role: 'org.ametys.cms.contenttype.ContentTypesTreeComponent',
methodName: 'getContentTypes',
reader: {
type: 'json',
rootProperty: 'children'
}
},
listeners: {
'beforeload': this._onBeforeLoad,
scope: this
},
fields: [
{name: 'id', mapping: 'contentTypeId'},
{name: 'label', mapping: 'text'}
]
}
var naturalOrder = Ext.isBoolean(this.naturalOrder) ? this.naturalOrder : this.naturalOrder == 'true';
if (!naturalOrder)
{
cfg.sorters = [{property: 'label', direction:'ASC'}]; // default order
}
return cfg;
},
/**
* 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
* @private
*/
_onBeforeLoad: function(store, operation)
{
operation.setParams( Ext.apply(operation.getParams() || {}, {
includeMixinOnly: this._includeMixinOnly,
hierarchicalView: false,
excludeReferenceTable: this._excludeReferenceTable,
excludeMixin: this._excludeMixin,
excludeAbstract: this._excludeAbstract,
excludePrivate: this._excludePrivate,
excludeMode: 'hide',
strictContentTypes: this._strictContentTypes,
contentTypes: this._contentTypes
}));
}
});