/*
* Copyright 2024 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.
*/
/**
* MCC course tree grid panel
* @private
*/
Ext.define('Ametys.plugins.odf.pilotage.tool.ContentViewTreeGridPanel', {
extend: 'Ametys.plugins.odf.tree.AbstractODFTreeGridPanel',
mixins: {
editContentsView: "Ametys.cms.content.EditContentsView"
},
/**
* @config {String} searchModel The name of the search model to determin columns
*/
/**
* @cfg {String} [messageTarget=Ametys.message.MessageTarget#CONTENT] The message target factory role to use for the event of the bus thrown and listened by the grid
*/
constructor: function(config)
{
config.columns = [{ xtype: 'treecolumn', locked: true }/*this._getDefaultGridConfig()*/];
config.methodArguments = ['contentId', 'path', 'tree', 'searchModel'];
config.messageTarget = config.messageTarget || Ametys.message.MessageTarget.CONTENT;
config.cls = Ext.Array.from(config.cls);
config.cls.push("contentviewtreegrid");
config.cls.push("treegrideditionfirst");
this.callParent(arguments);
config.saveBarPosition = 0;
this.mixins.editContentsView.constructor.call(this, config);
this.getStore().on('beforeload', function(store, operation) {
if (operation.node.get('contentId'))
{
var params = Ext.apply(operation.getParams() || {}, {
'searchModel': this.searchModel
});
operation.setParams(params);
}
}, this);
this.getStore().on('load', this._onLoad, this);
},
getContentRootNodeParameters: function(contentId, otherConfig)
{
let parameters = this.callParent(arguments);
parameters.push(this.searchModel);
return parameters;
},
_getNodeInformationsParameters(node)
{
let info = this.callParent(arguments);
info.push(this.searchModel);
return info;
},
_onLoad: function(store, records, successful, operation, eOpts)
{
// Checking if the new record is not about an existing record with the same contentId
let modifiedContents = {}
for (let modifiedRecord of this.store.getModifiedRecords()) // Maybe we should use this.getModifiedRecords() (from EditContentsView) to also include rootNode
{
modifiedContents[this._getContentId(modifiedRecord)] = modifiedRecord;
}
for (let record of records)
{
this._loadRecord(record, modifiedContents);
}
},
_onRootNodeLoad: function(record)
{
// root node does not trigger the classical load event
this._loadRecord(record, []);
},
_loadRecord: function(record, modifiedContents)
{
if (record.data.data)
{
let modifiedRecord = modifiedContents[this._getContentId(record)];
let changes;
if (modifiedRecord)
{
changes = modifiedRecord.getChanges();
}
let changesKeys = changes ? Object.keys(changes) : null;
if (changesKeys)
{
for (let changeFieldName of changesKeys)
{
if (modifiedRecord.get(changeFieldName + "_repeater") !== undefined)
{
changes[changeFieldName + "_repeater"] = modifiedRecord.get(changeFieldName + "_repeater");
}
if (modifiedRecord.get(changeFieldName + "_content") !== undefined)
{
changes[changeFieldName + "_content"] = modifiedRecord.get(changeFieldName + "_content");
}
}
changesKeys = Object.keys(changes);
}
let dataKeys = Object.keys(record.data.data);
for (let k of dataKeys)
{
if (!changesKeys || !changesKeys.includes(k))
{
// Any initial must be reset before setting the new loaded value
for (let k2 of Object.keys(record.data))
{
if (k2.startsWith(k + "_")
&& k2.endsWith("_initial"))
{
delete record.data[k2];
}
}
record.set(k, record.data.data[k], {silent: true});
}
}
record.set('data', undefined, {silent: true});
record.set('editionAvailable', true, {silent: true});
record.commit(false, Object.keys(record.modified)); // specifying the list of modified items avoid a basic refresh of the title cell that destroy the decorators
if (changesKeys)
{
for (let changeFieldName of changesKeys)
{
record.set(changeFieldName, changes[changeFieldName]);
}
}
}
let me = this;
window.setTimeout(function() {
for (let childRecord of record.childNodes || [])
{
me._loadRecord(childRecord, modifiedContents);
}
}, 1)
},
/**
* Function creating the structure of the columns grid
* @private
*/
_getDefaultGridConfig: function()
{
return [
{
xtype: 'treecolumn',
text: "{{i18n plugin.cms:PLUGINS_CMS_METADATA_TITLE_LABEL}}",
stateId: 'title',
sortable: false,
dataIndex: 'title',
width: 400,
locked: true,
lockable: false
}
];
},
_createEditPlugin: function(config) {
let plugin = this.mixins.editContentsView._createEditPlugin.apply(this, arguments);
plugin.editAfterSelect = false;
return plugin;
},
_getContentId(record) {
return record.get('contentId');
},
_findRecords(contentId) {
let records = [];
// Using byIdMap allow to search even in filtered items
for (let id in this.store.byIdMap)
{
if (this.store.byIdMap[id].get('contentId') == contentId)
{
records.push(this.store.byIdMap[id]);
}
}
return records;
},
_sendMessages: function()
{
let toolRootCmp = this.ownerCt;
while (!toolRootCmp.uiTool)
{
toolRootCmp = toolRootCmp.ownerCt;
}
let toolId = toolRootCmp.uiTool;
let tool = Ametys.tool.ToolsManager.getTool(toolId)
tool._ignoreNextModified++;
this.mixins.editContentsView._sendMessages.apply(this, arguments);
}
});