/*
* Copyright 2018 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 Tree for surveys, their pages and their questions.
* @private
*/
Ext.define('Ametys.plugins.linkdirectory.link.LinkDirectoryGrid', {
extend: 'Ext.grid.Panel',
/**
* @private
* @property {Ext.data.Store} _store The data store for this grid.
*/
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;
},
/**
* 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(', ')
},
/**
* Renderer for the limitedAccess
* @param {String|Boolean} value the restricted value
* @param {Object} metadata A collection of metadata about the current cell
* @param {Ext.data.Model} record The record for the current row
* @return {String} the representation of restricted value as an icon.
*/
renderLimitedAccess: function(value, metadata, record)
{
if (value == 'true' || (Ext.isBoolean(value) && value))
{
return '<span class="a-grid-glyph ametysicon-check34"></span>';
}
else
{
return "";
}
},
/**
* Renderer for the url
* @param {String} url the url value
* @param {Object} metadata A collection of metadata about the current cell
* @param {Ext.data.Model} record The record for the current row
* @return {String} the html string used for the rendering of the url
*/
renderUrl: function(url, metadata, record)
{
if (record.get('urlType') == 'PAGE')
{
if (record.get('unknownPage'))
{
return '<span class="a-grid-glyph ametysicon-link23 decorator-ametysicon-caution9 link-warning"></span>' + '{{i18n PLUGINS_LINKDIRECTORY_UITOOL_UNKNOWN_PAGE}}';
}
else
{
return '<span class="a-grid-glyph ametysicon-link23"></span><a class="link-page" href="javascript:(function(){Ametys.tool.ToolsManager.openTool(\'uitool-page\', {id:\'' + url + '\'});})()">' + Ext.String.escapeHtml(record.get('pageTitle')) + '</a>';
}
}
else
{
return '<span class="a-grid-glyph ametysicon-link23"></span>' + (url || record.get('internalUrl'));
}
},
/**
* Renderer for the status
* @param {String|Boolean} value the status value
* @param {Object} metadata A collection of metadata about the current cell
* @param {Ext.data.Model} record The record for the current row
* @return {String} the status label
*/
renderStatus: function(value, metadata, record)
{
if (value == 'BROKEN')
{
return "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_STATUS_BROKEN_LABEL}}";
}
else if (value == 'NEW')
{
return "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_STATUS_NEW_LABEL}}";
}
else if (value == 'NORMAL')
{
return "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_STATUS_NORMAL_LABEL}}";
}
}
},
constructor: function(config)
{
this._store = Ext.create('Ext.data.Store', {
model: 'Ametys.plugins.linkdirectory.link.LinkDirectoryTool.Link',
proxy: {
type: 'ametys',
plugin: 'link-directory',
url: 'links.json',
reader: {
type: 'json',
rootProperty: 'links'
},
extraParams: {
siteName: Ametys.getAppParameter('siteName')
}
},
listeners: {
'beforeload' : Ext.bind(this._onBeforeLoad, this)
}
});
var langCombo = Ametys.cms.language.LanguageDAO.createComboBox({
itemId: 'languages-combo',
fieldLabel: "{{i18n PLUGINS_LINKDIRECTORY_UITOOL_LANGUAGE}}",
listeners: {
'change': Ext.bind(this._onChangeLang, this)
}
});
config = Ext.applyIf(config, {
forceFit: true,
cls: 'linkdirectory-tool',
stateful: true,
stateId: this.self.getName() + "$linkgrid",
features: [{ftype:'grouping'}],
store : this._store,
selModel : {
mode: 'MULTI'
},
// Languages combo box
dockedItems: [{
dock: 'top',
xtype: 'toolbar',
layout: {
type: 'hbox',
align: 'stretch'
},
border: false,
defaults : {
cls: 'ametys',
labelWidth: 55,
labelSeparator: ''
},
items: [langCombo,
{
// Filter input
xtype: 'textfield',
itemId: 'search-filter-input',
cls: 'ametys',
flex: 1,
maxWidth: 300,
emptyText: "{{i18n PLUGINS_LINKDIRECTORY_UITOOL_FILTER_EMPTY_TEXT}}",
enableKeyEvents: true,
minLength: 3,
minLengthText: "{{i18n PLUGINS_LINKDIRECTORY_UITOOL_FILTER_MIN_LENGTH_INVALID}}",
msgTarget: 'qtip',
listeners: {change: Ext.Function.createBuffered(this._filterByTitleOrUrl, 300, this)}
}, {
// Clear filter
tooltip: "{{i18n PLUGINS_LINKDIRECTORY_UITOOL_FILTER_CLEAR}}",
handler: Ext.bind (this._clearFilter, this),
iconCls: 'a-btn-glyph ametysicon-eraser11 size-16',
cls: 'a-btn-light'
}]
}]
});
this.callParent(arguments);
},
/**
* @private
* Listener on selection of the language in top combo box
*/
_onChangeLang: function ()
{
this._store.load();
},
/**
* @private
* Function called when the 'beforeload' event is fired
* @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
*/
_onBeforeLoad: function(store, operation)
{
// Let the load occur only if we know the language.
var lang = this.down("combobox[itemId='languages-combo']").getValue();
operation.setParams( Ext.apply(operation.getParams() || {}, {
lang: lang
}));
},
/**
* @private
* Filters links by input field value.
* @param {Ext.form.Field} field The field
*/
_filterByTitleOrUrl: function (field)
{
var value = Ext.String.trim(field.getValue());
if (this._filterValue == value)
{
// Do nothing
return;
}
this._filterValue = value;
var regexFilter = new RegExp(value, 'i');
if (value.length > 2)
{
var currentSelection = this.getSelection();
this._store.clearFilter();
this._store.filterBy(function(record){
return regexFilter.test(record.data.title) || regexFilter.test(record.data.url);
});
if (currentSelection.length > 0)
{
var me = this;
Ext.Array.each(currentSelection, function (sel) {
if (me._store.findExact(me._store.getModel().idProperty, sel.getId()) == -1)
{
// The current selection is not visible, clear the selection
me.getSelectionModel().deselect([sel]);
}
})
}
}
else
{
// We do not call _clearFilter that will also empty the filter and prevent from typing
this._filterValue = null;
this._store.clearFilter();
}
},
/**
* @private
* Clear the current filter
*/
_clearFilter: function()
{
this.down("#search-filter-input").reset();
this._filterValue = null;
this._store.clearFilter();
}
});