/*
* Copyright 2015 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 tool displays the glossary.
* @private
*/
Ext.define('Ametys.plugins.glossary.GlossaryTool', {
extend: 'Ametys.tool.Tool',
/**
* @private
* @property {Ext.grid.Panel} _grid The grid for word definitions
*/
/**
* @private
* @property {Ext.data.Store} _store The store for word definitions
*/
statics: {
convertThemes: function(val, record, dataIndex)
{
var properties = {};
record.data[dataIndex + '_map'] = properties;
if (Ext.isArray(val) && val.length > 0 && Ext.isObject(val[0]))
{
for (var i = 0; i < val.length; i++)
{
properties[val[i].id] = val[i];
val[i] = val[i].id;
}
}
else if (Ext.isObject(val))
{
properties[val.id] = val;
val = val.id;
}
return val;
}
},
constructor: function(config)
{
this.callParent(arguments);
Ametys.message.MessageBus.on(Ametys.message.Message.CREATED, this._onMessageCreatedOrModified, this);
Ametys.message.MessageBus.on(Ametys.message.Message.MODIFIED, this._onMessageCreatedOrModified, this);
Ametys.message.MessageBus.on(Ametys.message.Message.DELETED, this._onMessageDeleted, this);
},
createPanel: function()
{
this._store = Ext.create('Ext.data.Store', {
model: 'Ametys.plugins.glossary.GlossaryTool.DefinitionEntry',
proxy: {
type: 'ametys',
role: 'org.ametys.plugins.glossary.GlossaryDAO',
methodName: 'getDefinitions',
methodArguments: ['siteName', 'lang'],
reader: {
type: 'json',
rootProperty: 'definitions'
},
extraParams: {
siteName: Ametys.getAppParameter('siteName')
}
},
groupField: 'firstLetter',
sorters: [{property: 'word', direction: 'ASC'}],
listeners: {
'beforeload': Ext.bind(this._onBeforeLoad, this)
}
});
var langCombo = Ametys.cms.language.LanguageDAO.createComboBox({
itemId: 'languages-combo',
fieldLabel: "{{i18n PLUGINS_GLOSSARY_UITOOL_LANGUAGE}}",
listeners: {
'change': Ext.bind(this._onChangeLang, this)
}
});
this._grid = Ext.create('Ext.grid.Panel', {
stateful: true,
stateId: this.self.getName() + "$grid",
// Languages combo box
dockedItems: [{
dock: 'top',
xtype: 'toolbar',
layout: {
type: 'hbox',
align: 'stretch'
},
border: false,
defaults : {
cls: 'ametys',
labelWidth: 55,
labelSeparator: ''
},
items: langCombo
}],
cls: 'glossary-tool',
store: this._store,
// Grouping by letter
features: [
{
ftype: 'grouping',
enableGroupingMenu: true,
hideGroupedHeader: true,
groupHeaderTpl: '{name}'
}
],
selModel: {
mode: 'MULTI'
},
columns: [
{stateId: 'grid-column-word', header: "{{i18n PLUGINS_GLOSSARY_UITOOL_WORD}}", width: 120, sortable: true, dataIndex: 'word'},
{stateId: 'grid-column-variants', header: "{{i18n PLUGINS_GLOSSARY_UITOOL_VARIANTS}}", width: 100, sortable: true, dataIndex: 'variants'},
{stateId: 'grid-column-content', header: "{{i18n PLUGINS_GLOSSARY_UITOOL_DEFINITION}}", flex: 1, sortable: true, dataIndex: 'content'},
{stateId: 'grid-column-themes', header: "{{i18n PLUGINS_GLOSSARY_UITOOL_THEMES}}", sortable: false, width: 100, groupable: true, dataIndex: 'themes', renderer: Ext.bind(this._renderThemes, null, ['themes'], true)},
{stateId: 'grid-column-display', header: "{{i18n PLUGINS_GLOSSARY_UITOOL_DISPLAY_ON_TEXT}}", width: 100, sortable: true, dataIndex: 'displayOnText', renderer: this._renderBoolean}
],
listeners: {
'selectionchange': Ext.bind(this.sendCurrentSelection, this)
}
});
return this._grid;
},
getMBSelectionInteraction: function()
{
return Ametys.tool.Tool.MB_TYPE_ACTIVE;
},
sendCurrentSelection: function()
{
var selection = this._grid.getSelectionModel().getSelection();
var targets = [];
for (var i = 0; i < selection.length; i++)
{
targets.push({
id: Ametys.message.MessageTarget.WORD_DEFINITION,
parameters: {
id: selection[i].id
}
});
}
Ext.create('Ametys.message.Message', {
type: Ametys.message.Message.SELECTION_CHANGED,
targets: targets
});
},
/**
* Gets the selected language.
* @return {String} The selected language.
*/
getCurrentLanguage: function()
{
return this._grid.down("combobox[itemId='languages-combo']").getValue();
},
/**
* @inheritdoc
* @param {Object} params the parameters
* @param {String[]} [params.selectedDefinitionIds] The id of word definition to select at opening
*/
setParams: function (params)
{
this.callParent(arguments);
this._initialSelectedDefIds = params.selectedDefinitionIds || [];
this.refresh();
},
refresh: function()
{
this.showRefreshing();
this._store.load({callback: this._refreshCb, scope: this});
},
/**
* Function invoked after loading the store
* @private
*/
_refreshCb: function ()
{
this.showRefreshed();
if (this._initialSelectedDefIds.length > 0)
{
var records = [];
var sm = this._grid.getSelectionModel();
var store = this._grid.getStore();
Ext.Array.each (this._initialSelectedDefIds, function (id) {
var index = store.find("id", id);
if (index != -1)
{
records.push(store.getAt(index));
}
});
sm.select(records);
this._initialSelectedDefIds = []; // reset
}
},
/**
* Listener on creation or edition message.
* @param {Ametys.message.Message} message The edition message.
* @private
*/
_onMessageCreatedOrModified: function(message)
{
var targets = message.getTargets(Ametys.message.MessageTarget.WORD_DEFINITION);
if (targets.length > 0)
{
this.showOutOfDate();
}
},
/**
* Listener on deletion message.
* @param {Ametys.message.Message} message The deletion message.
* @private
*/
_onMessageDeleted: function(message)
{
var targets = message.getTargets(Ametys.message.MessageTarget.WORD_DEFINITION);
for (var i = 0; i < targets.length; i++)
{
var record = this._store.getById(targets[i].getParameters().id);
this._store.remove(record);
}
},
/**
* Renders a boolean value.
* @param {Object} value The data value for the current cell.
* @private
*/
_renderBoolean: function(value)
{
if (value == true || value == 'true')
{
return "{{i18n PLUGINS_GLOSSARY_DEFINITION_YES}}";
}
else
{
return "{{i18n PLUGINS_GLOSSARY_DEFINITION_NO}}";
}
},
/**
* Renderer for the themes
* @param {Object[]} themes themes value.
* @param {Object} metadata A collection of metadata about the current cell
* @param {Ext.data.Model} record The record for the current row
* @param {Number} rowIndex The index of the current row
* @param {Number} colIndex The index of the current column
* @param {Ext.data.Store} store The data store
* @param {Ext.view.View} view The current view
* @param {String} dataIndex The data index of the column
* @return {String} the labels of the themes as a coma-separated string
*/
_renderThemes: function(value, metadata, record, rowIndex, colIndex, store, view, dataIndex)
{
value = Ext.Array.from(value);
var labels = [];
dataIndex = dataIndex || rowIndex; // When used by grouping feature, data index is the 4th arguments
var properties = record.get(dataIndex + "_map");
Ext.Array.forEach(value, function(v) {
var property = properties[v]
labels.push(Ext.String.escapeHtml(property ? property.label : value));
});
return labels.join(', ')
},
/**
* Listens when a language is changed.
* @param {Ext.form.field.Field} field The field
* @param {Object} newValue The new value.
* @param {Object} oldValue The original value.
* @private
*/
_onChangeLang: function(field, newValue, oldValue)
{
// Reload grid
this.refresh();
},
/**
* Listens before loading word definitions.
* The load action will be canceled if it returns false
* @param {Ext.data.Store} store The store.
* @param {Ext.data.operation.Operation} operation The Ext.data.operation.Operation object that will be passed to the Proxy to load the Store.
* @param {Object} eOpts The options object passed to Ext.util.Observable.addListener.
* @return {Boolean} False if the load action will be canceled.
* @private
*/
_onBeforeLoad: function(store, operation, eOpts)
{
// Let the load occur only if we know the language.
var lang = this._grid.down("combobox[itemId='languages-combo']").getValue();
operation.setParams( Ext.apply(operation.getParams() || {}, {
lang: lang
}));
}
});
Ext.define("Ametys.message.GlossaryMessageTarget",{
override: "Ametys.message.MessageTarget",
statics:
{
/**
* @member Ametys.message.MessageTarget
* @readonly
* @property {String} WORD_DEFINITION The target of the message is an word definition of glossary
*/
WORD_DEFINITION: "wordDefinition"
}
});