var flexygo;
(function (flexygo) {
var ui;
(function (ui_1) {
var wc;
(function (wc) {
var eStepResult;
(function (eStepResult) {
eStepResult[eStepResult["NoResult"] = 0] = "NoResult";
eStepResult[eStepResult["OK"] = 1] = "OK";
eStepResult[eStepResult["Error"] = 2] = "Error";
eStepResult[eStepResult["Warning"] = 3] = "Warning";
})(eStepResult || (eStepResult = {}));
var eStepStatus;
(function (eStepStatus) {
eStepStatus[eStepStatus["Initiliazing"] = 0] = "Initiliazing";
eStepStatus[eStepStatus["Running"] = 1] = "Running";
eStepStatus[eStepStatus["Paused"] = 2] = "Paused";
eStepStatus[eStepStatus["Finished"] = 3] = "Finished";
eStepStatus[eStepStatus["Aborted"] = 4] = "Aborted";
eStepStatus[eStepStatus["Waiting"] = 5] = "Waiting";
})(eStepStatus || (eStepStatus = {}));
class WorkflowNodeMarker {
}
wc.WorkflowNodeMarker = WorkflowNodeMarker;
class GipeTemplateFilterConfig {
}
wc.GipeTemplateFilterConfig = GipeTemplateFilterConfig;
class FlxGipeDesignerElement extends HTMLElement {
constructor() {
//If a constructor is defined, is REQUIRED call the super constructor
super();
/**
* Set if element has been connected to DOM
* @property connected {boolean}
*/
this.connected = false;
/**
* mxEditor opened dialog
* @property dialog {mxWindow}
*/
this.dialog = null;
/**
* Properties dialog
* @property dialog {mxWindow}
*/
this.propertiesDialog = null;
/**
* Debug dialog
* @property dialog {mxWindow}
*/
this.debugDialog = null;
/**
* Current loaded workflow
* @property workflow {flexygo.api.gipe.GipeWorkflow}
*/
this.workflow = null;
/**
* Current loaded workflow in debug mode
* @property workflow {flexygo.api.gipe.GipeWorkflow}
*/
this.debugWorkflow = null;
/**
* Current execution Id
* @property currentExecutionId {number}
*/
this.currentExecutionId = 0;
/**
* Last cell id painted as executed
* @property lastDebugGraphId {number}
*/
this.lastDebugGraphId = null;
/**
* Last cell that triggered a popup event
* @property popupCell {number}
*/
this.popupCell = null;
/**
* Filter configuration for templates dialog
* @property templateFilter {GipeTemplateFilterConfig}
*/
this.templateFilter = null;
this.fixedPropertiesDialog = false;
}
/**
* Array of observed attributes. REQUIRED
* @property observedAttributes {Array}
*/
static get observedAttributes() {
return ["objectname", "objectwhere"];
}
/**
* Fires when element is attached to DOM
* @method connectedCallback
*/
connectedCallback() {
this.connected = true;
flexygo.events.on(this, "module", "resized", this.onModuleResize);
this.init();
}
/**
* Fires when element is dettached to DOM
* @method disconnectedCallback
*/
disconnectedCallback() {
flexygo.events.off(this, "module", "resized", this.onModuleResize);
if (this.dialog) {
this.dialog.destroy();
}
if (this.propertiesDialog) {
this.propertiesDialog.destroy();
}
if (this.debugDialog) {
this.debugDialog.destroy();
}
}
/**
* Fires when the attribute value of the element is changed.
* @method attributeChangedCallback
*/
attributeChangedCallback(attrName, oldVal, newVal) {
let needInit = false;
if (this.connected && needInit) {
this.init();
}
if (attrName.toLowerCase() === 'objectname' || attrName.toLowerCase() === 'objectwhere') {
if (this.hasAttribute('objectName') && this.hasAttribute('objectwhere')) {
if (this.getAttribute('objectName').length > 0 && this.getAttribute('objectWhere').length > 0) {
let entity = new flexygo.obj.Entity(this.getAttribute('objectName'), this.getAttribute('objectWhere'));
entity.read();
this.loadWorkflow(entity.data["WorkflowId"].Value, -1, false);
}
}
}
}
/**
* Init the webcomponent. REQUIRED.
* @method init
*/
init() {
flexygo.events.on(this, "gipe", "debugstep", this.onDebugStepChanged);
//mxBasePath = '../js/plugins/mxgraph';
let editorconfig = `
<mxEditor
defaultGroup="group" defaultEdge=""
forcedInserting="0"
swimlaneRequired="0">
<Array as="cycleAttributeValues">
<add value="#EEEEEE"/>
</Array>
<Array as="templates"></Array>
<mxDefaultKeyHandler as="keyHandler">
</mxDefaultKeyHandler>
<ui>
<add as="graph" element="gipegraph"/>
</ui>
<mxGraph as="graph" alternateEdgeStyle="verticalEdge" dropEnabled="1">
<mxGraphModel as="model">
<root>
<Workflow label="" description="" id="0"/>
<Layer label="Default Layer">
<mxCell parent="0"/>
</Layer>
</root>
</mxGraphModel>
<mxStylesheet as="stylesheet">
</mxStylesheet>
</mxGraph>
</mxEditor>
`;
let self = this;
let me = $(this);
this.workflowStack = [];
this.debugStack = [];
me.empty();
this.uuid = flexygo.utils.uniqueUUID();
if (!mxClient.isBrowserSupported()) {
mxUtils.error('Browser is not supported!', 200, false);
return;
}
let template = `
<div id="${this.uuid}" class="gipecp">
<div class="gipetoolbar" id="gipetoolbar" />
<ol class="breadcrumb" />
<div class="gipecp graph" id="gipegraph" />
</div>
`;
me.html(template);
me.find('#gipegraph').droppable({
drop: (event, ui) => {
this.doDropTemplate(ui);
}
});
//Load base config from XML template
mxClient.language = null;
mxObjectCodec.allowEval = true;
let doc = mxUtils.parseXml(editorconfig).childNodes[0];
this.editor = new mxEditor(doc);
mxObjectCodec.allowEval = false;
// Snap to guides
mxGraphHandler.prototype.guidesEnabled = true;
mxConstants.GUIDE_COLOR = '#FF0000';
mxConstants.GUIDE_STROKEWIDTH = 1;
mxEdgeHandler.prototype.snapToTerminals = true;
//Rest of editor and graph configuration
this.initGraphStyles();
this.initEditorTemplates();
this.initEditorToolbar();
this.initEditorKeyHandler();
this.initEditorMouseHandler();
this.initEditorPopupMenu();
this.editor.defaultEdge = this.editor.templates["relation"];
this.editor.addAction("open", (editor, cell) => {
if (self.editor.isModified() === true) {
flexygo.msg.confirm(flexygo.localization.translate('flxgipe.confirmunsavedchanges'), (ret) => {
if (ret === true) {
self.openLoadDialog();
}
});
}
else {
self.openLoadDialog();
}
});
this.editor.addAction("new", (editor, cell) => {
self.newWorkflow();
});
this.editor.addAction("templates", (editor, cell) => {
self.openTemplateDialog();
});
this.editor.addAction("save", (editor, cell) => {
self.openSaveDialog();
});
this.editor.addAction("generate", (editor, cell) => {
self.generateWorkflow();
});
this.editor.addAction("up", (editor, cell) => {
self.goUp(self.workflowStack.length - 1);
});
this.editor.addAction("down", (editor, cell) => {
self.goDown();
});
this.editor.addAction("run", (editor, cell) => {
self.runWorkflow();
});
this.editor.addAction("debug", (editor, cell) => {
self.startDebugWorkflow();
});
this.editor.addAction("showProperties", (editor, cell) => {
if ((this.fixedPropertiesDialog === false) && (this.propertiesDialog != null)) {
this.propertiesDialog.destroy();
return;
}
if (graph.getSelectionCells().length === 1) {
self.showCellProperties(graph.getSelectionCells()[0]);
}
else {
self.showCellProperties(null);
}
});
this.editor.addAction("properties", (editor, cell) => {
let btn = $(this).find('button[data-btn="properties"]');
if (this.fixedPropertiesDialog === true) {
this.fixedPropertiesDialog = false;
$(btn).removeClass("mxToolbarItemSelected").addClass("mxToolbarItem");
if (this.propertiesDialog) {
this.propertiesDialog.destroy();
this.destroyPropertiesDialog();
}
}
else {
this.fixedPropertiesDialog = true;
$(btn).removeClass("mxToolbarItem").addClass("mxToolbarItemSelected");
if (!this.propertiesDialog) {
this.openPropertiesDialog();
if (graph.getSelectionCells().length === 1) {
self.showCellProperties(graph.getSelectionCells()[0]);
}
else {
self.showCellProperties(null);
}
}
}
});
let graph = this.editor.graph;
//Avoid unconnected edges
graph.setAllowDanglingEdges(false);
graph.setDisconnectOnMove(false);
graph.convertValueToString = function (cell) {
return cell.getAttribute('label', '');
};
var cellLabelChanged = graph.cellLabelChanged;
graph.cellLabelChanged = function (cell, newValue, autoSize) {
if (mxUtils.isNode(cell.value)) {
// Clones the value for correct undo/redo
var elt = cell.value.cloneNode(true);
elt.setAttribute('label', newValue);
newValue = elt;
}
cellLabelChanged.apply(graph, [cell, newValue, autoSize]);
};
graph.getSelectionModel().addListener(mxEvent.CHANGE, function (sender, evt) {
self.updateToolbarStatus();
if (self.fixedPropertiesDialog === true) {
if (graph.getSelectionCells().length === 1) {
self.showCellProperties(graph.getSelectionCells()[0]);
}
else {
self.showCellProperties(null);
}
}
});
this.editor.graph.setHtmlLabels(true);
this.setGraphSize();
this.render();
}
initGraphStyles() {
//Graph styles
let style = null;
//Default vertex style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RECTANGLE;
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
style[mxConstants.STYLE_STROKECOLOR] = '#98c75d';
style[mxConstants.STYLE_ROUNDED] = true;
style[mxConstants.STYLE_FILLCOLOR] = '#cce3ae';
style[mxConstants.STYLE_FONTCOLOR] = 'black';
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
style[mxConstants.STYLE_FONTSIZE] = '12';
style[mxConstants.STYLE_WHITE_SPACE] = 'wrap';
this.editor.graph.getStylesheet().putDefaultVertexStyle(style);
//Invalid vertex
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RECTANGLE;
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
style[mxConstants.STYLE_STROKECOLOR] = '#c75d62';
style[mxConstants.STYLE_FILLCOLOR] = '#db9699';
this.editor.graph.getStylesheet().putCellStyle("invalid-rectangle", style);
//Success vertex
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RECTANGLE;
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
style[mxConstants.STYLE_STROKECOLOR] = '#648b30';
style[mxConstants.STYLE_FILLCOLOR] = '#8cc048';
style[mxConstants.STYLE_STROKEWIDTH] = 4;
this.editor.graph.getStylesheet().putCellStyle("success-rectangle", style);
//Running rectangle
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RECTANGLE;
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
style[mxConstants.STYLE_STROKEWIDTH] = 4;
style[mxConstants.STYLE_STROKECOLOR] = '#ffa500';
style[mxConstants.STYLE_FILLCOLOR] = '#ffdb99';
this.editor.graph.getStylesheet().putCellStyle("running-rectangle", style);
//Error rectangle
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RECTANGLE;
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
style[mxConstants.STYLE_STROKEWIDTH] = 4;
style[mxConstants.STYLE_STROKECOLOR] = '#ff0f0f';
style[mxConstants.STYLE_FILLCOLOR] = '#ff4a4a';
this.editor.graph.getStylesheet().putCellStyle("error-rectangle", style);
// Default edge style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_CONNECTOR;
style[mxConstants.STYLE_STROKECOLOR] = '#6482B9';
style[mxConstants.STYLE_STROKEWIDTH] = 2;
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
style[mxConstants.STYLE_EDGE] = mxEdgeStyle.ElbowConnector;
style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_CLASSIC;
style[mxConstants.STYLE_VERTICAL_LABEL_POSITION] = mxConstants.ALIGN_TOP;
style[mxConstants.STYLE_FONTSIZE] = '12';
style[mxConstants.STYLE_ENDSIZE] = 2;
style[mxConstants.STYLE_ENDFILL] = 1;
style[mxConstants.STYLE_ROUNDED] = 1;
this.editor.graph.getStylesheet().putDefaultEdgeStyle(style);
// Running edge style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_CONNECTOR;
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
style[mxConstants.STYLE_EDGE] = mxEdgeStyle.ElbowConnector;
style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_CLASSIC;
style[mxConstants.STYLE_VERTICAL_LABEL_POSITION] = mxConstants.ALIGN_TOP;
style[mxConstants.STYLE_FONTSIZE] = '12';
style[mxConstants.STYLE_ENDSIZE] = 2;
style[mxConstants.STYLE_ENDFILL] = 1;
style[mxConstants.STYLE_ROUNDED] = 1;
style[mxConstants.STYLE_STROKEWIDTH] = 4;
style[mxConstants.STYLE_STROKECOLOR] = '#ffa500';
style[mxConstants.STYLE_FILLCOLOR] = '#ffdb99';
this.editor.graph.getStylesheet().putCellStyle("running-edge", style);
// Success edge style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_CONNECTOR;
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
style[mxConstants.STYLE_EDGE] = mxEdgeStyle.ElbowConnector;
style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_CLASSIC;
style[mxConstants.STYLE_VERTICAL_LABEL_POSITION] = mxConstants.ALIGN_TOP;
style[mxConstants.STYLE_FONTSIZE] = '12';
style[mxConstants.STYLE_ENDSIZE] = 2;
style[mxConstants.STYLE_ENDFILL] = 1;
style[mxConstants.STYLE_ROUNDED] = 1;
style[mxConstants.STYLE_STROKECOLOR] = '#648b30';
style[mxConstants.STYLE_FILLCOLOR] = '#8cc048';
style[mxConstants.STYLE_STROKEWIDTH] = 2;
this.editor.graph.getStylesheet().putCellStyle("success-edge", style);
//Label style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RECTANGLE;
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
style[mxConstants.STYLE_STROKECOLOR] = 'black';
style[mxConstants.STYLE_ROUNDED] = true;
style[mxConstants.STYLE_FILLCOLOR] = 'white';
this.editor.graph.getStylesheet().putCellStyle("label", style);
//Ellipse style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_ELLIPSE;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_ELLIPSE;
this.editor.graph.getStylesheet().putCellStyle("ellipse", style);
//invalid Ellipse style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_ELLIPSE;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_ELLIPSE;
style[mxConstants.STYLE_STROKECOLOR] = '#c75d62';
style[mxConstants.STYLE_FILLCOLOR] = '#db9699';
this.editor.graph.getStylesheet().putCellStyle("invalid-ellipse", style);
//Success Ellipse style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_ELLIPSE;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_ELLIPSE;
style[mxConstants.STYLE_STROKECOLOR] = '#648b30';
style[mxConstants.STYLE_FILLCOLOR] = '#8cc048';
style[mxConstants.STYLE_STROKEWIDTH] = 4;
this.editor.graph.getStylesheet().putCellStyle("success-ellipse", style);
//Error Ellipse style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_ELLIPSE;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_ELLIPSE;
style[mxConstants.STYLE_STROKECOLOR] = '#ff0f0f';
style[mxConstants.STYLE_FILLCOLOR] = '#ff4a4a';
style[mxConstants.STYLE_STROKEWIDTH] = 4;
this.editor.graph.getStylesheet().putCellStyle("error-ellipse", style);
//Running Ellipse style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_ELLIPSE;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_ELLIPSE;
style[mxConstants.STYLE_STROKEWIDTH] = 4;
style[mxConstants.STYLE_STROKECOLOR] = '#ffa500';
style[mxConstants.STYLE_FILLCOLOR] = '#ffdb99';
this.editor.graph.getStylesheet().putCellStyle("running-ellipse", style);
//Rhombus style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RHOMBUS;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_RHOMBUS;
this.editor.graph.getStylesheet().putCellStyle("rhombus", style);
//Invalid Rhombus style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RHOMBUS;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_RHOMBUS;
style[mxConstants.STYLE_STROKECOLOR] = '#c75d62';
style[mxConstants.STYLE_FILLCOLOR] = '#db9699';
this.editor.graph.getStylesheet().putCellStyle("invalid-rhombus", style);
//Running rhombus style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RHOMBUS;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_RHOMBUS;
style[mxConstants.STYLE_STROKEWIDTH] = 4;
style[mxConstants.STYLE_STROKECOLOR] = '#ffa500';
style[mxConstants.STYLE_FILLCOLOR] = '#ffdb99';
this.editor.graph.getStylesheet().putCellStyle("running-rhombus", style);
//Success rhombus style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RHOMBUS;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_RHOMBUS;
style[mxConstants.STYLE_STROKEWIDTH] = 4;
style[mxConstants.STYLE_STROKECOLOR] = '#648b30';
style[mxConstants.STYLE_FILLCOLOR] = '#8cc048';
this.editor.graph.getStylesheet().putCellStyle("success-rhombus", style);
//Error rhombus style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RHOMBUS;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_RHOMBUS;
style[mxConstants.STYLE_STROKEWIDTH] = 4;
style[mxConstants.STYLE_STROKECOLOR] = '#ff0f0f';
style[mxConstants.STYLE_FILLCOLOR] = '#ff4a4a';
this.editor.graph.getStylesheet().putCellStyle("error-rhombus", style);
//Cloud style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_CLOUD;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_RHOMBUS;
this.editor.graph.getStylesheet().putCellStyle("cloud", style);
//Invalid Cloud style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_CLOUD;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_RHOMBUS;
style[mxConstants.STYLE_STROKECOLOR] = '#c75d62';
style[mxConstants.STYLE_FILLCOLOR] = '#db9699';
this.editor.graph.getStylesheet().putCellStyle("invalid-cloud", style);
//Running Cloud style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_CLOUD;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_RHOMBUS;
style[mxConstants.STYLE_STROKEWIDTH] = 4;
style[mxConstants.STYLE_STROKECOLOR] = '#ffa500';
style[mxConstants.STYLE_FILLCOLOR] = '#ffdb99';
this.editor.graph.getStylesheet().putCellStyle("running-cloud", style);
//Success Cloud style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_CLOUD;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_RHOMBUS;
style[mxConstants.STYLE_STROKEWIDTH] = 4;
style[mxConstants.STYLE_STROKECOLOR] = '#648b30';
style[mxConstants.STYLE_FILLCOLOR] = '#8cc048';
this.editor.graph.getStylesheet().putCellStyle("success-cloud", style);
//Error Cloud style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_CLOUD;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_RHOMBUS;
style[mxConstants.STYLE_STROKEWIDTH] = 4;
style[mxConstants.STYLE_STROKECOLOR] = '#ff0f0f';
style[mxConstants.STYLE_FILLCOLOR] = '#ff4a4a';
this.editor.graph.getStylesheet().putCellStyle("error-cloud", style);
//Hexagon style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_HEXAGON;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_HEXAGON;
style[mxConstants.STYLE_FONTCOLOR] = 'black';
style[mxConstants.STYLE_LABEL_BACKGROUNDCOLOR] = 'none';
this.editor.graph.getStylesheet().putCellStyle("hexagon", style);
//Invalid hexagon style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_HEXAGON;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_HEXAGON;
style[mxConstants.STYLE_STROKECOLOR] = '#c75d62';
style[mxConstants.STYLE_FILLCOLOR] = '#db9699';
this.editor.graph.getStylesheet().putCellStyle("invalid-hexagon", style);
//Running hexagon style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_HEXAGON;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_HEXAGON;
style[mxConstants.STYLE_STROKEWIDTH] = 4;
style[mxConstants.STYLE_STROKECOLOR] = '#ffa500';
style[mxConstants.STYLE_FILLCOLOR] = '#ffdb99';
this.editor.graph.getStylesheet().putCellStyle("running-hexagon", style);
//Succes hexagon
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_HEXAGON;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_HEXAGON;
style[mxConstants.STYLE_STROKECOLOR] = '#648b30';
style[mxConstants.STYLE_FILLCOLOR] = '#8cc048';
style[mxConstants.STYLE_STROKEWIDTH] = 4;
this.editor.graph.getStylesheet().putCellStyle("success-hexagon", style);
//Error hexagon
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_HEXAGON;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_HEXAGON;
style[mxConstants.STYLE_STROKECOLOR] = '#ff0f0f';
style[mxConstants.STYLE_FILLCOLOR] = '#ff4a4a';
style[mxConstants.STYLE_STROKEWIDTH] = 4;
this.editor.graph.getStylesheet().putCellStyle("error-hexagon", style);
//customized workflow
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_HEXAGON;
style[mxConstants.STYLE_PERIMETER] = mxConstants.PERIMETER_HEXAGON;
style[mxConstants.STYLE_STROKECOLOR] = '#a462d6';
style[mxConstants.STYLE_FILLCOLOR] = '#c79fe6';
//style[mxConstants.STYLE_FONTCOLOR] = 'white';
this.editor.graph.getStylesheet().putCellStyle("customized-workflow", style);
}
initEditorTemplates() {
this.addEditorTemplate('process', '<Process label="' + flexygo.localization.translate('flxgipe.editortemplates.process') + '" description="" fgid="" ><mxCell style="invalid-rectangle" vertex="1" ><mxGeometry as="geometry" width="108" height="48" /></mxCell></Process>');
this.addEditorTemplate('object', '<Object label="' + flexygo.localization.translate('flxgipe.editortemplates.object') + '" description="" fgid=""><mxCell vertex="1" style="invalid-ellipse"><mxGeometry as="geometry" width="48" height="48" /></mxCell></Object>');
this.addEditorTemplate('decission', '<Decission label="' + flexygo.localization.translate('flxgipe.editortemplates.decission') + '" description="" fgid=""><mxCell vertex= "1" style="invalid-rhombus"><mxGeometry as="geometry" width="108" height="48" /></mxCell></Decission>');
this.addEditorTemplate('event', '<Event label="' + flexygo.localization.translate('flxgipe.editortemplates.event') + '" description="" fgid=""><mxCell vertex= "1" style="invalid-cloud"><mxGeometry as="geometry" width="108" height="48" /></mxCell></Event>');
this.addEditorTemplate('label', '<Label label="' + flexygo.localization.translate('flxgipe.editortemplates.label') + '" description=""><mxCell vertex= "1" style="label" connectable="0"><mxGeometry as="geometry" width="108" height="48" /></mxCell></Label>');
this.addEditorTemplate('group', '<Group label="" description="" ><mxCell vertex="1" style="group" connectable="0"/></Group>');
this.addEditorTemplate('relation', '<Relation label="" description=""><mxCell edge="1"><mxGeometry as="geometry" relative="1"/></mxCell></Relation>');
this.addEditorTemplate('workflow', '<Workflow label="' + flexygo.localization.translate('flxgipe.editortemplates.workflow') + '" description="" fgid=""><mxCell vertex="1" style="invalid-hexagon" connectable="1"><mxGeometry as="geometry" width="108" height="108"/></mxCell></Workflow>');
}
addEditorTemplate(name, xmlString) {
let doc = mxUtils.parseXml(xmlString);
let codec = new mxCodec(doc);
let template = codec.decodeCell(doc.documentElement);
this.editor.addTemplate(name, template);
}
initEditorPopupMenu() {
let self = this;
let graph = this.editor.graph;
// Installs context menu
graph.popupMenuHandler.factoryMethod = function (menu, cell, evt) {
self.popupCell = null;
if (self.currentExecutionId !== 0) {
return;
}
if (!cell) {
if (self.workflow !== null) {
menu.addItem(flexygo.localization.translate('flxgipe.popupmenu.workflowproperties'), null, function () { self.showWorkflowProperties(); }, null, "fa fa-gear");
menu.addSeparator();
cell = graph.getModel().cells[0];
menu.addItem(flexygo.localization.translate('flxgipe.popupmenu.view'), null, function () { self.viewCell(cell); }, null, "flx-icon icon-eye");
menu.addItem(flexygo.localization.translate('flxgipe.popupmenu.listparams'), null, function () { self.listParamsCell(cell); }, null, "flx-icon icon-bullet-list");
}
else {
return;
}
}
else {
let hasId = (cell.value.hasAttribute('fgid') && cell.value.getAttribute('fgid').length > 0);
menu.addItem(flexygo.localization.translate('flxgipe.popupmenu.properties'), null, function () { self.showCellProperties(cell); }, null, "fa fa-gear");
if (cell.value.localName.toLowerCase() === 'workflow') {
if (hasId) {
menu.addItem(flexygo.localization.translate('flxgipe.popupmenu.enter'), null, function () { self.goDown(); }, null, "flx-icon icon-arrow-2");
menu.addSeparator();
}
}
if (hasId) {
menu.addSeparator();
menu.addItem(flexygo.localization.translate('flxgipe.popupmenu.view'), null, function () { self.viewCell(cell); }, null, "flx-icon icon-eye");
if (cell.value.localName.toLowerCase() === 'workflow' || cell.value.localName.toLowerCase() === 'process' || cell.value.localName.toLowerCase() === 'decission') {
menu.addItem(flexygo.localization.translate('flxgipe.popupmenu.listparams'), null, function () { self.listParamsCell(cell); }, null, "flx-icon icon-bullet-list");
}
}
else {
menu.addSeparator();
menu.addItem(flexygo.localization.translate('flxgipe.popupmenu.new'), null, function () { self.newCell(cell); }, null, "flx-icon icon-new");
}
//menu.addItem('Edit', null, function () { self.editCell(cell); }, null, "fa fa-gear");
}
//menu.addSeparator();
//var submenu1 = menu.addItem('Submenu 1', null, null);
//menu.addItem('Subitem 1', null, function () {
// alert('Subitem 1');
//}, submenu1);
};
}
initEditorToolbar() {
var container = document.getElementById("gipetoolbar");
var toolbar = new mxDefaultToolbar(container, this.editor);
let btn = null;
btn = toolbar.addItem("", null, "new");
$(btn).append('<i class="flx-icon icon-new" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.new'));
btn = toolbar.addItem("", null, "open");
$(btn).append('<i class="fa fa-folder-open" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.open'));
btn = toolbar.addItem("", null, "save");
$(btn).append('<i class="fa fa-save" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.save'));
btn = toolbar.addItem("", null, "generate");
$(btn).append('<i class="fa fa-arrow-circle-o-right" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.generate'));
btn = toolbar.addItem("", null, "run");
$(btn).append('<i class="flx-icon icon-arrow-head-3" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.run'));
btn = toolbar.addItem("", null, "debug");
$(btn).append('<i class="fa fa-play-circle" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.debug'));
toolbar.addSeparator();
this.versionCombo = toolbar.addCombo();
$(this.versionCombo).on('click', (e) => {
let val = $(this.versionCombo).val();
if (val && val !== '') {
if (val != this.workflow.Version) {
this.loadWorkflow(this.workflow.WorkflowId, val, false);
}
}
});
toolbar.addSeparator();
btn = toolbar.addItem("", null, "up");
btn.setAttribute("data-action", "up");
$(btn).append('<i class="fa fa-expand" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.up'));
btn = toolbar.addItem("", null, "down");
btn.setAttribute("data-action", "down");
$(btn).append('<i class="fa fa-compress" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.down'));
toolbar.addSeparator();
btn = toolbar.addMode("", null, "select");
$(btn).append('<i class="fa fa-mouse-pointer" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.select'));
btn = toolbar.addMode("", null, "pan");
$(btn).append('<i class="fa fa-hand-pointer-o" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.pan'));
toolbar.addSeparator();
btn = toolbar.addItem("", null, "undo");
$(btn).append('<i class="fa fa-undo" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.undo'));
btn = toolbar.addItem("", null, "redo");
$(btn).append('<i class="fa fa-repeat" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.redo'));
toolbar.addSeparator();
btn = toolbar.addItem("", null, "cut");
$(btn).append('<i class="fa fa-cut" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.cut'));
btn = toolbar.addItem("", null, "copy");
$(btn).append('<i class="fa fa-copy" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.copy'));
btn = toolbar.addItem("", null, "paste");
$(btn).append('<i class="fa fa-paste" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.paste'));
btn = toolbar.addItem("", null, "delete");
$(btn).append('<i class="fa fa-times-circle" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.delete'));
toolbar.addSeparator();
btn = toolbar.addItem("", null, "group");
$(btn).append('<i class="fa fa fa-object-group" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.group'));
btn = toolbar.addItem("", null, "ungroup");
$(btn).append('<i class="fa fa fa-object-ungroup" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.ungroup'));
toolbar.addSeparator();
//var combo = toolbar.addActionCombo('More actions...');
//toolbar.addActionOption(combo, 'Paste', 'paste');
toolbar.addPrototype(flexygo.localization.translate('flxgipe.editortoolbar.label'), "js/plugins/mxgraph/images/text.gif", this.editor.templates["label"]);
toolbar.addPrototype(flexygo.localization.translate('flxgipe.editortoolbar.workflow'), "js/plugins/mxgraph/images/hexagon.gif", this.editor.templates["workflow"]);
toolbar.addPrototype(flexygo.localization.translate('flxgipe.editortoolbar.object'), "js/plugins/mxgraph/images/ellipse.gif", this.editor.templates["object"]);
toolbar.addPrototype(flexygo.localization.translate('flxgipe.editortoolbar.process'), "js/plugins/mxgraph/images/rectangle.gif", this.editor.templates["process"]);
toolbar.addPrototype(flexygo.localization.translate('flxgipe.editortoolbar.decission'), "js/plugins/mxgraph/images/rhombus.gif", this.editor.templates["decission"]);
toolbar.addPrototype(flexygo.localization.translate('flxgipe.editortoolbar.event'), "js/plugins/mxgraph/images/cloud.gif", this.editor.templates["event"]);
toolbar.addMode(flexygo.localization.translate('flxgipe.editortoolbar.connect'), "js/plugins/mxgraph/images/connect.gif", "connect");
toolbar.addSeparator();
btn = toolbar.addItem("", null, "fit");
$(btn).append('<i class="fa fa-square-o" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.fit'));
btn = toolbar.addItem("", null, "zoomIn");
$(btn).append('<i class="fa fa-search-plus" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.zoomin'));
btn = toolbar.addItem("", null, "zoomOut");
$(btn).append('<i class="fa fa-search-minus" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.zoomout'));
btn = toolbar.addItem("", null, "actualSize");
$(btn).append('<i class="fa fa-search" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.actualsize'));
toolbar.addSeparator();
btn = toolbar.addItem("", null, "templates");
$(btn).append('<i class="fa fa-tasks" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.templates'));
btn = toolbar.addItem("", null, "properties");
$(btn).append('<i class="fa fa-gear" />').attr("title", flexygo.localization.translate('flxgipe.editortoolbar.properties'));
$(btn).attr("data-btn", "properties");
}
initEditorKeyHandler() {
//https://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
this.editor.keyHandler.bindAction(8, "collapse"); //backspace
this.editor.keyHandler.bindAction(13, "expand"); //enter
this.editor.keyHandler.bindAction(33, "exitGroup");
this.editor.keyHandler.bindAction(34, "enterGroup");
this.editor.keyHandler.bindAction(35, "refresh"); //end
this.editor.keyHandler.bindAction(36, "home"); //home
this.editor.keyHandler.bindAction(37, "selectPrevious");
this.editor.keyHandler.bindAction(38, "selectParent");
this.editor.keyHandler.bindAction(40, "selectChild");
this.editor.keyHandler.bindAction(39, "selectNext");
this.editor.keyHandler.bindAction(46, "delete"); //delete
this.editor.keyHandler.bindAction(113, "edit");
this.editor.keyHandler.bindAction(107, "zoomIn"); //add
this.editor.keyHandler.bindAction(109, "zoomOut"); //substract
this.editor.keyHandler.bindAction(65, "selectAll", true); //Ctrl+A
this.editor.keyHandler.bindAction(90, "undo", true); //Ctrl+Z
this.editor.keyHandler.bindAction(89, "redo", true); //Ctrol+Y
this.editor.keyHandler.bindAction(88, "cut", true);
this.editor.keyHandler.bindAction(67, "copy", true);
this.editor.keyHandler.bindAction(86, "paste", true);
this.editor.keyHandler.bindAction(71, "group", true);
this.editor.keyHandler.bindAction(85, "ungroup", true);
this.editor.keyHandler.bindAction(115, "showProperties"); //f4
//this.editor.keyHandler.bindAction(123, "showProperties"); F12
}
initEditorMouseHandler() {
let editor = this.editor;
mxEvent.addMouseWheelListener((evt, up) => {
if (!mxEvent.isConsumed(evt)) {
let consume = false;
let elem = evt.srcElement;
while (elem) {
if (elem.hasAttribute("id")) {
if (elem.getAttribute("id") === "gipegraph") {
consume = true;
elem = null;
}
}
if (elem) {
elem = elem.parentElement;
}
}
if (consume) {
if (up) {
editor.execute('zoomIn');
}
else {
editor.execute('zoomOut');
}
mxEvent.consume(evt);
}
}
});
}
doDropTemplate(ui) {
let type = parseInt(ui.draggable.attr("data-type"));
let id = ui.draggable.attr("data-id");
let descrip = ui.draggable.attr("data-descrip");
let style = null;
let value = null;
let w;
let h;
switch (type) {
case 1:
style = 'ellipse';
w = 48;
h = 48;
value = this.editor.templates["object"].value.cloneNode(true);
break;
case 2:
style = 'rounded';
w = 108;
h = 48;
value = this.editor.templates["process"].value.cloneNode(true);
break;
case 3:
style = 'rhombus';
w = 108;
h = 48;
value = this.editor.templates["decission"].value.cloneNode(true);
break;
case 4:
style = 'hexagon';
w = 108;
h = 108;
value = this.editor.templates["workflow"].value.cloneNode(true);
break;
case 5:
style = 'cloud';
w = 108;
h = 48;
value = this.editor.templates["event"].value.cloneNode(true);
break;
case 6:
style = 'label';
w = 108;
h = 48;
value = this.editor.templates["label"].value.cloneNode(true);
break;
}
if (type && style && id) {
let parent = this.editor.graph.getDefaultParent();
this.editor.graph.getModel().beginUpdate();
try {
let x = ui.position.left - $('#gipegraph').position().left;
if (x < 0)
x = 0;
let y = ui.position.top - $('#gipegraph').position().top;
if (y < 0)
y = 0;
value.setAttribute("fgid", id);
value.setAttribute("label", descrip);
let v = this.editor.graph.insertVertex(parent, null, value, x, y, w, h, style);
}
finally {
// Updates the display
this.editor.graph.getModel().endUpdate();
}
}
}
setGraphSize() {
let module = $(this).closest('flx-module');
let height = 0;
let toolbarHeight = module.find('#gipetoolbar').outerHeight();
if (toolbarHeight < 35) {
toolbarHeight = 35;
}
let graphMargin = ($('#gipegraph').outerHeight(true) - $('#gipegraph').outerHeight());
if (module.hasClass("fullscreen")) {
let moduleHeight = module.outerHeight();
height = moduleHeight - toolbarHeight - graphMargin;
}
else {
let doubleMargin = 2 * ($('#realMain').outerHeight(true) - $('#realMain').outerHeight());
let headerHeight = module.find('.cntHeader').outerHeight();
let contentHeight = $('#mainContent').height();
height = contentHeight - doubleMargin - headerHeight - toolbarHeight - graphMargin;
}
$(this).find("#gipegraph").height(height);
}
/**
* Refresh the webcomponent. REQUIRED.
* @method refresh
*/
refresh() {
this.render();
}
/**
* Opens upper workflow
* @method goUp
*/
goUp(level) {
let exec = () => {
while (this.workflowStack.length > level) {
this.workflow = this.workflowStack.pop();
}
this.loadWorkflow(this.workflow.WorkflowId, this.workflow.Version, false);
};
if (this.workflowStack && this.workflowStack.length > 0) {
if (this.editor.isModified() === true) {
flexygo.msg.confirm(flexygo.localization.translate('flxgipe.confirmunsavedchanges'), (ret) => {
if (ret === true) {
exec();
}
});
}
else {
exec();
}
}
}
/**
* Opens lower workflow
* @method goDown
*/
goDown() {
let selected = this.editor.graph.getSelectionCells();
if (selected && selected.length === 1) {
let cell = selected[0];
if (cell.value && cell.value.localName === 'Workflow') {
let wfid = cell.value.getAttribute('fgid');
if (this.editor.isModified() === true) {
flexygo.msg.confirm(flexygo.localization.translate('flxgipe.confirmunsavedchanges'), (ret) => {
if (ret === true) {
this.loadWorkflow(wfid, -1, true);
}
});
}
else {
this.loadWorkflow(wfid, -1, true);
}
}
}
}
/**
* Runs the current workflow
* @method runWorkflow
*/
runWorkflow() {
if (!this.workflow) {
flexygo.msg.error(flexygo.localization.translate('flxgipe.errornoworkflowselected'), null, flexygo.localization.translate('flxgipe.dialogruntitle'));
return;
}
//flexygo.nav.execProcess(this.workflow.WorkflowId, null, null, null, null, 'current', false, $(this));
flexygo.ajax.post('~/api/Gipe', 'runWorkflow', { workflowId: this.workflow.WorkflowId, version: this.workflow.Version }, (ret) => {
});
}
/**
* Runs the current workflow in debug mode
* @method startDebugWorkflow
*/
startDebugWorkflow() {
if (!this.workflow) {
flexygo.msg.error(flexygo.localization.translate('flxgipe.errornoworkflowselected'), null, flexygo.localization.translate('flxgipe.dialogruntitle'));
return;
}
if (this.currentExecutionId !== 0) {
flexygo.msg.error(flexygo.localization.translate('flxgipe.errorallreadydebugging'), null, flexygo.localization.translate('flxgipe.dialogruntitle'));
return;
}
if (!this.debugDialog) {
this.openDebugDialog();
}
$(this.debugDialog.content).find('button[name="dbg-stepinto"]').prop('disabled', true);
$(this.debugDialog.content).find('button[name="dbg-stepover"]').prop('disabled', true);
flexygo.ajax.post('~/api/Gipe', 'debugWorkflow', { workflowId: this.workflow.WorkflowId, version: this.workflow.Version, executionId: this.currentExecutionId, stepOver: false }, (execId) => {
var tree = $('#gipe-debug-tree');
let mainNode = {
text: this.workflow.Descrip,
icon: "flx-icon flx-icon-share"
};
$.jstree.defaults.core.data = mainNode;
$(tree).jstree();
this.debugStack = [];
this.workflow.ExecutionId = execId;
this.debugWorkflow = this.workflow;
this.currentExecutionId = execId;
this.debugWorkflow.WorkflowData = this.editor.writeGraphModel(null);
this.debugStack.push(this.debugWorkflow);
this.updateToolbarStatus();
this.onDebugStepChanged();
});
}
/**
* Open the workflow load dialog
* @method openLoadDialog
*/
openLoadDialog() {
let content = $('<div></div>');
let areaFilter = "";
let moduleFilter = "";
let workflowFilter = "";
let loadTemplate = `
<div class="col-12" style="position:relative">
<label class="control-label ">${flexygo.localization.translate('flxgipe.labelarea')}</label>
<flx-dbcombo name="areaId" ObjectName="sysWorkflow" ViewName="areasView" SQLValueField="WorkflowAreaId" SQLDisplayField="Descrip" placeholder="${flexygo.localization.translate('flxgipe.workflowareaplaceholder')}"/>
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelmodule')}</label>
<flx-dbcombo name="moduleId" ObjectName="sysWorkflow" ViewName="modulesView" SQLValueField="WorkflowModuleId" SQLDisplayField="Descrip" placeholder="${flexygo.localization.translate('flxgipe.workflowmoduleplaceholder')}"/>
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelname')}</label>
<flx-dbcombo name="workflowid" ObjectName="sysWorkflow" ViewName="defaultWorkflowView" SQLValueField="WorkflowId" SQLDisplayField="Descrip" placeholder="${flexygo.localization.translate('flxgipe.workflownameplaceholder')}"/>
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelversion')}</label>
<flx-dbcombo name="version" ObjectName="sysWorkflow" ViewName="versionsView" SQLValueField="Version" SQLDisplayField="Descrip" additionalWhere ="1=0" placeholder="${flexygo.localization.translate('flxgipe.workflowversionplaceholder')}"/>
</div>
<div class="fgWindowToolbar">
<button class="btn btn-sm bg-info loadButton"><i class="flx-icon icon-load"></i>${flexygo.localization.translate('flxgipe.buttonload')}</button>
<button class="btn btn-sm bg-danger closeButton"><i class="flx-icon icon-remove"></i>${flexygo.localization.translate('flxgipe.buttoncancel')}</button>
</div>
`;
content.append(loadTemplate);
let cboArea = content.find('flx-dbcombo[name="areaId"]')[0];
let cboModule = content.find('flx-dbcombo[name="moduleId"]')[0];
let cboWorkflow = content.find('flx-dbcombo[name="workflowid"]')[0];
let cboVersion = content.find('flx-dbcombo[name="version"]')[0];
$(cboArea).on('change', (e) => {
let val = cboArea.getValue();
if (val && val.length > 0) {
areaFilter = "areaId='" + val + "'";
}
else {
areaFilter = "";
}
cboWorkflow.additionalWhere = this.concatWhere(areaFilter, moduleFilter);
cboWorkflow.setValue("");
cboWorkflow.refresh();
});
$(cboModule).on('change', (e) => {
let val = cboModule.getValue();
if (val && val.length > 0) {
moduleFilter = "moduleId='" + val + "'";
}
else {
moduleFilter = "";
}
cboWorkflow.additionalWhere = this.concatWhere(areaFilter, moduleFilter);
cboWorkflow.setValue("");
cboWorkflow.refresh();
});
$(cboWorkflow).on('change', (e) => {
let val = e.currentTarget.getValue();
if (val && val.length > 0) {
workflowFilter = "workflowId='" + val + "'";
}
else {
workflowFilter = "";
}
cboVersion.additionalWhere = workflowFilter;
cboVersion.refresh();
flexygo.ajax.post('~/api/Gipe', 'getActiveVersion', { workflowId: val }, (ret) => {
if (ret && ret.length > 0) {
cboVersion.setValue(ret);
}
});
});
let wnd = new mxWindow(flexygo.localization.translate('flxgipe.dialogloadtitle'), content[0], (window.outerWidth / 2) - 150, (window.outerHeight / 2) - 200, 300, 400, false, true, null, "fgWindow");
wnd.setMaximizable(false);
wnd.setScrollable(true);
wnd.setResizable(false);
wnd.setClosable(true);
wnd.setVisible(true);
content.find("button.loadButton").on("click", (e) => {
let id = cboWorkflow.getValue();
if (!id) {
flexygo.msg.error(flexygo.localization.translate('flxgipe.errornoworkflowselected'), null, flexygo.localization.translate('flxgipe.dialogloadtitle'));
}
else {
let ver = cboVersion.getValue();
if ((!ver) || (ver && ver.length === 0)) {
flexygo.msg.error(flexygo.localization.translate('flxgipe.errornoversionselected'), null, flexygo.localization.translate('flxgipe.dialogloadtitle'));
}
else {
this.workflowStack = [];
this.loadWorkflow(id, parseInt(ver));
wnd.destroy();
}
}
});
content.find("button.closeButton").on("click", (e) => {
wnd.destroy();
});
wnd.addListener(mxEvent.DESTROY, (sender, object) => {
this.destroyDialog();
});
this.showDialog(wnd);
}
/**
* Sets a window as the current dialog
* @method showDialog
*/
showDialog(window) {
this.dialog = window;
this.updateToolbarStatus();
}
/**
* Sets a window as the current properties dialog
* @method showPropertiesDialog
*/
showPropertiesDialog(window) {
this.propertiesDialog = window;
this.updateToolbarStatus();
}
/**
* Sets a window as the current debug dialog
* @method showDebugDialog
*/
showDebugDialog(window) {
this.debugDialog = window;
this.updateToolbarStatus();
}
/**
* Set nothing as the current dialog
* @method destroyDialog
*/
destroyDialog() {
this.dialog = null;
this.updateToolbarStatus();
}
/**
* Set nothing as the current properties dialog
* @method destroyPropertiesDialog
*/
destroyPropertiesDialog() {
this.propertiesDialog = null;
this.updateToolbarStatus();
}
/**
* Set nothing as the current debug dialog
* @method destroyPropertiesDialog
*/
destroyDebugDialog() {
this.debugDialog = null;
this.updateToolbarStatus();
}
/**
* Loads and display a saved workflow
* @method loadWorkflow
*/
loadWorkflow(id, version, pushCurrent) {
let params = {
workflowId: id,
version: version
};
flexygo.ajax.post('~/api/Gipe', 'loadWorkflow', params, (ret) => {
if (ret) {
if (pushCurrent === true) {
this.workflowStack.push(this.workflow);
}
this.workflow = ret;
this.render();
}
});
}
/**
* Loads and display a saved workflow in debug mode
* @method loadWorkflow
*/
loadDebugWorkflow(id, version, newExecutionId, debugInfo) {
let stackIndex = -1;
this.debugStack.forEach((w, i) => {
if (w.ExecutionId === newExecutionId) {
stackIndex = i;
return false;
}
});
//Store current graphic
let currentIndex = -1;
this.debugStack.forEach((w, i) => {
if (w.ExecutionId === this.debugWorkflow.ExecutionId) {
currentIndex = i;
return false;
}
});
if (currentIndex === -1) {
flexygo.msg.error('Current workflow not found on debug stack');
return;
}
else {
//Save current graphic
this.debugStack[currentIndex].WorkflowData = this.editor.writeGraphModel(null);
}
if (stackIndex === -1) {
let params = {
workflowId: id,
version: version
};
flexygo.ajax.syncPost('~/api/Gipe', 'loadWorkflow', params, (ret) => {
this.debugWorkflow = ret;
this.debugWorkflow.ExecutionId = newExecutionId;
this.debugStack.push(this.debugWorkflow);
});
}
else {
this.debugWorkflow = this.debugStack[stackIndex];
}
this.render();
this.updateDebugInfo(debugInfo);
}
/**
* Open the workflow save dialog
* @method openSaveDialog
*/
openSaveDialog() {
let content = $('<div></div>');
let current = (this.workflow) ? this.workflow : { WorkflowId: '', ModuleId: '', AreaId: '', Descrip: 'New workflow', Version: 1, WorkflowData: null, Active: true, Versions: [] };
let saveTemplate = `
<div class="col-12" style="position:relative">
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelarea')}</label>
<flx-dbcombo name="dbc-areaid" value="${current.AreaId}" ObjectName="sysWorkflow" ViewName="areasView" SQLValueField="WorkflowAreaId" SQLDisplayField="Descrip" placeholder="${flexygo.localization.translate('flxgipe.workflowareaplaceholder')}"/>
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelmodule')}</label>
<flx-dbcombo name="dbc-moduleid" value="${current.ModuleId}" ObjectName="sysWorkflow" ViewName="modulesView" SQLValueField="WorkflowModuleId" SQLDisplayField="Descrip" placeholder="${flexygo.localization.translate('flxgipe.workflowmoduleplaceholder')}"/>
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelname')}</label>
<flx-text name="dbc-wfid" value="${current.WorkflowId}" ${(current.WorkflowId.length > 0) ? 'disabled="true"' : ''}/>
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labeldescrip')}</label>
<flx-text name="dbc-wfdescrip" value="${this.htmlEncode(current.Descrip)}" placeholder="${flexygo.localization.translate('flxgipe.workflownameplaceholder')}" />
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelactive')}</label>
<flx-check name="dbc-wfactive" ${(current.Active && current.Active === true) ? 'checked' : ''}></flx-check>
</div>
<div class="fgWindowToolbar">
<button class="btn btn-sm bg-info saveButton"><i class="flx-icon icon-save"></i>${flexygo.localization.translate('flxgipe.buttonsave')}</button>
<button class="btn btn-sm bg-danger closeButton"><i class="flx-icon icon-remove"></i>${flexygo.localization.translate('flxgipe.buttoncancel')}</button>
</div>
`;
content.append(saveTemplate);
let wnd = new mxWindow(flexygo.localization.translate('flxgipe.dialogsavetitle'), content[0], (window.outerWidth / 2) - 150, (window.outerHeight / 2) - 200, 300, 400, false, true, null, "fgWindow");
wnd.setMaximizable(false);
wnd.setScrollable(true);
wnd.setResizable(false);
wnd.setClosable(true);
wnd.setVisible(true);
content.find("button.saveButton").on("click", (e) => {
current.WorkflowId = content.find('[name="dbc-wfid"]')[0].getValue();
current.Descrip = content.find('[name="dbc-wfdescrip"]')[0].getValue();
current.ModuleId = content.find('[name="dbc-moduleid"]')[0].getValue();
current.AreaId = content.find('[name="dbc-areaid"]')[0].getValue();
current.Active = content.find('[name="dbc-wfactive"]')[0].getValue();
let wf = this.editor.graph.getModel().cells[0].value;
wf.setAttribute("fgid", current.WorkflowId);
wf.setAttribute("description", current.Descrip);
current.WorkflowData = this.editor.writeGraphModel(null);
flexygo.ajax.post('~/api/Gipe', 'saveWorkflow', current, (ret) => {
if (ret) {
flexygo.msg.success(flexygo.localization.translate('flxgipe.messages.workflowsaved'));
wnd.destroy();
this.workflow = ret;
this.render();
}
});
});
content.find("button.closeButton").on("click", (e) => {
wnd.destroy();
});
wnd.addListener(mxEvent.DESTROY, (sender, object) => {
this.destroyDialog();
});
this.showDialog(wnd);
}
/**
* Clears the workflow and edit new workflow
* @method newWorkflow
*/
newWorkflow() {
this.workflow = null;
this.workflowStack = [];
this.debugStack = [];
this.render();
}
/**
* Generates the workflow
* @method generateWorkflow
*/
generateWorkflow() {
if (!(this.workflow && this.workflow.WorkflowId && this.workflow.WorkflowId.length > 0)) {
flexygo.msg.error(flexygo.localization.translate('flxgipe.messages.savefirst'));
return;
}
flexygo.ajax.post('~/api/Gipe', 'generateWorkflow', { workflowId: this.workflow.WorkflowId, Version: this.workflow.Version }, (ret) => {
if (ret && ret === true) {
flexygo.msg.success(flexygo.localization.translate('flxgipe.messages.workflowgenerated'));
}
});
}
/**
* Open the templates dialog
* @method openTemplateDialog
*/
openTemplateDialog() {
let filterContent = $('<tr></tr>');
let listContent = $('<div></div>');
this.templateFilter = {
name: '',
areaId: null,
originId: null,
objects: true,
processes: true,
decissions: true,
workflows: true,
events: true
};
let filterTemplae = `
<div id="GipeTemplateDialogPanel" class="col-12">
<div class="templateFilterPanel" style="position:relative">
<flx-dbcombo id="gcp-tf-cbo-area" ObjectName="sysWorkflow" ViewName="areasView" SQLValueField="WorkflowAreaId" SQLDisplayField="Descrip" placeholder="${flexygo.localization.translate('flxgipe.workflowareaplaceholder')}"/>
<flx-dbcombo id="gcp-tf-cbo-origin" ObjectName="sysWorkflow" ViewName="originsView" SQLValueField="OriginId" SQLDisplayField="Descrip" placeholder="${flexygo.localization.translate('flxgipe.workfloworiginplaceholder')}"/>
<div class="col-12 templateFilterPanelButtons">
<button id="gcp-tf-btn-object" type="button" title="${flexygo.localization.translate('flxgipe.editortemplates.object')}" class="btn btn-lg active" aria-pressed="true" data-toggle="button">
<i class="flx-icon icon-object"></i>
</button>
<button id="gcp-tf-btn-process" type="button" title="${flexygo.localization.translate('flxgipe.editortemplates.process')}" class="btn btn-lg active" aria-pressed="true" data-toggle="button">
<i class="flx-icon icon-process"></i>
</button>
<button id="gcp-tf-btn-decission" type="button" title="${flexygo.localization.translate('flxgipe.editortemplates.decission')}" class="btn btn-lg active" aria-pressed="true" data-toggle="button">
<i class="flx-icon icon-expand"></i>
</button>
<button id="gcp-tf-btn-workflow" type="button" title="${flexygo.localization.translate('flxgipe.editortemplates.workflow')}" class="btn btn-lg active" aria-pressed="true" data-toggle="button">
<i class="flx-icon icon-flow-chart"></i>
</button>
<button id="gcp-tf-btn-event" type="button" title="${flexygo.localization.translate('flxgipe.editortemplates.event')}" class="btn btn-lg active" aria-pressed="true" data-toggle="button">
<i class="flx-icon icon-wifi"></i>
</button>
<button id="gcp-tf-btn-all" type="button" title="${flexygo.localization.translate('flxgipe.editortemplates.toggleall')}" class="btn btn-lg active" aria-pressed="true" data-toggle="button">
<i class="flx-icon icon-select"></i>
</button>
</div>
<flx-text id="gcp-tf-txt-name" class="searchInput" placeholder="${flexygo.localization.translate('flxgipe.searchtemplates')}" iconclass="flx-icon icon-search" />
</div>
</div>`;
let contentTemplate = `
<div style="clear:both">
</div>
<div id="GipeTemplateList">
<ul class="connectedSortable">
</ul>
</div>
`;
filterContent.append(filterTemplae);
listContent.append(contentTemplate);
filterContent.find('#gcp-tf-cbo-area').off('change').on('change', (e) => {
let cbo = $(e.currentTarget);
this.templateFilter.areaId = (cbo.val() && cbo.val().length > 0) ? cbo.val() : null;
this.updateTemplateFilter();
});
filterContent.find('#gcp-tf-cbo-origin').off('change').on('change', (e) => {
let cbo = $(e.currentTarget);
this.templateFilter.originId = (cbo.val() && cbo.val().length > 0) ? parseInt(cbo.val()) : null;
this.updateTemplateFilter();
});
filterContent.find('#gcp-tf-txt-name').off('keyup').on('keyup', (e) => {
this.templateFilter.name = $(e.currentTarget).val();
this.updateTemplateFilter();
});
filterContent.find('#gcp-tf-btn-object').off('click').on('click', (e) => {
this.templateFilter.objects = !this.templateFilter.objects;
this.updateTemplateFilter();
});
filterContent.find('#gcp-tf-btn-process').off('click').on('click', (e) => {
this.templateFilter.processes = !this.templateFilter.processes;
this.updateTemplateFilter();
});
filterContent.find('#gcp-tf-btn-decission').off('click').on('click', (e) => {
this.templateFilter.decissions = !this.templateFilter.decissions;
this.updateTemplateFilter();
});
filterContent.find('#gcp-tf-btn-workflow').off('click').on('click', (e) => {
this.templateFilter.workflows = !this.templateFilter.workflows;
this.updateTemplateFilter();
});
filterContent.find('#gcp-tf-btn-event').off('click').on('click', (e) => {
this.templateFilter.events = !this.templateFilter.events;
this.updateTemplateFilter();
});
filterContent.find('#gcp-tf-btn-all').off('click').on('click', (e) => {
let setted = !($(e.currentTarget).attr('aria-pressed') === 'true');
if ($('#gcp-tf-btn-object').hasClass('active') !== setted)
$('#gcp-tf-btn-object').button('toggle');
if ($('#gcp-tf-btn-process').hasClass('active') !== setted)
$('#gcp-tf-btn-process').button('toggle');
if ($('#gcp-tf-btn-decission').hasClass('active') !== setted)
$('#gcp-tf-btn-decission').button('toggle');
if ($('#gcp-tf-btn-workflow').hasClass('active') !== setted)
$('#gcp-tf-btn-workflow').button('toggle');
if ($('#gcp-tf-btn-event').hasClass('active') !== setted)
$('#gcp-tf-btn-event').button('toggle');
this.templateFilter.objects = setted;
this.templateFilter.processes = setted;
this.templateFilter.decissions = setted;
this.templateFilter.workflows = setted;
this.templateFilter.events = setted;
this.updateTemplateFilter();
});
let wnd = new mxWindow(flexygo.localization.translate('flxgipe.dialogtemplatetitle'), listContent[0], (window.outerWidth / 2) - 150, (window.outerHeight / 2) - 200, 300, 400, false, true, null, "fgWindow");
let titleRow = $(wnd.title).parent();
titleRow.after(filterContent);
let list = listContent.find('#GipeTemplateList ul');
flexygo.ajax.post('~/api/Gipe', 'getTemplates', null, (ret) => {
ret.forEach((e) => {
list.append(`
<li data-type="${e.NodeType}" data-id="${e.NodeKey}" data-descrip="${e.NodeDescrip}" data-originid="${e.NodeOriginId}" data-areas="${e.NodeAreas}" class="templateItem nolist">
<div class="box-primary">
<div class="listDescrip">
<i title="${e.NodeDescrip}" class="${e.NodeIcon} icon-lg"></i>
<span class="modDesc">${e.NodeDescrip}</span>
</div>
</div>
</li>
`);
});
list.find('li').draggable({
appendTo: 'body',
containment: $('#gipegraph'),
helper: 'clone'
});
});
wnd.setMaximizable(false);
wnd.setScrollable(true);
wnd.setResizable(true);
wnd.setClosable(true);
wnd.setVisible(true);
wnd.addListener(mxEvent.DESTROY, (sender, object) => {
this.destroyDialog();
});
this.showDialog(wnd);
}
updateTemplateFilter() {
let content = $(document).find('#GipeTemplateList');
content.find('li[data-descrip]').hide();
let filter = this.templateFilter;
console.log("updateTemplateFilter", filter);
let filterTypes = '';
if (filter.objects === true)
filterTypes += '1';
if (filter.processes === true)
filterTypes += '2';
if (filter.decissions === true)
filterTypes += '3';
if (filter.workflows === true)
filterTypes += '4';
if (filter.events === true)
filterTypes += '5';
let filterName = (filter.name || '').toLowerCase();
let filterArea = (filter.areaId || '').toLowerCase();
let elems = content.find('li[data-descrip]').filter(function () {
let e = $(this);
let visible = true;
if (filterName.length > 0) {
visible = e.attr('data-descrip').toLowerCase().indexOf(filterName) !== -1;
}
if (visible === true) {
visible = filterTypes.indexOf(e.attr('data-type')) !== -1;
if (visible === true) {
if (filter.originId !== null) {
visible = (parseInt(e.attr('data-originid')) === filter.originId);
}
if (visible === true) {
if (filterArea.length > 0) {
visible = (e.attr('data-areas').toLowerCase() == filterArea);
}
}
}
}
return visible;
});
elems.show();
}
onModuleResize(e) {
let module = e.sender;
let mine = $(this).closest('flx-module')[0];
if (module.moduleName === mine.moduleName) {
this.setGraphSize();
}
}
/**
* Open the workflow debug dialog
* @method openDebugDialog
*/
openDebugDialog() {
let content = $('<div></div>');
let debugTemplate = `
<div class="gipetoolbar" id="gipedebugtoolbar">
<button name="dbg-stepinto"><i class="fa fa-step-forward" /></button>
<button name="dbg-stepover"><i class="fa fa-fast-forward" /></button>
<button name="dbg-stop"><i class="fa fa-stop" /></button>
</div>
<div class="col-12">
<div class="col-6">
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelstatus')}</label>
<flx-text id="gipedbg-status"/>
</div>
<div class="col-6">
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelresult')}</label>
<flx-text id="gipedbg-result"/>
</div>
</div>
<div class="col-12">
<div id="gipe-debug-tree" />
</div>
`;
content.append(debugTemplate);
let wnd = new mxWindow(flexygo.localization.translate('flxgipe.dialogdebugtitle'), content[0], (window.outerWidth / 2) - 150, (window.outerHeight / 2) - 200, 300, 400, false, true, null, "fgWindow");
wnd.setMaximizable(false);
wnd.setScrollable(true);
wnd.setResizable(true);
wnd.setClosable(true);
wnd.setVisible(true);
content.find('button[name="dbg-stepinto"]').on("click", (e) => {
if (this.currentExecutionId === 0) {
flexygo.msg.error(flexygo.localization.translate('flxgipe.errornocurrentexecution'));
return;
}
content.find('button[name="dbg-stepinto"]').prop('disabled', true);
content.find('button[name="dbg-stepover"]').prop('disabled', true);
//Execute one step
flexygo.ajax.post('~/api/Gipe', 'debugWorkflow', { workflowId: this.workflow.WorkflowId, version: this.workflow.Version, executionId: this.currentExecutionId, stepOver: false }, (ret) => {
});
});
content.find('button[name="dbg-stepover"]').on("click", (e) => {
if (this.currentExecutionId === 0) {
flexygo.msg.error(flexygo.localization.translate('flxgipe.errornocurrentexecution'));
return;
}
content.find('button[name="dbg-stepinto"]').prop('disabled', true);
content.find('button[name="dbg-stepover"]').prop('disabled', true);
//Execute one step
flexygo.ajax.post('~/api/Gipe', 'debugWorkflow', { workflowId: this.workflow.WorkflowId, version: this.workflow.Version, executionId: this.currentExecutionId, stepOver: true }, (ret) => {
});
});
content.find('button[name="dbg-stop"]').on("click", (e) => {
if (this.currentExecutionId !== 0) {
var postParams = {
execId: this.currentExecutionId,
stepId: 0
};
flexygo.ajax.post('~/api/Gipe', 'abortExecution', postParams, (ret) => { });
//this.lastDebugGraphId = 0;
//this.currentExecutionId = 0;
//this.updateToolbarStatus();
}
});
wnd.addListener(mxEvent.DESTROY, (sender, object) => {
this.destroyDebugDialog();
if (this.currentExecutionId !== 0) {
var postParams = {
execId: this.currentExecutionId,
stepId: 0
};
flexygo.ajax.post('~/api/Gipe', 'abortExecution', postParams, (ret) => { });
this.lastDebugGraphId = null;
this.currentExecutionId = 0;
this.debugStack = [];
this.updateToolbarStatus();
}
this.loadWorkflow(this.workflow.WorkflowId, this.workflow.Version, false);
});
this.showDebugDialog(wnd);
}
/**
* Render HTML data.
* @method render
*/
render() {
let empty = `<mxGraphModel>
<root>
<Workflow label="" description="" id="0"/>
<Layer label="Default Layer">
<mxCell parent="0"/>
</Layer>
</root>
</mxGraphModel>
`;
let node = null;
let error = "";
let current = null;
if (this.currentExecutionId === 0) {
current = this.workflow;
}
else {
current = this.debugWorkflow;
}
if (current && current !== null) {
node = mxUtils.parseXml(current.WorkflowData);
if (node.getElementsByTagName("parsererror").length > 0) {
error = node.getElementsByTagName("parsererror")[0].innerText;
node = mxUtils.parseXml(empty);
}
}
else {
node = mxUtils.parseXml(empty);
}
let doc = node.documentElement;
this.editor.readGraphModel(doc);
this.updateToolbarStatus();
this.updateModuleTitle();
this.updateBreadcrumb();
this.updateComboVersions();
if (error.length > 0) {
flexygo.msg.error(error);
}
}
/**
* Updates toolbar status.
* @method render
*/
updateToolbarStatus() {
let canAny;
let canGoDown;
let canGoUp;
let selected = this.editor.graph.getSelectionCells();
canAny = !(this.dialog !== null);
if (canAny === true) {
canAny = (this.currentExecutionId === 0);
}
if (canAny) {
$(this).find('button.mxToolbarItem').prop('disabled', false);
if (selected.length === 0) {
canGoDown = false;
}
else if (selected.length > 1) {
canGoDown = false;
}
else {
let cell = selected[0];
if (cell.value && cell.value.localName === 'Workflow') {
canGoDown = true;
}
else {
canGoDown = false;
}
}
canGoUp = (this.workflowStack.length > 0);
let btnUp = $(this).find('button[data-action="up"]');
let btnDown = $(this).find('button[data-action="down"]');
btnUp.prop("disabled", !canGoUp);
btnDown.prop("disabled", !canGoDown);
}
else {
$(this).find('button.mxToolbarItem').prop('disabled', true);
}
}
openPropertiesDialog() {
let content = $('<div></div>');
let wnd = new mxWindow(flexygo.localization.translate('flxgipe.dialogpropertiestitle'), content[0], (window.outerWidth / 2) - 150, (window.outerHeight / 2) - 200, 500, 400, false, true, null, "fgWindow");
wnd.setMaximizable(false);
wnd.setScrollable(true);
wnd.setResizable(true);
wnd.setClosable(true);
wnd.setVisible(true);
wnd.addListener(mxEvent.DESTROY, (sender, object) => {
this.destroyPropertiesDialog();
});
this.showPropertiesDialog(wnd);
}
showCellProperties(cell) {
if (!this.propertiesDialog) {
this.openPropertiesDialog();
}
if (!cell) {
this.showWorkflowProperties();
return;
}
if (cell && cell.isEdge() === true) {
this.showRelationProperties(cell);
return;
}
let content = $(this.propertiesDialog.content);
content.empty();
let cboParams = null;
switch (cell.value.localName.toLowerCase()) {
case 'process':
cboParams = {
Label: flexygo.localization.translate("flxgipe.labelprocess"),
ObjectName: "sysWorkflow",
ViewName: "processesView",
SQLValueField: "ProcessName",
SQLDisplayField: "ProcessName"
};
break;
case 'object':
cboParams = {
Label: flexygo.localization.translate("flxgipe.labelobject"),
ObjectName: "sysWorkflow",
ViewName: "objectsView",
SQLValueField: "ObjectName",
SQLDisplayField: "ObjectName"
};
break;
case 'decission':
cboParams = {
Label: flexygo.localization.translate("flxgipe.labeldecission"),
ObjectName: "sysWorkflow",
ViewName: "decissionsView",
SQLValueField: "ProcessName",
SQLDisplayField: "ProcessName"
};
break;
case 'workflow':
cboParams = {
Label: flexygo.localization.translate("flxgipe.labelworkflow"),
ObjectName: "sysWorkflow",
ViewName: "workflowsView",
SQLValueField: "ProcessName",
SQLDisplayField: "ProcessName"
};
break;
case 'event':
cboParams = {
Label: flexygo.localization.translate("flxgipe.labelevent"),
ObjectName: "sysWorkflow",
ViewName: "eventsView",
SQLValueField: "NodeKey",
SQLDisplayField: "NodeDescrip"
};
break;
case 'label':
cboParams = {
Label: flexygo.localization.translate("flxgipe.labellabel"),
ObjectName: "sysWorkflow",
ViewName: "labelsView",
SQLValueField: "LabelName",
SQLDisplayField: "LabelDescrip",
backgroundColor: "",
textColor: "",
borderColor: "",
};
let style = cell.style;
if (style.indexOf(';') != -1) {
let styles = style.split(';');
for (let i = 0; i < styles.length; i++) {
if (styles[i].indexOf('=') != -1) {
let key = styles[i].split('=')[0];
let value = styles[i].split('=')[1];
switch (key) {
case mxConstants.STYLE_FILLCOLOR:
cboParams['backgroundColor'] = value;
break;
case mxConstants.STYLE_FONTCOLOR:
cboParams['textColor'] = value;
break;
case mxConstants.STYLE_STROKECOLOR:
cboParams['borderColor'] = value;
break;
}
}
}
}
break;
default:
flexygo.msg.error('Invalid value');
return;
}
let propTemplate = `
<div class="col-12">
<div class="col-6">
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelleft')}</label>
<flx-text name="x" type="number" value="${cell.geometry.x}"/>
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelwidth')}</label>
<flx-text name="w" type="number" value="${cell.geometry.width}"/>
</div>
<div class="col-6">
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labeltop')}</label>
<flx-text name="y" type="number" value="${cell.geometry.y}"/>
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelheight')}</label>
<flx-text name="h" type="number" value="${cell.geometry.height}"/>
</div>
</div>
<div class="col-12" style="position:relative">
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labellabel')}</label>
<flx-text name="l" value="${this.htmlEncode(cell.value.getAttribute('label'))}"/>
${(cell.value.localName.toLowerCase() != 'label') ? `
<label class="control-label fgWindowLabel">${cboParams.Label}</label>
<flx-dbcombo name="fgid" ObjectName="${cboParams.ObjectName}" ViewName="${cboParams.ViewName}" SQLDisplayField="${cboParams.SQLDisplayField}" SQLValueField="${cboParams.SQLValueField}" value="${cell.value.getAttribute('fgid')}" />
` : `
<div class="col-6">
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelbackgroundcolor')}</label>
<flx-text name="backgroundColor" type="text" value="${cboParams.backgroundColor}"/>
</div>
<div class="col-6">
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelbordercolor')}</label>
<flx-text name="borderColor" type="text" value="${cboParams.borderColor}"/>
</div>
<div class="col-6">
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labeltextcolor')}</label>
<flx-text name="textColor" type="text" value="${cboParams.textColor}"/>
</div>
`}
</div>
<div class="fgWindowToolbar">
<button class="btn btn-sm bg-info saveButton"><i class="flx-icon icon-save"></i>${flexygo.localization.translate('flxgipe.buttonsave')}</button>
<button class="btn btn-sm bg-danger closeButton"><i class="flx-icon icon-remove"></i>${flexygo.localization.translate('flxgipe.buttoncancel')}</button>
</div>
`;
content.append(propTemplate);
content.find("button.closeButton").off("click").on("click", (e) => {
if (this.fixedPropertiesDialog === false) {
this.propertiesDialog.destroy();
}
});
content.find("button.saveButton").off("click").on("click", (e) => {
let xField = content.find('flx-text[name="x"]')[0];
let yField = content.find('flx-text[name="y"]')[0];
let wField = content.find('flx-text[name="w"]')[0];
let hField = content.find('flx-text[name="h"]')[0];
let textColor = content.find('flx-text[name="textColor"]')[0];
let borderColor = content.find('flx-text[name="borderColor"]')[0];
let backgroundColor = content.find('flx-text[name="backgroundColor"]')[0];
let lblField = content.find('flx-text[name="l"]')[0];
let idField = content.find('flx-dbcombo[name="fgid"]')[0];
// Supports undo for the changes on the underlying
// XML structure / XML node attribute changes.
let graph = this.editor.graph;
let model = graph.getModel();
let geo = cell.geometry;
let style = "";
var attrs = [];
var texts = [];
attrs.push('label');
attrs.push('description');
attrs.push('fgid');
let fgid = (idField ? idField.getValue() : null);
texts.push(lblField.getValue());
texts.push(cell.value.getAttribute('description'));
texts.push(fgid);
let okid = (fgid && fgid.length > 0);
switch (cell.value.localName.toLowerCase()) {
case 'process':
style = (okid) ? 'process' : 'invalid-process';
break;
case 'object':
style = (okid) ? 'ellipse' : 'invalid-ellipse';
break;
case 'decission':
style = (okid) ? 'rhombus' : 'invalid-rhombus';
break;
case 'workflow':
style = (okid) ? 'hexagon' : 'invalid-hexagon';
break;
case 'event':
style = (okid) ? 'cloud' : 'invalid-cloud';
break;
case 'label':
style = 'label';
if (textColor.getValue()) {
style += ';' + mxConstants.STYLE_FONTCOLOR + '=' + textColor.getValue();
}
if (backgroundColor.getValue()) {
style += ';' + mxConstants.STYLE_FILLCOLOR + '=' + backgroundColor.getValue();
}
if (borderColor.getValue()) {
style += ';' + mxConstants.STYLE_STROKECOLOR + '=' + borderColor.getValue();
}
break;
default:
flexygo.msg.error('Invalid value');
return;
}
model.beginUpdate();
try {
if (geo != null) {
geo = geo.clone();
geo.x = parseFloat(xField.getValue());
geo.y = parseFloat(yField.getValue());
geo.width = parseFloat(wField.getValue());
geo.height = parseFloat(hField.getValue());
model.setGeometry(cell, geo);
}
// Applies the style
if (style.length > 0) {
model.setStyle(cell, style);
}
else {
model.setStyle(cell, null);
}
// Creates an undoable change for each
// attribute and executes it using the
// model, which will also make the change
// part of the current transaction
for (var i = 0; i < attrs.length; i++) {
var edit = new mxCellAttributeChange(cell, attrs[i], texts[i]);
model.execute(edit);
}
// Checks if the graph wants cells to
// be automatically sized and updates
// the size as an undoable step if
// the feature is enabled
if (graph.isAutoSizeCell(cell)) {
graph.updateCellSize(cell);
}
}
finally {
model.endUpdate();
}
if (!this.fixedPropertiesDialog) {
this.propertiesDialog.destroy();
}
});
}
showRelationProperties(cell) {
if (!this.propertiesDialog) {
this.openPropertiesDialog();
}
let content = $(this.propertiesDialog.content);
content.empty();
if (typeof cell.value === "string") {
return;
}
let targetCell = cell.target;
let model = this.editor.graph.getModel();
let currentWorkflow = this.workflow;
let propTemplate = `
<div class="col-12">
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labellabel')}</label>
<flx-text name="l" value="${this.htmlEncode(cell.value.getAttribute('label'))}"/>
</div>
<div name="parameters" class="col-12">
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelrelations')}</label>
</div>
<div name="gipeprops" class="col-12">
</div>
<div class="fgWindowToolbar">
<button class="btn btn-sm bg-info saveButton"><i class="flx-icon icon-save"></i>${flexygo.localization.translate('flxgipe.buttonsave')}</button>
<button class="btn btn-sm bg-danger closeButton"><i class="flx-icon icon-remove"></i>${flexygo.localization.translate('flxgipe.buttoncancel')}</button>
</div>
`;
content.append(propTemplate);
content.find("button.closeButton").off("click").on("click", (e) => {
if (this.fixedPropertiesDialog === false) {
this.propertiesDialog.destroy();
}
});
content.find("button.saveButton").off("click").on("click", (e) => {
let lblField = content.find('flx-text[name="l"]')[0];
let graph = this.editor.graph;
let model = graph.getModel();
let value = this.editor.templates["relation"].value.cloneNode(true);
content.find('label[data-name="propname"]').each((i, e) => {
let lblProp = $(e);
let prop = lblProp.attr('data-prop');
let cboType = lblProp.parent().find(`select[data-name="parenttype"][data-prop="${prop}"]`);
let cboParent = lblProp.parent().find(`select[data-name="parentname"][data-prop="${prop}"]`);
let cboParam = lblProp.parent().find(`select[data-name="paramname"][data-prop="${prop}"]`);
let txtValue = cboType.parent().find(`input[data-name="txtvalue"][data-prop="${prop}"]`);
let type = cboType.val();
let parent = cboParent.val();
let param = cboParam.val();
let defaultvalue = txtValue.val();
if (type && type.length > 0) {
if (parent && parent.length > 0) {
parent = `parent="${parent}"`;
}
else {
parent = "";
}
if (param && param.length > 0) {
param = `parentparam="${param}"`;
}
else {
param = "";
}
if (defaultvalue && defaultvalue.length > 0) {
parent = `parent="0"`;
defaultvalue = `defaultvalue="${defaultvalue}"`;
}
else {
defaultvalue = "";
}
let s = `<Parameter childparam="${prop}" type="${type}" ${parent} ${param} ${defaultvalue}></Parameter>`;
let r = mxUtils.parseXml(s);
value.appendChild(r.documentElement);
}
});
model.beginUpdate();
try {
cell.setValue(value);
// Creates an undoable change for each
// attribute and executes it using the
// model, which will also make the change
// part of the current transaction
var edit = new mxCellAttributeChange(cell, 'label', lblField.getValue());
model.execute(edit);
}
finally {
model.endUpdate();
}
if (!this.fixedPropertiesDialog) {
this.propertiesDialog.destroy();
}
});
flexygo.ajax.post('~/api/Gipe', 'getNodeRelations', { nodeType: targetCell.value.nodeName, nodeName: targetCell.value.getAttribute("fgid") }, (ret) => {
let parameters = cell.value.getElementsByTagName('Parameter');
let divProps = content.find('div[name="gipeprops"]');
ret.forEach((param) => {
let parentvalue = "";
let parentdescrip = "";
let typevalue = "";
let paramvalue = "";
let defaultvalue = "";
$.each(parameters, (i, n) => {
if (n.getAttribute('childparam').toLowerCase() === param.ParamName.toLowerCase()) {
typevalue = n.getAttribute('type');
if (n.hasAttribute('parent')) {
parentvalue = model.getCell(n.getAttribute('parent')).id;
if (typevalue && typevalue == 'workflow') {
parentdescrip = currentWorkflow.WorkflowId;
}
else {
parentdescrip = model.getCell(n.getAttribute('parent')).value.getAttribute('label');
}
paramvalue = n.getAttribute('parentparam');
}
defaultvalue = n.getAttribute('defaultvalue') || '';
}
});
let inputVisibleStr = (defaultvalue && defaultvalue.length > 0) ? '' : 'style="display:none"';
let selectVisibleStr = (inputVisibleStr && inputVisibleStr.length > 0) ? '' : 'style="display:none"';
let prop = param.ParamName;
let template = `
<div class="col-12">
<label class="col-3" data-name="propname" data-prop="${prop}">${param.ParamLabel}</label>
<select class="col-3" data-name="parenttype" data-prop="${prop}"><option value=""/><option value="workflow">Workflow</option><option value="node">Node</option><option value="value">Default value</option><option value="context">Context</option></select>
<input ${inputVisibleStr} class="col-6" data-name="txtvalue" data-prop="${prop}"></input>
<select ${selectVisibleStr} class="col-3" data-name="parentname" data-prop="${prop}"></select>
<select ${selectVisibleStr} class="col-3" data-name="paramname" data-prop="${prop}"></select>
</div>`;
let parsed = $(template);
if (typevalue !== '') {
parsed.find('select[data-name="parenttype"]').val(typevalue);
}
if (parentvalue !== '') {
parsed.find('select[data-name="parentname"]').append(`<option value="${parentvalue}" selected>${parentdescrip}</option>`);
}
if (paramvalue !== '') {
parsed.find('select[data-name="paramname"]').append(`<option value="${paramvalue}" selected>${paramvalue}</option>`);
}
if (defaultvalue !== '') {
parsed.find('input[data-name="txtvalue"]').val(defaultvalue);
}
divProps.append(parsed);
});
divProps.find('select[data-name="parenttype"]').off('change').on('change', (e) => {
let cboType = $(e.currentTarget);
let prop = cboType.attr('data-prop');
let cboParent = cboType.parent().find(`select[data-name="parentname"][data-prop="${prop}"]`);
let cboParam = cboType.parent().find(`select[data-name="paramname"][data-prop="${prop}"]`);
let txtValue = cboType.parent().find(`input[data-name="txtvalue"][data-prop="${prop}"]`);
txtValue.hide();
cboParent.find('option').remove();
cboParam.find('option').remove();
let nodes = `<option value=""></option>`;
switch (cboType.val()) {
case 'node':
txtValue.hide();
txtValue.val('');
cboParent.show();
cboParam.show();
cboParent.prop('disabled', false);
for (let key in model.cells) {
let cell = model.cells[key];
if (cell.isVertex() && cell.value.tagName.toLowerCase() != 'label') {
nodes += `<option value="${cell.id}">${cell.value.getAttribute('label')}</option>`;
}
}
cboParent.append(nodes);
break;
case 'workflow':
txtValue.hide();
txtValue.val('');
cboParent.show();
cboParam.show();
cboParent.prop('disabled', true);
cboParent.append(`<option value="0" selected>${currentWorkflow.WorkflowId}</option>`);
cboParam.html();
flexygo.ajax.post('~/api/Gipe', 'getNodeRelations', { nodeType: 'workflow', nodeName: currentWorkflow.WorkflowId }, (ret) => {
ret.forEach((param) => {
nodes += `<option value="${param.ParamName}">${param.ParamLabel}</option>`;
});
cboParam.append(nodes);
});
break;
case 'context':
txtValue.hide();
txtValue.val('');
cboParent.hide();
cboParam.show();
cboParent.prop('disabled', true);
cboParam.html();
for (let key in flexygo.context) {
nodes += `<option value="key">${key}</option>`;
}
cboParam.append(nodes);
break;
case 'value':
txtValue.show();
cboParent.hide();
cboParent.val('');
cboParam.hide();
cboParam.html();
txtValue.val('');
}
});
divProps.find('select[data-name="parentname"]').off('change').on('change', (e) => {
let cboParent = $(e.currentTarget);
let prop = cboParent.attr('data-prop');
let cboType = cboParent.parent().find(`select[data-name="parenttype"][data-prop="${prop}"]`);
let cboParam = cboParent.parent().find(`select[data-name="paramname"][data-prop="${prop}"]`);
cboParam.find('option').remove();
let nodes = `<option value=""></option>`;
switch (cboType.val()) {
case 'node':
let cell = model.getCell(cboParent.val());
flexygo.ajax.post('~/api/Gipe', 'getNodeRelations', { nodeType: cell.value.localName, nodeName: cell.value.getAttribute('fgid') }, (ret) => {
ret.forEach((param) => {
nodes += `<option value="${param.ParamName}">${param.ParamLabel}</option>`;
});
cboParam.append(nodes);
});
break;
}
});
});
}
viewCell(cell) {
switch (cell.value.localName.toLowerCase()) {
case 'process':
case 'decission':
flexygo.nav.openPage('view', 'sysProcess', "processName='" + cell.value.getAttribute('fgid') + "'", null, 'popup1024x678');
return;
case 'object':
flexygo.nav.openPage('view', 'sysObject', "objectName='" + cell.value.getAttribute('fgid') + "'", null, 'popup1024x678');
return;
case 'workflow':
flexygo.nav.openPage('view', 'sysWorkflow', "workflowId='" + cell.value.getAttribute('fgid') + "' AND Active=1", null, 'popup1024x678');
return;
case 'event':
break;
case 'label':
break;
default:
flexygo.msg.error('Invalid value');
return;
}
}
listParamsCell(cell) {
switch (cell.value.localName.toLowerCase()) {
case 'process':
case 'decission':
case 'workflow':
flexygo.nav.openPage('list', 'sysProcessParams', "Processes_Params.ProcessName='" + cell.value.getAttribute('fgid') + "'", '{"ProcessName":"' + cell.value.getAttribute('fgid') + '"}', 'popup1024x678');
return;
case 'event':
case 'object':
case 'label':
break;
default:
flexygo.msg.error('Invalid value');
return;
}
}
newCell(cell) {
flexygo.events.off(this, "entity", "inserted");
this.popupCell = cell;
let desc = null;
if (cell && cell.value && cell.value.attributes && cell.value.attributes.label && cell.value.attributes.label.value) {
desc = cell.value.attributes.label.value;
}
switch (cell.value.localName.toLowerCase()) {
case 'process':
flexygo.nav.openPage('edit', 'sysProcess', '', { ProcessDescrip: desc }, 'popup');
flexygo.events.on(this, "entity", "inserted", this.onEntityInserted);
return;
case 'object':
flexygo.nav.openPageName('syspage-generic-objectwizard', 'sysObject', '', null, 'popup', false);
flexygo.events.on(this, "entity", "inserted", this.onEntityInserted);
return;
case 'decission':
flexygo.nav.openPage('edit', 'sysProcess', "", { "typeId": "12", ProcessDescrip: desc }, 'popup1024x678');
flexygo.events.on(this, "entity", "inserted", this.onEntityInserted);
return;
case 'workflow':
flexygo.nav.openPage('edit', 'sysProcess', "", { "typeId": "11", ProcessDescrip: desc }, 'popup1024x678');
flexygo.events.on(this, "entity", "inserted", this.onEntityInserted);
return;
case 'event':
break;
case 'label':
break;
default:
flexygo.msg.error('Invalid value');
return;
}
}
onEntityInserted(e) {
flexygo.events.off(this, "entity", "inserted");
if (!this.popupCell) {
return;
}
let cell = this.popupCell;
let cellType = cell.value.localName.toLowerCase();
let cellId = cell.value.getAttribute('fgid').toLowerCase();
if (cellId && cellId.length > 0) {
return;
}
let entity = e.sender;
let newId = '';
let newLabel = '';
switch (entity.objectName.toLowerCase()) {
case 'sysobject':
switch (cellType) {
case 'object':
newId = entity.data["ObjectName"].Value;
newLabel = entity.data["Descrip"].Value;
break;
}
break;
case 'sysprocess':
let typeId = parseInt(entity.data["TypeId"].Value);
switch (cellType) {
case 'process':
if (typeId !== 11 && typeId !== 12) {
newId = entity.data["ProcessName"].Value;
newLabel = entity.data["ProcessDescrip"].Value;
}
break;
case 'decission':
if (typeId === 12) {
newId = entity.data["ProcessName"].Value;
newLabel = entity.data["ProcessDescrip"].Value;
}
break;
case 'workflow':
if (typeId === 11) {
newId = entity.data["ProcessName"].Value;
newLabel = entity.data["ProcessDescrip"].Value;
}
break;
}
break;
}
if (newId.length === 0) {
return;
}
let model = this.editor.graph.getModel();
model.beginUpdate();
try {
let edit = new mxCellAttributeChange(cell, 'fgid', newId);
model.execute(edit);
edit = new mxCellAttributeChange(cell, 'label', newLabel);
model.execute(edit);
let style = this.getStepStyle(cell, '');
if (style.length > 0) {
model.setStyle(cell, style);
}
else {
model.setStyle(cell, null);
}
}
finally {
model.endUpdate();
}
this.popupCell = null;
}
showWorkflowProperties() {
if (!this.workflow) {
return;
}
if (!this.propertiesDialog) {
this.openPropertiesDialog();
}
let content = $(this.propertiesDialog.content);
content.empty();
let current = this.workflow;
let graph = this.editor.graph;
let model = graph.getModel();
let cell = model.cells[0];
let propTemplate = `
<div class="col-12" style="position:relative">
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelname')}</label>
<flx-text name="dbc-wfid" disabled="true" value="${current.WorkflowId}"></flx-text>
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labeldescrip')}</label>
<flx-text name="dbc-descrip" value="${this.htmlEncode(current.Descrip)}" placeholder="${flexygo.localization.translate('flxgipe.workflownameplaceholder')}"></flx-text>
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelarea')}</label>
<flx-dbcombo name="dbc-areaid" value="${current.AreaId}" ObjectName="sysWorkflow" ViewName="areasView" SQLValueField="WorkflowAreaId" SQLDisplayField="Descrip" placeholder="${flexygo.localization.translate('flxgipe.workflowareaplaceholder')}"></flx-dbcombo>
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelmodule')}</label>
<flx-dbcombo name="dbc-moduleid" value="${current.ModuleId}" ObjectName="sysWorkflow" ViewName="modulesView" SQLValueField="WorkflowModuleId" SQLDisplayField="Descrip" placeholder="${flexygo.localization.translate('flxgipe.workflowmoduleplaceholder')}"></flx-dbcombo>
<br/>
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labelactive')}</label>
<flx-check name="dbc-active" ${(current.Active && current.Active === true) ? 'checked' : ''}></flx-check>
</div>
<div name="parameters" class="col-12">
<label class="control-label fgWindowLabel">${flexygo.localization.translate('flxgipe.labeloutputparams')}</label>
</div>
<div name="gipeprops" class="col-12">
</div>
<div class="fgWindowToolbar">
<button class="btn btn-sm bg-info saveButton"><i class="flx-icon icon-save"></i>${flexygo.localization.translate('flxgipe.buttonsave')}</button>
<button class="btn btn-sm bg-danger closeButton"><i class="flx-icon icon-remove"></i>${flexygo.localization.translate('flxgipe.buttoncancel')}</button>
</div>
`;
content.append(propTemplate);
content.find("button.closeButton").off("click").on("click", (e) => {
if (this.fixedPropertiesDialog === false) {
this.propertiesDialog.destroy();
}
});
content.find("button.saveButton").off("click").on("click", (e) => {
this.workflow.AreaId = content.find('flx-dbcombo[name="dbc-areaid"]')[0].getValue();
this.workflow.ModuleId = content.find('flx-dbcombo[name="dbc-moduleid"]')[0].getValue();
this.workflow.Descrip = content.find('flx-text[name="dbc-descrip"]')[0].getValue();
this.workflow.Active = content.find('flx-check[name="dbc-active"]')[0].getValue();
let oldCells = [];
for (let key in model.cells) {
let c = model.cells[key];
if (c.isEdge() == true && parseInt(c.target.id) === 0) {
oldCells.push(c);
}
}
let newValues = [];
content.find('label[data-name="propname"]').each((i, e) => {
let value = this.editor.templates["relation"].value.cloneNode(true);
let lblProp = $(e);
let prop = lblProp.attr('data-prop');
let cboType = lblProp.parent().find(`select[data-name="parenttype"][data-prop="${prop}"]`); //TYPE SIEMPRE NODE
let cboParent = lblProp.parent().find(`select[data-name="parentname"][data-prop="${prop}"]`); //NODO PADRE
let cboParam = lblProp.parent().find(`select[data-name="paramname"][data-prop="${prop}"]`);
let type = "node";
let iotype = cboType.val();
let parent = cboParent.val();
let param = cboParam.val();
if (type && type.length > 0 && parent && parent.length > 0 && param && param.length > 0) {
let s = `<Parameter childparam="${prop}" iotype="${iotype}" type="${type}" parent="${parent}" parentparam="${param}"></Parameter>`;
let r = mxUtils.parseXml(s);
value.appendChild(r.documentElement);
newValues.push(value);
}
});
model.beginUpdate();
try {
graph.removeCells(oldCells);
newValues.forEach((n) => {
let parent = graph.getModel().getCell(n.firstChild.attributes['parent'].value);
let newCell = this.editor.graph.insertEdge(cell, null, n, parent, cell);
newCell.setVisible(false);
});
}
finally {
model.endUpdate();
}
if (!this.fixedPropertiesDialog) {
this.propertiesDialog.destroy();
}
});
flexygo.ajax.post('~/api/Gipe', 'getNodeRelations', { nodeType: cell.value.nodeName, nodeName: cell.value.getAttribute("fgid") }, (ret) => {
let relations = graph.getEdges(cell);
let divProps = content.find('div[name="gipeprops"]');
ret.forEach((param) => {
let parentvalue = "";
let parentdescrip = "";
let typevalue = "";
let paramvalue = "";
$.each(relations, (i, n) => {
let np = n.value.childNodes[0];
if (np.getAttribute('childparam').toLowerCase() === param.ParamName.toLowerCase()) {
typevalue = np.getAttribute('iotype');
parentvalue = model.getCell(np.getAttribute('parent')).id;
paramvalue = np.getAttribute('parentparam');
parentdescrip = model.getCell(np.getAttribute('parent')).value.getAttribute('label');
}
});
let prop = param.ParamName;
let template = `
<div class="col-12">
<label class="col-3" data-name="propname" data-prop="${prop}">${param.ParamLabel}</label>
<select class="col-3" data-name="parenttype" data-prop="${prop}"><option value=""/><option value="II">Input</option><option value="IO">Input/Output</option><option value="OO">Output</option></select>
<select class="col-3" data-name="parentname" data-prop="${prop}"></select>
<select class="col-3" data-name="paramname" data-prop="${prop}"></select>
</div>`;
let parsed = $(template);
if (typevalue.length === 0) {
typevalue = param.ParamType;
}
let nodes = `<option value=""></option>`;
let cboParent = parsed.find(`select[data-name="parentname"][data-prop="${prop}"]`);
for (let key in model.cells) {
let cell = model.cells[key];
if (cell.isVertex()) {
nodes += `<option value="${cell.id}">${cell.value.getAttribute('label')}</option>`;
}
}
cboParent.append(nodes);
if (typevalue !== '') {
parsed.find('select[data-name="parenttype"]').val(typevalue);
}
if (parentvalue !== '') {
parsed.find('select[data-name="parentname"]').append(`<option value="${parentvalue}" selected>${parentdescrip}</option>`);
}
if (paramvalue !== '') {
parsed.find('select[data-name="paramname"]').append(`<option value="${paramvalue}" selected>${paramvalue}</option>`);
}
divProps.append(parsed);
});
divProps.find('select[data-name="parenttype"]').off('change').on('change', (e) => {
let cboType = $(e.currentTarget);
let prop = cboType.attr('data-prop');
let cboParent = cboType.parent().find(`select[data-name="parentname"][data-prop="${prop}"]`);
let cboParam = cboType.parent().find(`select[data-name="paramname"][data-prop="${prop}"]`);
cboParam.find('option').remove();
cboParent.val('');
cboParam.val('');
switch (cboType.val()) {
case 'II':
cboParent.prop('disabled', true);
cboParam.prop('disabled', true);
break;
default:
cboParent.prop('disabled', false);
cboParam.prop('disabled', false);
cboParam.html();
break;
}
});
divProps.find('select[data-name="parentname"]').off('change').on('change', (e) => {
let cboParent = $(e.currentTarget);
let prop = cboParent.attr('data-prop');
let cboType = cboParent.parent().find(`select[data-name="parenttype"][data-prop="${prop}"]`);
let cboParam = cboParent.parent().find(`select[data-name="paramname"][data-prop="${prop}"]`);
cboParam.find('option').remove();
let nodes = `<option value=""></option>`;
switch (cboType.val()) {
case 'II':
break;
default:
let cell = model.getCell(cboParent.val());
if (!cell) {
cboParam.append(nodes);
}
else {
flexygo.ajax.post('~/api/Gipe', 'getNodeRelations', { nodeType: cell.value.localName, nodeName: cell.value.getAttribute('fgid') }, (ret) => {
ret.forEach((param) => {
nodes += `<option value="${param.ParamName}">${param.ParamLabel}</option>`;
});
cboParam.append(nodes);
});
}
break;
}
});
});
}
updateModuleTitle() {
let module = $(this).closest('flx-module');
let title = this.moduleTitle;
if (this.workflow) {
title += ' (' + this.workflow.WorkflowId + ') - ' + this.workflow.Descrip + ' - (V' + this.workflow.Version + ')';
}
$(module).find('.cntTitle').text(title);
}
updateBreadcrumb() {
let self = this;
let bc = $(this).find('ol.breadcrumb');
bc.empty();
if (this.currentExecutionId === 0) {
this.workflowStack.forEach((wf, i) => {
let li = $(`
<li class="breadcrumb-item"><a>${wf.WorkflowId}</a></li>
`);
li.on('click', (e) => {
self.goUp(i);
});
bc.append(li);
});
if (this.workflow && this.workflow.WorkflowId) {
bc.append(`
<li class="breadcrumb-item active"><a>${this.workflow.WorkflowId}</a></li>
`);
}
}
else {
this.debugStack.forEach((wf, i) => {
let li = $(`
<li class="breadcrumb-item" style="color:red"><a>${wf.WorkflowId}</a></li>
`);
li.on('click', (e) => {
let wf = this.debugStack[i];
self.loadDebugWorkflow(wf.WorkflowId, -1, wf.ExecutionId, null);
});
bc.append(li);
});
}
}
concatWhere(whereA, whereB) {
let where = "";
if (whereA && whereA.length > 0) {
where = whereA;
}
if (whereB && whereB.length > 0) {
if (whereA && whereA.length > 0) {
where += " AND " + whereB;
}
else {
where = whereB;
}
}
return where;
}
updateComboVersions() {
let cbo = $(this.versionCombo);
cbo.empty();
if (!this.workflow) {
cbo.append('<option value="">No versions</option>');
}
else {
this.workflow.Versions.forEach((v, i) => {
let isCurrent = (v.Version === this.workflow.Version);
cbo.append(`<option value="${v.Version}" ${(isCurrent) ? 'selected' : ''} >V${v.Version} ${(v.Active) ? '(Active)' : ''}</option>`);
});
}
}
htmlEncode(value) {
return $('<div/>').text(value).html();
}
getStepStyle(cell, style) {
let sep = '';
if (style && style.length > 0) {
sep = '-';
}
switch (cell.value.localName.toLowerCase()) {
case 'process':
return style + sep + 'rectangle';
case 'object':
return style + sep + 'ellipse';
case 'decission':
return style + sep + 'rhombus';
case 'workflow':
return style + sep + 'hexagon';
case 'event':
return style + sep + 'cloud';
case 'relation':
return style + sep + 'edge';
case 'label':
return 'label';
default:
flexygo.msg.error('Invalid value');
return;
}
}
/**
* Fires when an execution has finisehd a step
* @method debugWorkflow
*/
onDebugStepChanged() {
if (this.currentExecutionId === 0) {
return;
}
$(this.debugDialog.content).find('button[name="dbg-stepinto"]').prop('disabled', false);
$(this.debugDialog.content).find('button[name="dbg-stepover"]').prop('disabled', false);
flexygo.ajax.post('~/api/Gipe', 'getWorkflowExecutionStatus', { executionId: this.currentExecutionId }, (ret) => {
let execInfo = null;
if (ret && ret.Execution && ret.Execution.length > 0) {
ret.Execution.forEach((ex) => {
if (ex.ExecutionId == ret.NextWorkflow) {
execInfo = ex;
return false;
}
});
if (!execInfo) {
ret.Execution.forEach((ex) => {
if (ex.ExecutionId == this.debugWorkflow.ExecutionId) {
execInfo = ex;
return false;
}
});
}
}
if (execInfo.ExecutionId !== this.debugWorkflow.ExecutionId) {
this.loadDebugWorkflow(execInfo.WorkflowId, -1, execInfo.ExecutionId, ret);
}
else {
this.updateDebugInfo(ret);
}
});
}
addTreeNode(change, rootNode) {
if (change.ExecutionData && change.ExecutionData.length > 0) {
let model = null;
let itemLabel = "";
if (change.ExecutionId == this.debugWorkflow.ExecutionId) {
model = this.editor.graph.getModel();
let cell = model.getCell(change.GraphId);
itemLabel = cell.value.getAttribute('label');
}
else {
this.debugStack.forEach((wf, i) => {
if (wf.ExecutionId == change.ExecutionId) {
let node = mxUtils.parseXml(this.debugStack[i].WorkflowData);
let cell = $(node.documentElement).find(`[id="${change.GraphId}"]`);
if (cell.length > 0) {
itemLabel = cell[0].getAttribute('label');
}
return false;
}
});
}
let data = (new DOMParser()).parseFromString(change.ExecutionData, "text/xml").documentElement;
let itemNode = {
text: itemLabel,
icon: "fa fa-folder",
children: []
};
let resultNode = {
text: `<span>${flexygo.localization.translate('flxgipe.labelresult')}:</span><span style="color:black"><b>${change.ResultDescription}</b></span>`,
icon: "none",
children: []
};
itemNode.children.push(resultNode);
if (change.ResultId == eStepResult.Error) {
let errorNode = {
text: `<span>${flexygo.localization.translate('flxgipe.labelerrormessage')}:</span><span style="color:black"><b>${change.ErrorMessage}</b></span>`,
icon: "none",
children: []
};
resultNode.children.push(errorNode);
}
let statusNode = {
text: `<span>${flexygo.localization.translate('flxgipe.labelstatus')}:</span><span style="color:black"><b>${change.StatusDescription}</b></span>`,
icon: "none",
children: []
};
itemNode.children.push(statusNode);
let inNode = {
text: flexygo.localization.translate('flxgipe.treeinnode'),
icon: "flx-icon icon-document-export",
children: []
};
let inParams = data.getElementsByTagName('in')[0];
$.each(inParams.getElementsByTagName('param'), (i, e) => {
let paramNode = {
text: `<span>${e.getAttribute('name')}:</span><span style="color:black"><b>${e.getAttribute('value')}</b></span>`,
icon: 'none'
};
inNode.children.push(paramNode);
});
itemNode.children.push(inNode);
let outNode = {
text: flexygo.localization.translate('flxgipe.treeoutnode'),
icon: "flx-icon icon-document-import",
children: []
};
let outParams = data.getElementsByTagName('out')[0];
$.each(outParams.getElementsByTagName('param'), (i, e) => {
let paramNode = {
text: `<span>${e.getAttribute('name')}:</span><span style="color:black"><b>${e.getAttribute('value')}</b></span>`,
icon: 'none'
};
outNode.children.push(paramNode);
});
itemNode.children.push(outNode);
rootNode.children.push(itemNode);
}
}
updateDebugInfo(ret) {
if (!ret) {
return;
}
let graph = this.editor.graph;
let model = graph.getModel();
let lastWorkflowExecutionId = ret.LastWorkflow;
if (lastWorkflowExecutionId === 0) {
lastWorkflowExecutionId = this.currentExecutionId;
}
let execInfo = null;
if (ret && ret.Execution && ret.Execution.length > 0) {
ret.Execution.forEach((ex) => {
if (ex.ExecutionId == lastWorkflowExecutionId) {
execInfo = ex;
return false;
}
});
if (execInfo) {
let finishedSteps = [];
ret.Execution.forEach((ex) => {
if ((ex.ExecutionId !== execInfo.ExecutionId) && (ex.StatusId === eStepStatus.Finished)) {
//Remove child finished workflows from stack
this.debugStack.forEach((ds, i) => {
if (ds.ExecutionId === ex.ExecutionId) {
finishedSteps.push(ds);
}
});
}
});
if (finishedSteps.length !== 0) {
finishedSteps.forEach((fs) => {
this.debugStack.splice(this.debugStack.indexOf(fs), 1);
});
this.updateBreadcrumb();
}
}
}
let txtStatus = $('#gipedbg-status')[0];
let txtResult = $('#gipedbg-result')[0];
if (execInfo) {
txtStatus.setValue(execInfo.StatusDescription);
txtResult.setValue(execInfo.ResultDescription);
if (execInfo.ResultId !== eStepResult.NoResult) {
$(this.debugDialog.content).find('button[name="dbg-stepinto"]').prop('disabled', true);
$(this.debugDialog.content).find('button[name="dbg-stepover"]').prop('disabled', true);
}
}
let rootNodes = [];
ret.Execution.forEach((exec) => {
let execNode = {
id: 'WF-' + exec.ExecutionId,
text: exec.WorkflowDescription,
icon: "flx-icon icon-share",
children: []
};
rootNodes.push(execNode);
});
if (ret.Nodes) {
model.beginUpdate();
try {
ret.Nodes.forEach((change) => {
if ((change.ExecutionId === execInfo.ExecutionId) && (change.ExecutionId === this.debugWorkflow.ExecutionId)) {
let cell = model.getCell(change.GraphId);
if (change.ResultId !== eStepResult.NoResult) {
cell.edges.forEach((edge) => {
if (edge.target.id === cell.id) {
model.setStyle(edge, this.getStepStyle(edge, 'success'));
let state = graph.view.getState(edge);
state.shape.node.removeAttribute('class');
}
});
}
switch (change.ResultId) {
case eStepResult.OK:
model.setStyle(cell, this.getStepStyle(cell, 'success'));
break;
case eStepResult.Error:
model.setStyle(cell, this.getStepStyle(cell, 'error'));
break;
default:
model.setStyle(cell, this.getStepStyle(cell, ''));
break;
}
let state = graph.view.getState(cell);
state.shape.node.removeAttribute('class');
}
let rootNode = null;
rootNodes.forEach((n) => {
if (n.id == 'WF-' + change.ExecutionId) {
rootNode = n;
return false;
}
});
this.addTreeNode(change, rootNode);
});
let nextId = 0;
if (ret.NextWorkflow === execInfo.ExecutionId) {
if (ret.NextStep && ret.NextStep !== 0) {
nextId = ret.NextStep;
}
else {
if (execInfo.ResultId === 0) {
nextId = execInfo.InitialGraphId;
}
}
}
else if ((ret.NextWorkflow === 0) && (ret.NextStep === 0)) {
if (ret.LastWorkflow === this.debugWorkflow.ExecutionId) {
nextId = ret.LastStep;
}
}
if (nextId !== 0) {
let next = model.getCell(nextId);
let state = graph.view.getState(next);
model.setStyle(next, this.getStepStyle(next, 'running'));
state.shape.node.setAttribute('class', 'flow');
next.edges.forEach((edge) => {
if (edge.target.id === next.id) {
let state = graph.view.getState(edge);
model.setStyle(edge, this.getStepStyle(edge, 'running'));
state.shape.node.setAttribute('class', 'flow');
}
});
this.lastDebugGraphId = {
executionId: execInfo.ExecutionId,
graphId: nextId
};
}
}
finally {
model.endUpdate();
}
}
var tree = $('#gipe-debug-tree');
tree.jstree(true).settings.core.data = rootNodes;
tree.jstree(true).refresh();
if ((execInfo.StatusId == eStepStatus.Aborted || execInfo.StatusId == eStepStatus.Finished) && (execInfo.ExecutionId == this.currentExecutionId)) {
this.lastDebugGraphId = null;
this.currentExecutionId = 0;
this.updateToolbarStatus();
}
}
}
wc.FlxGipeDesignerElement = FlxGipeDesignerElement;
})(wc = ui_1.wc || (ui_1.wc = {}));
})(ui = flexygo.ui || (flexygo.ui = {}));
})(flexygo || (flexygo = {}));
window.customElements.define("flx-gipedesigner", flexygo.ui.wc.FlxGipeDesignerElement);
//# sourceMappingURL=flx-gipedesigner.js.map