/*
* Copyright 2021 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 all carts in READ access for current user
* @private
*/
Ext.define('Ametys.plugins.cart.tool.CartsPanel', {
extend: 'Ext.grid.Panel',
/**
* @property {Ext.data.Store} _store The cart store
* @private
*/
/**
* @cfg {String} profile The profile ('read_access' or 'right_access') filter. By default, if null, the server will treat the request as 'read_access'
*/
/**
* @cfg {Boolean} enableDrop Enable drag and drop process to drop elements into cart
*/
statics: {
/**
* Function to render query's title in result grid
* @param {Object} title The data title
* @param {Object} metaData A collection of metadata about the current cell
* @param {Ext.data.Model} record The record
* @private
*/
renderWithTooltip: function(value, metaData, record)
{
metaData.tdAttr = Ametys.plugins.cart.tool.CartsPanel.descriptionTooltip(record);
return value;
},
/**
* Function to generate description tooltip
* @param {Ext.data.Model} record The record
* @private
*/
descriptionTooltip: function(record)
{
return 'data-qtip="<strong>' + record.get("title").replaceAll('"', '"') + '</strong>'
+ (record.get("description") && record.get("description") !== '' ? '<br/>' + record.get("description").replaceAll('"', '"') : '')
+ (record.get("documentation") && record.get("documentation") !== '' ? '<br/>' + Ametys.plugins.cart.tool.CartsPanel.renderDocumentation(record.get("documentation"), null, record).replaceAll('"', '"') : '')
+ '"';
},
/**
* Function to render cart's documentation in result grid
* @param {Object} title The data title
* @param {Object} metaData A collection of metadata about the current cell
* @param {Ext.data.Model} record The record
* @private
*/
renderDocumentation: function(documentation, metaData, record)
{
return '<a href="' + documentation + '" target="_blank">' + documentation + '</a>';
}
},
constructor: function(config)
{
if (config.enableDrop)
{
config.viewConfig = config.viewConfig || {};
Ext.apply(config.viewConfig, {
plugins: {
ptype: 'ametysgridviewdragdrop',
dragTextField: 'title',
setAmetysDropZoneInfos: Ext.bind(this.getDropInfo, this)
}
});
}
config.store = this.createStore(config);
config.scrollable = true;
config.cls = 'carts-uitool';
config.columns = [
{header: "{{i18n PLUGINS_CART_UITOOL_CARTS_COLUMN_TITLE}}", width: 180, sortable: true, dataIndex: 'title', renderer: Ametys.plugins.cart.tool.CartsPanel.renderWithTooltip},
{header: "{{i18n PLUGINS_CART_UITOOL_CARTS_COLUMN_DESCRIPTION}}", hidden: false, width: 180, sortable: true, dataIndex: 'description', renderer: Ametys.plugins.cart.tool.CartsPanel.renderWithTooltip},
{header: "{{i18n PLUGINS_CART_UITOOL_CARTS_COLUMN_DOCUMENTATION}}", hidden: true, width: 180, sortable: true, dataIndex: 'documentation', renderer: Ametys.plugins.cart.tool.CartsPanel.renderDocumentation},
{header: "{{i18n PLUGINS_CART_UITOOL_CARTS_COLUMN_AUTHOR}}", hidden: false, width: 110, sortable: true, dataIndex: 'authorFullName'},
{header: "{{i18n PLUGINS_CART_UITOOL_CARTS_COLUMN_CONTRIBUTOR}}", hidden: false, width: 110, sortable: true, dataIndex: 'contributorFullName'},
{header: "{{i18n PLUGINS_CART_UITOOL_CARTS_COLUMN_CREATIONDATE}}", hidden: true, width: 110, sortable: true, dataIndex: 'creationDate', renderer: Ext.util.Format.dateRenderer(Ext.Date.patterns.FriendlyDateTime)},
{header: "{{i18n PLUGINS_CART_UITOOL_CARTS_COLUMN_LASTMODIFICATIONDATE}}", hidden: true, width: 110, sortable: true, dataIndex: 'lastModificationDate', renderer: Ext.util.Format.dateRenderer(Ext.Date.patterns.FriendlyDateTime)}
];
config.selModel = {
mode: 'MULTI'
};
config.features = [{
ftype:'grouping',
groupHeaderTpl: Ext.create('Ext.XTemplate',
'{name:this.formatName}',
{
formatName: function(name)
{
switch (parseInt(name))
{
case 0:
return "{{i18n PLUGINS_CART_UITOOL_CARTS_GROUP_PERSONAL_CARTS}}";
case 1:
return "{{i18n PLUGINS_CART_UITOOL_CARTS_GROUP_SHARED_CARTS}}";
default:
return name;
}
}
}
)
}];
config.cls = this;
// Filter
config.dockedItems = [{
dock: 'top',
xtype: 'toolbar',
layout: {
type: 'hbox',
align: 'stretch'
},
border: false,
defaults : {
cls: 'ametys',
labelWidth: 55,
labelSeparator: ''
},
items: [
{
// Filter input
xtype: 'textfield',
itemId: 'search-filter-input',
cls: 'ametys',
flex: 1,
maxWidth: 300,
emptyText: "{{i18n PLUGINS_CART_UITOOL_CARTS_FILTER_EMPTY_TEXT}}",
enableKeyEvents: true,
msgTarget: 'qtip',
listeners: {change: Ext.Function.createBuffered(this._filterByRegexp, 300, this)}
}, {
// Clear filter
tooltip: "{{i18n PLUGINS_CART_UITOOL_CARTS_FILTER_CLEAR}}",
handler: Ext.bind (this._clearFilter, this),
iconCls: 'a-btn-glyph ametysicon-eraser11 size-16',
cls: 'a-btn-light'
}]
}]
this.callParent(arguments);
Ametys.message.MessageBus.on(Ametys.message.Message.CREATED, this._onCartCreated, this);
Ametys.message.MessageBus.on(Ametys.message.Message.MODIFIED, this._onCartUpdated, this);
Ametys.message.MessageBus.on(Ametys.message.Message.DELETED, this._onCartDeleted, this);
},
/**
* Creates the cart store
* @param {Object} config The configuration
* @param {String} [config.profile=null] See {@link #cfg-profile}
*/
createStore: function(config)
{
var profile = config.profile;
if (!this._store)
{
this._store = Ext.create('Ext.data.Store', {
model: 'Ametys.plugins.cart.tool.CartsTool.CartEntry',
sorters: [{property: 'title', direction:'ASC'}],
groupField: 'group',
proxy: {
type: 'ametys',
plugin: 'cart',
url: 'carts/list.json',
reader: {
type: 'json',
rootProperty: 'carts'
},
extraParams: {
profile: profile
}
},
autoLoad: true
});
}
return this._store;
},
onDestroy: function()
{
Ametys.message.MessageBus.unAll(this);
this.callParent(arguments);
},
/**
* @private
* This event is thrown before the beforeDrop event and create the target of the drop operation relation.
* @param {Ext.data.Model[]} targetRecords The target records of the drop operation.
* @param {Object} item The default drag data that will be transmitted. You have to add a 'target' item in it:
* @param {Object} item.target The target (in the relation way) of the drop operation. A Ametys.relation.RelationPoint config.
*/
getDropInfo: function(targetRecords, item)
{
if (targetRecords.length > 0)
{
var targets = [];
Ext.each (targetRecords, function (record) {
if (record.get('canWrite'))
{
targets.push({
id: Ametys.message.MessageTarget.CART,
parameters: {
id: record.get('id')
}
});
}
});
item.target = {
relationTypes: [Ametys.relation.Relation.REFERENCE],
targets: targets
};
}
},
/**
* @private
* Filters carts by input field value.
* @param {Ext.form.Field} field The field
*/
_filterByRegexp: function (field)
{
var value = Ext.String.trim(field.getValue());
if (this._filterValue == value)
{
// Do nothing
return;
}
this._filterValue = value;
if (value)
{
var regexFilter = new RegExp(value, 'i');
var currentSelection = this.getSelection();
this._store.clearFilter();
this._store.filterBy(function(record){
return regexFilter.test(record.data.title) || regexFilter.test(record.data.description) || regexFilter.test(record.data.documentation);
});
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._filterValue = null;
this.down("#search-filter-input").reset();
},
/**
* Listener when carts have been created
* Will set the tool in "out of date" mode
* @param {Ametys.message.Message} message The creation message.
* @private
*/
_onCartCreated: function(message)
{
var targets = message.getTargets(Ametys.message.MessageTarget.CART);
if (targets.length > 0)
{
this.getStore().reload()
}
},
/**
* Listener when carts have been edited
* Will set the tool in "out of date" mode
* @param {Ametys.message.Message} message The edition message.
* @private
*/
_onCartUpdated: function(message)
{
var targets = message.getTargets(Ametys.message.MessageTarget.CART);
if (targets.length > 0)
{
this.getStore().reload()
}
},
/**
* Listener when carts have been deleted
* Will remove the records if present
* @param {Ametys.message.Message} message The deletion message.
* @private
*/
_onCartDeleted: function (message)
{
var targets = message.getTargets(Ametys.message.MessageTarget.CART);
if (targets.length > 0)
{
var ids = Ext.Array.map(targets, function(target) {
return this.getStore().getById(target.getParameters().id);
}, this);
this.getStore().remove(ids);
}
}
});