/*
* Copyright 2019 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 is a common class for tools displaying comments and reports on contents
* @private
*/
Ext.define('Ametys.plugins.cms.content.tool.CommonCommentsAndReportsTool', {
/**
* Initialize the tool. This function has to be called in the constructor.
* @protected
*/
_initialize: function()
{
Ametys.message.MessageBus.on(Ametys.message.Message.MODIFIED, this._onReportedObjectModified, this);
Ametys.message.MessageBus.on(Ametys.message.Message.DELETED, this._onReportedObjectDeleted, this);
},
/**
* Get the tree panel
* @param {Object} specificConfig The panel specific configuration. store is mandatory
* @return {Ext.tree.Panel} the created tree panel
* @protected
*/
_getTreePanel: function(specificConfig)
{
var config = {
rootVisible: false,
scrollable: true,
border: false,
multiSelect: true,
stateful: true,
stateId: this.self.getName() + "$tree",
flex: 1,
columns: [
{xtype: 'treecolumn', stateId: 'grid-text', header: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_AND_REPORTS_VIEW_COLUMN_CONTENT}}", width: 320, sortable: true, dataIndex: 'text'},
{stateId: 'grid-contentTitle', header: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_AND_REPORTS_VIEW_COLUMN_TITLE}}", sortable: true, dataIndex: 'contentTitle', hidden: true},
{stateId: 'grid-creationDate', header: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_AND_REPORTS_VIEW_COLUMN_DATE}}", width: 140, sortable: true, dataIndex: 'creationDate', renderer: Ext.util.Format.dateRenderer(Ext.Date.patterns.FriendlyDateTime)},
{stateId: 'grid-validated', header: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_AND_REPORTS_VIEW_COLUMN_STATE}}", width: 50, sortable: true, dataIndex: 'validated', renderer: this._renderValidated},
{stateId: 'grid-nb-reporters', header: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_AND_REPORTS_VIEW_COLUMN_REPORTED}}", width: 110, sortable: true, dataIndex: 'reportsCount'},
{stateId: 'grid-authorName', header: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_AND_REPORTS_VIEW_COLUMN_AUTHOR}}", width: 170, sortable: true, dataIndex: 'authorName'},
{stateId: 'grid-authorEmail', header: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_AND_REPORTS_VIEW_COLUMN_AUTHOR_EMAIL}}", width: 170, sortable: true, dataIndex: 'authorEmail', hidden: true}
],
listeners: {
selectionchange: this.onSelectComment,
load: this._onLoad,
scope: this
}
};
Ext.Object.merge(config, specificConfig);
return Ext.create("Ext.tree.Panel", config);
},
/**
* Get the tree store
* @param {Object} specificConfig the store specific configuration. proxy.methodName and proxy.methodArguments are mandatory.
* @return {Ext.data.TreeStore} the created tree store
* @protected
*/
_getTreeStore: function(specificConfig)
{
var config = {
model: 'Ametys.plugins.cms.content.tool.CommonCommentsAndReportsTool.CommentEntry',
proxy: {
type: 'ametys',
plugin: 'cms',
role: 'org.ametys.cms.repository.comment.ui.CommentsAndReportsTreeComponent',
reader: {
type: 'json',
rootProperty: 'comments'
}
},
multiSelect: true,
root: {
allowDrag: false,
expanded: true,
valid: true,
id: 'root',
name: 'ametys:comments'
},
sortOnLoad: true,
sorters: [{property: 'contentName', direction:'DESC'}, {property: 'creationDate', direction:'DESC'}],
listeners: {
beforeload: this._onBeforeLoad,
scope: this
}
};
Ext.Object.merge(config, specificConfig);
return Ext.create('Ext.data.TreeStore', config);
},
/**
* Send the current comments selection on message bus.
* @protected
*/
onSelectComment: function ()
{
var targets = [];
var records = this._treePanel.getSelectionModel().getSelection();
Ext.Array.each (records, function(record) {
if (!record.isRoot())
{
var contentId = record.get('contentId');
var commentId = record.get('commentId');
var reportsCount = record.get('reportsCount');
if (Ext.isEmpty(commentId))
{
targets.push({
id: Ametys.message.MessageTarget.CONTENT,
parameters: {
ids: [contentId]
}
});
}
else
{
targets.push({
id: Ametys.message.MessageTarget.COMMENT,
parameters: {
id: commentId,
content: contentId,
reportsCount: reportsCount
}
});
}
}
});
if (!Ext.isEmpty(targets))
{
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.SELECTION_CHANGED,
targets: targets
});
}
},
/**
* Renderer method to transform records' validated state
* @param {Object} value The data value
* @param {Object} metaData A collection of metadata about the current cell
* @param {Ext.data.Model} record The record for the current row
* @private
*/
_renderValidated: function (value, metaData, record)
{
if (record.get("commentId") != "")
{
if (!value)
{
return '<span class="a-grid-glyph ametysicon-forbidden1 not-validated"></span>';
}
else if (record.get("reportsCount") > 0)
{
return '<span class="a-grid-glyph ametysicon-sign-caution reported"></span>';
}
else
{
return '<span class="a-grid-glyph ametysicon-check34 validated"></span>';
}
}
else if (record.get("reportsCount") > 0)
{
return '<span class="a-grid-glyph ametysicon-sign-caution reported"></span>';
}
},
/**
* Listener when a content or a comment has been modified.
* @param {Ametys.message.Message} message The modified message.
* @private
*/
_onReportedObjectModified: function (message)
{
var targets = message.getTargets(function(target) {
return target.getId() == Ametys.message.MessageTarget.CONTENT
|| target.getId() == Ametys.message.MessageTarget.COMMENT;
});
if (targets.length > 0)
{
this.showOutOfDate();
}
},
/**
* Listener when a content or a comment has been deleted.
* @param {Ametys.message.Message} message The deletion message.
* @private
*/
_onReportedObjectDeleted: function (message)
{
var targets = message.getTargets(function(target) {
return target.getId() == Ametys.message.MessageTarget.CONTENT
|| target.getId() == Ametys.message.MessageTarget.COMMENT;
});
if (targets.length > 0)
{
var me = this;
Ext.Array.forEach(targets, function(target) {
var nodeId = me._getNodeIdFromTarget(target);
var node = me._store.getNodeById(nodeId);
if (node != null)
{
var parentNode = node.parentNode;
me._treePanel.getSelectionModel().select([parentNode]);
node.remove();
}
});
}
},
/**
* Retrieves the node identifier corresponding to the given target
* @param {Ametys.message.MessageTarget} target the target
* @return {String} the node identifier
*/
_getNodeIdFromTarget: function(target)
{
var targetParameters = target.getParameters();
var contentId = targetParameters.id;
var commentId = "";
if (target.getId() == Ametys.message.MessageTarget.COMMENT)
{
contentId = targetParameters.content;
commentId = targetParameters.id;
}
return contentId + ";" + commentId;
}
});
/**
* This class is the model for entries in the grid of the comments tool
* @private
*/
Ext.define("Ametys.plugins.cms.content.tool.CommonCommentsAndReportsTool.CommentEntry", {
extend: 'Ext.data.TreeModel',
fields: [
{name: 'commentId', type: 'string' },
{name: 'contentId', type: 'string' },
{name: 'reportsCount', type: 'int' },
{name: 'validated', type: 'boolean'},
{name: 'creationDate', type: 'date', dateFormat: 'c'},
{name: 'authorName', type: 'string'},
{name: 'authorEmail', type: 'string'},
{name: 'contentTitle', type: 'string'},
{name: 'authorUrl', type: 'string'},
{name: 'authorIsEmailHidden', type: 'boolean'},
{
name: 'iconCls',
depends: ['commentId'],
calculate: function (data)
{
if (!Ext.isEmpty(data.commentId))
{
return 'ametysicon-interface-1';
}
else
{
return 'ametysicon-text70';
}
}
},
{name: 'text'},
{
name: 'id',
calculate: function (data) {
return data.contentId + ';' + data.commentId
}
}
]
});