The diagram is as follows:
The code is as follows:
1.provider/parts/ExecutionOrderProps.js
'use strict';
var is = require('bpmn-js/lib/util/ModelUtil').is,
isAny = require('bpmn-js/lib/features/modeling/util/ModelingUtil').isAny,
getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
cmdHelper = require('bpmn-js-properties-panel/lib/helper/CmdHelper'),
elementHelper = require('bpmn-js-properties-panel/lib/helper/ElementHelper'),
eventDefinitionHelper = require('bpmn-js-properties-panel/lib/helper/EventDefinitionHelper'),
script = require('bpmn-js-properties-panel/lib/provider/camunda/parts/implementation/Script')('language', 'body', true);
var domQuery = require('min-dom').query,
domClosest = require('min-dom').closest,
domify = require('min-dom').domify,
domClear = require('min-dom').clear,
forEach = require('lodash/forEach');
function getSelectBox(node, id) {
var currentTab = domClosest(node, 'div.bpp-properties-tab');
var query = 'select[name=selectedGatewayOutgoing]' + (id ? '[id=cam-gateway-' + id + ']' : '');
return domQuery(query, currentTab);
}
function getSelected(node, id) {
var selectBox = getSelectBox(node, id);
if (selectBox)
return {
box: selectBox,
value: selectBox.value,
idx: selectBox.selectedIndex,
length: selectBox.options.length
};
return null;
}
function orderSelectBoxOptions(node, id, from, to) {
var selectBox = getSelectBox(node, id);
if (!selectBox)
return;
if (selectBox.selectedIndex == -1)
return;
if (from == to)
return;
var start = Math.min(from, to);
var end = Math.max(from, to);
var options = new Array(selectBox.options.length);
if (from > to) {
for (var i = 0; i < selectBox.options.length; i++) {
if (i < start)
options[i] = selectBox.options[i];
else if (i == start)
options[i] = selectBox.options[end];
else if (i <= end)
options[i] = selectBox.options[i - 1];
else
options[i] = selectBox.options[i];
}
} else {
for (var i = selectBox.options.length - 1; i >= 0; i--) {
if (i > end)
options[i] = selectBox.options[i];
else if (i == end)
options[i] = selectBox.options[start];
else if (i >= start)
options[i] = selectBox.options[i + 1];
else
options[i] = selectBox.options[i];
}
}
domClear(selectBox);
forEach(options, (o) => {
selectBox.appendChild(o);
});
}
function orderedOutgoing(bo, from, to) {
if (!bo)
return;
if (from == to)
return;
var start = Math.min(from, to);
var end = Math.max(from, to);
var outgoing = bo.outgoing;
if (!outgoing)
return;
if (from > to) {
while (end > start) {
var tmp = outgoing[end - 1];
outgoing[end - 1] = outgoing[end];
outgoing[end] = tmp;
end = end - 1;
}
} else {
while (start < end) {
var tmp = outgoing[start + 1];
outgoing[start + 1] = outgoing[start];
outgoing[start] = tmp;
start = start + 1;
}
}
}
module.exports = function (group, element, bpmnFactory, translate, eventBus) {
var bo = getBusinessObject(element);
var id = "outgoing";
var label = translate('Outgoing');
var defaultSize = 5;
if (!bo) {
return;
}
if (!is(element, 'bpmn:ExclusiveGateway'))
return;
var initSelectionSize = function (selectBox, optionsLength) {
selectBox.size = optionsLength > defaultSize ? optionsLength : defaultSize;
};
var createOption = function (value) {
return '<option value="' + value + '" data-value data-name="extensionElementValue">' + value + '</option>';
};
group.entries.push({
id: id,
label: label,
modelProperty: '',
html: '<div class="bpp-row bpp-element-list" ' + '>' +
'<label for="cam-gateway-' + id + '">' + label + '</label>' +
'<div class="bpp-field-wrapper">' +
'<select id="cam-gateway-' + id + '"' +
'name="selectedGatewayOutgoing" ' +
'size="' + defaultSize + '" ' +
'data-list-entry-container >' +
'</select>' +
'<button class="top" ' +
'id="cam-gateway-top-' + id + '" ' +
'data-action="topElement" >' +
'<span class="fa fa-angle-double-up top"></span>' +
'</button>' +
'<button class="up" ' +
'id="cam-gateway-up-' + id + '" ' +
'data-action="upElement" >' +
'<span class="fa fa-angle-up"></span>' +
'</button>' +
'<button class="down" ' +
'id="cam-gateway-down-' + id + '" ' +
'data-action="downElement" >' +
'<span class="fas fa-angle-down"></span>' +
'</button>' +
'<button class="bottom" ' +
'id="cam-gateway-bottom-' + id + '" ' +
'data-action="bottomElement" >' +
'<span class="fas fa-angle-double-down"></span>' +
'</button>' +
'</div>' +
'</div>',
get: function (element, node) {
var result = [];
forEach(bo.outgoing, function (elem) {
result.push({
extensionElementValue: elem.id
});
});
var selectBox = getSelectBox(node.parentNode, id);
initSelectionSize(selectBox, result.length);
return result;
},
set: function (element, values, containerElement) {
bo = bo || getBusinessObject(element);
var commands = [];
var outgoing = bo.outgoing;
if (!outgoing)
commands.push(cmdHelper.updateBusinessObject(element, bo, {
outgoing: outgoing
}));
return commands;
},
createListEntryTemplate: function (value, index, selectBox) {
initSelectionSize(selectBox, selectBox.options.length + 1);
return createOption(value.extensionElementValue);
},
topElement: function (element, node) {
var box = getSelected(node, id);
if (!box)
return false;
if (box.idx <= 0)
return false;
orderSelectBoxOptions(node, id, box.idx, 0);
orderedOutgoing(bo, box.idx, 0);
return true;
},
upElement: function (element, node) {
var box = getSelected(node, id);
if (!box)
return false;
if (box.idx <= 0)
return false;
orderSelectBoxOptions(node, id, box.idx, box.idx - 1);
orderedOutgoing(bo, box.idx, box.idx - 1);
return true;
},
downElement: function (element, node) {
var box = getSelected(node, id);
if (!box)
return false;
if (box.idx < 0 || box.idx >= box.length - 1)
return false;
orderSelectBoxOptions(node, id, box.idx, box.idx + 1);
orderedOutgoing(bo, box.idx, box.idx + 1);
return true;
},
bottomElement: function (element, node) {
var box = getSelected(node, id);
if (!box)
return false;
if (box.idx < 0 || box.idx >= box.length - 1)
return false;
orderSelectBoxOptions(node, id, box.idx, box.length - 1);
orderedOutgoing(bo, box.idx, box.length - 1);
return true;
}
});
};
2.PropertiesProvider.js
function createGeneralTabGroups(element, bpmnFactory, elementRegistry, elementTemplates, translate, eventBus) {
// ......
var executionOrderGroup = {
id: 'executionOrder',
label: translate('Execution Order'),
entries: []
};
executionOrderProps(executionOrderGroup, element, bpmnFactory, translate, eventBus); //The execution order of the outgoing branches of the exclusive gateway
var groups = [];
// ...
groups.push(executionOrderGroup);
return groups;
}
3.app.cs
.bpp-element-list button.top,
.bpp-element-list button.up,
.bpp-element-list button.down,
.bpp-element-list button.bottom {
top: -23px;
border-bottom: none;
}
.bpp-element-list button.top>span,
.bpp-element-list button.up>span,
.bpp-element-list button.down>span,
.bpp-element-list button.bottom>span {
display: block;
}
.bpp-element-list button.bottom {
right: 0px;
}
.bpp-element-list button.down {
right: 23px;
}
.bpp-element-list button.up {
right: 46px;
}
.bpp-element-list button.top {
right: 69px;
}