/**
* Copyright 2023 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 display the list of all existing workflows
*/
Ext.define('Ametys.plugins.workflow.tools.WorkflowsSearchTool', {
extend: "Ametys.tool.Tool",
displayWorkflowOverflow: true,
/**
* @private
* @property {String} _workflowName id of currently selected workflow
*/
constructor: function(config)
{
this.callParent(arguments);
Ametys.message.MessageBus.on(Ametys.message.Message.SELECTION_CHANGED, this._onSelectionChanged, this);
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.plugins.workflow.tools.WorkflowEditorTool.WORKFLOW_SAVED, this.showOutOfDate, this);
},
getMBSelectionInteraction: function()
{
return Ametys.tool.Tool.MB_TYPE_ACTIVE;
},
sendCurrentSelection : function()
{
var selection = this._panel.getSelectionModel().getSelection();
if(selection.length > 0){
var currentRecord = selection[0].getData();
var target = {
id: Ametys.message.MessageTarget.WORKFLOW_OBJECT,
parameters: {
id: currentRecord.id,
}
};
}
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.SELECTION_CHANGED,
targets: target
});
},
createPanel: function()
{
this._panel = Ext.create('Ext.grid.Panel', {
cls: 'workflow-search-tool',
stateful: true,
stateId: this.self.getName() + "$workflowgrid",
store: this._createStore(),
columns: [
{
dataIndex: "title",
text: "{{i18n plugin.workflow:PLUGINS_WORKFLOW_COLUM_TITLE_LABEL}}",
sortable: true,
width: 250,
renderer: this._renderTitles
},{
dataIndex: "id",
text: "{{i18n plugin.workflow:PLUGINS_WORKFLOW_COLUM_ID_LABEL}}",
sortable: true,
hidden: true,
width: 150
}
],
viewConfig: {
getRowClass: Ext.bind(this._getRowClass, this)
}
});
this._panel.on('selectionchange', this.sendCurrentSelection, this);
this._panel.on('itemdblclick', this._openWorkflowEditorTool, this);
return this._panel;
},
/**
* Render the workflow title so it would show if workflow has unsaved changes
* @param {Object} value The data value
* @param {Object} metaData A collection of metadata about the current cell
* @param {Ext.data.Model} record The record
* @return {String} The html representation of the title
*/
_renderTitles: function(value, metaData, record)
{
return '<span class="a-grid-glyph ametysicon-workflow"></span>' + record.getData().title;
},
/**
* @private
* Determine a row CSS class depending upon the record
* @param {Ext.data.Model} record The record
* @return {String} The CSS classname to apply
*/
_getRowClass: function(record)
{
return record.getData().hasChanges ? "row-modified" : "";
},
setParams: function (params)
{
this.callParent(arguments);
this.showOutOfDate();
},
/**
* Open an editor tool for selected workflow
* @param {Object} record : record of selected row
* @private
*/
_openWorkflowEditorTool: function(view, record)
{
var data = record.getData();
Ametys.tool.ToolsManager.openTool("uitool-workflow-editor", {id: data.id, title: data.title});
Ametys.tool.ToolsManager.openTool("uitool-workflow-preview", {workflowId: data.id, elementType: "workflow"});
},
/**
* Create the grid's store
* @returns {Object} the search grid's store
* @private
*/
_createStore: function()
{
var store = Ext.create('Ext.data.Store', {
model: Ametys.plugins.workflow.WorkflowGridModel,
sorters: [{
property: 'type',
direction: 'ASC'
},
{
property: 'title',
direction: 'ASC'
},
{
property:'id',
direction: 'ASC'
}],
proxy: {
type: 'ametys',
role: 'org.ametys.plugins.workflow.dao.WorkflowsDAO',
methodName: 'getWorkflowsList',
methodArguments: [],
cancelOutdatedRequest: true,
reader: this._getReaderCfg()
},
sortOnLoad: true
})
return store;
},
/**
* The Proxy reader's config
* @private
*/
_getReaderCfg: function()
{
return {
type: 'json',
rootProperty: 'workflows'
};
},
refresh: function ()
{
this.showRefreshing();
this._panel.getStore().load({callback: this._refreshCb, scope: this});
},
/**
* Function invoked after loading the store
* @private
*/
_refreshCb: function ()
{
var rows = this._panel.getStore().getData().items;
var hasChanged = false;
for (var i = 0; i < rows.length; i++)
{
if (rows[i].getData().hasChanges)
{
hasChanged = true;
}
}
this.setDirty(hasChanged);
var selection = this._panel.getSelectionModel().getSelection();
var record = this._panel.getStore().getById(this._workflowName);
if (record)
{
if (selection.length > 0 && record == selection[0])
{
// same selection
this.showRefreshed();
return;
}
this._panel.getSelectionModel().select(record);
}
this.showRefreshed();
},
/**
* Listener on selection messages, update tree selection
* @param {Ametys.message.Message} message The selection message.
* @private
*/
_onSelectionChanged: function (message)
{
var target = message.getTarget(Ametys.message.MessageTarget.WORKFLOW_OBJECT);
if (target != null)
{
var selection = this._panel.getSelectionModel().getSelection();
this._workflowName = target.getParameters().id;
var record = this._panel.getStore().getById(this._workflowName);
if (record)
{
if (selection.length > 0 && record == selection[0])
{
// same selection
return;
}
this._panel.getSelectionModel().select(record);
}
}
},
/**
* Listener on created and modified messages, select the new element
* @param {Ametys.message.Message} message The selection message.
* @private
*/
_onMessageCreatedOrModified: function(message)
{
var targets = message.getTargets(function(target) {
return target.getId() == Ametys.message.MessageTarget.WORKFLOW_OBJECT
});
if (targets.length)
{
this._workflowName = targets[0].getParameters().id
this.showOutOfDate();
}
}
});
/**
* Define the model for the workflow grid
*/
Ext.define('Ametys.plugins.workflow.WorkflowGridModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'string'},
{name: 'title', type: 'string'},
{name: 'hasChanges', type: 'boolean'}
]
});
/** Class defining target message names for workflows */
Ext.define("Ametys.message.WorkflowMessageTarget",
{
override: "Ametys.message.MessageTarget",
statics:
{
/**
* @member Ametys.message.MessageTarget
* @readonly
* @property {String} WORKFLOW_OBJECT The target type is a workflow. The expected parameters are:
* @property {String} WORKFLOW_OBJECT.id The id of the workflow
* @property {String} WORKFLOW_OBJECT.label The label of the workflow
* @property {String} WORKFLOW_OBJECT.hasChanges true if the workflow has unsaved changes
* @property {String} WORKFLOW_OBJECT.isNew true if the workflow has never been saved
*/
WORKFLOW_OBJECT: "workflow-object",
/**
* @member Ametys.message.MessageTarget
* @readonly
* @property {String} WORKFLOW_STEP The target type is a workflow step. The expected parameters are:
* @property {String} WORKFLOW_STEP.id The id of the step
* @property {String} WORKFLOW_STEP.label The label of the step
* @property {String} WORKFLOW_STEP.workflowId id of the related workflow
*/
WORKFLOW_STEP: "workflow-step",
/**
* @member Ametys.message.MessageTarget
* @readonly
* @property {String} WORKFLOW_ACTION The target type is a workflow action. The expected parameters are:
* @property {String} WORKFLOW_ACTION.id The id of the action
* @property {String} WORKFLOW_ACTION.label The label of the action
* @property {String} WORKFLOW_ACTION.stepId The id of the parent step
* @property {String} WORKFLOW_ACTION.workflowId id of the related workflow
*/
WORKFLOW_ACTION: "workflow-action",
/**
* @member Ametys.message.MessageTarget
* @readonly
* @property {String} WORKFLOW_PROPERTY The target type is a workflow meta. The expected parameters are:
* @property {String} WORKFLOW_PROPERTY.workflowId The id of the parent workflow
* @property {String} WORKFLOW_PROPERTY.stepId The id of the parent step
* @property {String} WORKFLOW_PROPERTY.actionId the parent action id, can be null if direct parent is a step
* @property {String} WORKFLOW_PROPERTY.name the property's name
* @property {String} WORKFLOW_PROPERTY.value the property's value
*/
WORKFLOW_PROPERTY: "workflow-property",
/**
* @member Ametys.message.MessageTarget
* @readonly
* @property {String} WORKFLOW_FUNCTION The target type is a workflow meta. The expected parameters are:
* @property {String} WORKFLOW_FUNCTION.workflowId The id of the parent workflow
* @property {String} WORKFLOW_FUNCTION.stepId The id of the parent step
* @property {String} WORKFLOW_FUNCTION.actionId the parent action id, can be null if direct parent is a step
* @property {String} WORKFLOW_FUNCTION.id the function's extension id
* @property {String} WORKFLOW_FUNCTION.type the function's type
* @property {Number} WORKFLOW_FUNCTION.index the function's index in its list
* @property {Boolean} WORKFLOW_FUNCTION.isLast if the function's is at the bottom of its list
*/
WORKFLOW_FUNCTION: "workflow-function",
/**
* @member Ametys.message.MessageTarget
* @readonly
* @property {String} WORKFLOW_CONDITIONS_OPERATOR The target type is a workflow conditions. The expected parameters are:
* @property {String} WORKFLOW_CONDITIONS_OPERATOR.workflowId The id of the parent workflow
* @property {String} WORKFLOW_CONDITIONS_OPERATOR.stepId The id of the parent step
* @property {String} WORKFLOW_CONDITIONS_OPERATOR.actionId the parent action
* @property {String} WORKFLOW_CONDITIONS_OPERATOR.type the conditions's type
* @property {String} WORKFLOW_CONDITIONS_OPERATOR.nodeId the conditions's node id
*/
WORKFLOW_CONDITIONS_OPERATOR: "workflow-conditions-operator",
/**
* @member Ametys.message.MessageTarget
* @readonly
* @property {String} WORKFLOW_CONDITION The target type is a workflow conditions. The expected parameters are:
* @property {String} WORKFLOW_CONDITION.workflowId The id of the parent workflow
* @property {String} WORKFLOW_CONDITION.stepId The id of the parent step
* @property {String} WORKFLOW_CONDITION.actionId the parent action id
* @property {String} WORKFLOW_CONDITION.nodeId the condition's node id
* @property {String} WORKFLOW_CONDITION.conditionId the condition's extension id
*/
WORKFLOW_CONDITION: "workflow-condition",
/**
* @member Ametys.message.MessageTarget
* @readonly
* @property {String} WORKFLOW_RESULT The target type is a workflow result. The expected parameters are:
* @property {String} WORKFLOW_RESULT.workflowId The id of the parent workflow
* @property {String} WORKFLOW_RESULT.actionId the parent action id
* @property {String} WORKFLOW_RESULT.stepId The id of the parent step
* @property {String} WORKFLOW_RESULT.nodeId the result's node id
* @property {String} WORKFLOW_RESULT.nodeLabel the result's node label
* @property {String} WORKFLOW_RESULT.isConditional true if the result is conditional
*/
WORKFLOW_RESULT: "workflow-result"
}
});