Skip to content

Commit

Permalink
feat: create ad-hoc sub process via replace menu
Browse files Browse the repository at this point in the history
  • Loading branch information
jarekdanielak committed Jan 23, 2025
1 parent d9fc726 commit 2428fba
Show file tree
Hide file tree
Showing 7 changed files with 429 additions and 131 deletions.
40 changes: 16 additions & 24 deletions lib/features/popup-menu/ReplaceMenuProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,14 @@ ReplaceMenuProvider.prototype.getPopupMenuEntries = function(target) {
return this._createEntries(target, filteredReplaceOptions);
}

// expanded ad hoc sub processes
if (is(businessObject, 'bpmn:AdHocSubProcess') && isExpanded(target)) {

filteredReplaceOptions = filter(replaceOptions.AD_HOC_SUBPROCESS_EXPANDED, differentType);

return this._createEntries(target, filteredReplaceOptions);
}

// expanded sub processes
if (is(businessObject, 'bpmn:SubProcess') && isExpanded(target)) {

Expand All @@ -239,18 +247,16 @@ ReplaceMenuProvider.prototype.getPopupMenuEntries = function(target) {
return this._createEntries(target, filteredReplaceOptions);
}

// collapsed ad hoc sub processes
if (is(businessObject, 'bpmn:AdHocSubProcess') && !isExpanded(target)) {
// collapsed sub process or collapsed ad hoc sub process
if (is(businessObject, 'bpmn:SubProcess') && !isExpanded(target)) {

filteredReplaceOptions = filter(replaceOptions.TASK, function(replaceOption) {

var target = replaceOption.target;

var isTargetSubProcess = target.type === 'bpmn:SubProcess';
var isTargetSameType = replaceOption.target.type === target.type;
var isTargetExpanded = replaceOption.target.isExpanded === true;

var isTargetExpanded = target.isExpanded === true;

return isDifferentType(target, target) && (!isTargetSubProcess || isTargetExpanded);
// Collapsed subprocess cannot be replaced with itself or expanded subprocess of different type.
return isTargetSameType === isTargetExpanded;
});

return this._createEntries(target, filteredReplaceOptions);
Expand All @@ -265,13 +271,6 @@ ReplaceMenuProvider.prototype.getPopupMenuEntries = function(target) {
if (is(businessObject, 'bpmn:FlowNode')) {
filteredReplaceOptions = filter(replaceOptions.TASK, differentType);

// collapsed sub process cannot be replaced with itself
if (is(businessObject, 'bpmn:SubProcess') && !isExpanded(target)) {
filteredReplaceOptions = filter(filteredReplaceOptions, function(replaceOption) {
return replaceOption.label !== 'Sub-process (collapsed)';
});
}

return this._createEntries(target, filteredReplaceOptions);
}

Expand Down Expand Up @@ -308,15 +307,6 @@ ReplaceMenuProvider.prototype.getPopupMenuHeaderEntries = function(target) {
};
}

if (is(target, 'bpmn:SubProcess') &&
!is(target, 'bpmn:Transaction') &&
!isEventSubProcess(target)) {
headerEntries = {
...headerEntries,
...this._getAdHocHeaderEntries(target)
};
}

if (canBeNonInterrupting(target)) {
headerEntries = {
...headerEntries,
Expand Down Expand Up @@ -620,6 +610,8 @@ ReplaceMenuProvider.prototype._getParticipantMultiplicityHeaderEntries = functio
* @param {PopupMenuTarget} element
*
* @return {PopupMenuHeaderEntries}
*
* @deprecated sinve v18.2.0 `bpmn:AdHocSubProcess` is available as a separate menu option.
*/
ReplaceMenuProvider.prototype._getAdHocHeaderEntries = function(element) {
var translate = this._translate;
Expand Down
2 changes: 1 addition & 1 deletion lib/features/replace/BpmnReplace.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export default function BpmnReplace(
var type = targetElement.type,
oldBusinessObject = element.businessObject;

if (isSubProcess(oldBusinessObject) && type === 'bpmn:SubProcess') {
if (isSubProcess(oldBusinessObject) && (type === 'bpmn:SubProcess' || type === 'bpmn:AdHocSubProcess')) {
if (shouldToggleCollapsed(element, targetElement)) {

// expanding or collapsing process
Expand Down
79 changes: 79 additions & 0 deletions lib/features/replace/ReplaceOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,15 @@ export var SUBPROCESS_EXPANDED = [
isExpanded: true
}
},
{
label: 'Ad-hoc sub-process',
actionName: 'replace-with-ad-hoc-subprocess',
className: 'bpmn-icon-subprocess-expanded',
target: {
type: 'bpmn:AdHocSubProcess',
isExpanded: true
}
},
{
label: 'Sub-process (collapsed)',
actionName: 'replace-with-collapsed-subprocess',
Expand All @@ -438,6 +447,49 @@ export var SUBPROCESS_EXPANDED = [
}
];

/**
* @type {ReplaceOption[]}
*/
export var AD_HOC_SUBPROCESS_EXPANDED = [
{
label: 'Sub-process',
actionName: 'replace-with-subprocess',
className: 'bpmn-icon-subprocess-expanded',
target: {
type: 'bpmn:SubProcess',
isExpanded: true
}
},
{
label: 'Transaction',
actionName: 'replace-with-transaction',
className: 'bpmn-icon-transaction',
target: {
type: 'bpmn:Transaction',
isExpanded: true
}
},
{
label: 'Event sub-process',
actionName: 'replace-with-event-subprocess',
className: 'bpmn-icon-event-subprocess-expanded',
target: {
type: 'bpmn:SubProcess',
triggeredByEvent: true,
isExpanded: true
}
},
{
label: 'Ad-hoc sub-process (collapsed)',
actionName: 'replace-with-collapsed-ad-hoc-subprocess',
className: 'bpmn-icon-subprocess-collapsed',
target: {
type: 'bpmn:AdHocSubProcess',
isExpanded: false
}
}
];

/**
* @type {ReplaceOption[]}
*/
Expand All @@ -460,6 +512,15 @@ export var TRANSACTION = [
isExpanded: true
}
},
{
label: 'Ad-hoc sub-process',
actionName: 'replace-with-ad-hoc-subprocess',
className: 'bpmn-icon-subprocess-expanded',
target: {
type: 'bpmn:AdHocSubProcess',
isExpanded: true
}
},
{
label: 'Event sub-process',
actionName: 'replace-with-event-subprocess',
Expand Down Expand Up @@ -570,6 +631,24 @@ export var TASK = [
type: 'bpmn:SubProcess',
isExpanded: true
}
},
{
label: 'Ad-hoc sub-process (collapsed)',
actionName: 'replace-with-collapsed-ad-hoc-subprocess',
className: 'bpmn-icon-subprocess-collapsed',
target: {
type: 'bpmn:AdHocSubProcess',
isExpanded: false
}
},
{
label: 'Ad-hoc sub-process (expanded)',
actionName: 'replace-with-ad-hoc-subprocess',
className: 'bpmn-icon-subprocess-expanded',
target: {
type: 'bpmn:AdHocSubProcess',
isExpanded: true
}
}
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@
<bpmn2:startEvent id="StartEvent_4">
<bpmn2:outgoing>SequenceFlow_9</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:sequenceFlow id="SequenceFlow_9" sourceRef="StartEvent_4" targetRef="SubProcess_2" />
<bpmn2:sequenceFlow id="SequenceFlow_9" sourceRef="StartEvent_4" targetRef="AdHocSubProcess_1" />
<bpmn2:endEvent id="EndEvent_5">
<bpmn2:incoming>SequenceFlow_8</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="SequenceFlow_8" sourceRef="SubProcess_2" targetRef="EndEvent_5" />
<bpmn2:sequenceFlow id="SequenceFlow_8" sourceRef="AdHocSubProcess_1" targetRef="EndEvent_5" />
<bpmn2:subProcess id="SubProcess_3" />
<bpmn2:adHocSubProcess id="SubProcess_4">
<bpmn2:multiInstanceLoopCharacteristics />
<bpmn2:startEvent id="StartEvent_5" />
</bpmn2:adHocSubProcess>
<bpmn2:adHocSubProcess id="SubProcess_2">
<bpmn2:adHocSubProcess id="AdHocSubProcess_1">
<bpmn2:incoming>SequenceFlow_9</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_8</bpmn2:outgoing>
<bpmn2:multiInstanceLoopCharacteristics />
Expand Down Expand Up @@ -143,7 +143,7 @@
<bpmndi:BPMNShape id="AdHocSubProcess_0ojckgh_di" bpmnElement="SubProcess_4" isExpanded="false">
<dc:Bounds x="541" y="652" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="AdHocSubProcess_128w1vu_di" bpmnElement="SubProcess_2" isExpanded="true">
<bpmndi:BPMNShape id="AdHocSubProcess_128w1vu_di" bpmnElement="AdHocSubProcess_1" isExpanded="true">
<dc:Bounds x="407" y="335" width="385" height="200" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_1s8bqj4_di" bpmnElement="SequenceFlow_11">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ describe('features/modeling - collapse and expand elements', function() {
// when
var expandedAdHocSubProcess = bpmnReplace.replaceElement(collapsedAdHocSubProcess,
{
type: 'bpmn:SubProcess',
type: 'bpmn:AdHocSubProcess',
isExpanded: true
}
);
Expand Down Expand Up @@ -322,12 +322,12 @@ describe('features/modeling - collapse and expand elements', function() {
inject(function(elementRegistry, bpmnReplace) {

// given
var expandedSubProcess = elementRegistry.get('SubProcess_2');
var expandedSubProcess = elementRegistry.get('AdHocSubProcess_1');

// when
var collapsedSubProcess = bpmnReplace.replaceElement(expandedSubProcess,
{
type: 'bpmn:SubProcess',
type: 'bpmn:AdHocSubProcess',
isExpanded: false
}
);
Expand All @@ -342,12 +342,12 @@ describe('features/modeling - collapse and expand elements', function() {
inject(function(elementRegistry, bpmnReplace) {

// given
var expandedSubProcess = elementRegistry.get('SubProcess_2');
var expandedSubProcess = elementRegistry.get('AdHocSubProcess_1');

// when
var collapsedSubProcess = bpmnReplace.replaceElement(expandedSubProcess,
{
type: 'bpmn:SubProcess',
type: 'bpmn:AdHocSubProcess',
isExpanded: false
}
);
Expand All @@ -364,7 +364,7 @@ describe('features/modeling - collapse and expand elements', function() {
inject(function(elementRegistry, bpmnReplace) {

// given
var expandedSubProcess = elementRegistry.get('SubProcess_2');
var expandedSubProcess = elementRegistry.get('AdHocSubProcess_1');
var originalChildren = expandedSubProcess.children.slice();

// when
Expand All @@ -376,7 +376,7 @@ describe('features/modeling - collapse and expand elements', function() {
);

// then
var plane = elementRegistry.get('SubProcess_2_plane');
var plane = elementRegistry.get('AdHocSubProcess_1_plane');
originalChildren.forEach(function(c) {
expect(plane.children).to.include(c);
});
Expand All @@ -390,7 +390,7 @@ describe('features/modeling - collapse and expand elements', function() {
inject(function(elementRegistry, bpmnReplace) {

// given
var expandedSubProcess = elementRegistry.get('SubProcess_2');
var expandedSubProcess = elementRegistry.get('AdHocSubProcess_1');
var oldMid = {
x: expandedSubProcess.x + expandedSubProcess.width / 2,
y: expandedSubProcess.y + expandedSubProcess.height / 2
Expand All @@ -399,7 +399,7 @@ describe('features/modeling - collapse and expand elements', function() {
// when
var collapsedSubProcess = bpmnReplace.replaceElement(expandedSubProcess,
{
type: 'bpmn:SubProcess',
type: 'bpmn:AdHocSubProcess',
isExpanded: false
}
);
Expand All @@ -426,10 +426,10 @@ describe('features/modeling - collapse and expand elements', function() {
inject(function(elementRegistry, bpmnReplace, commandStack) {

// given
var expandedSubProcess = elementRegistry.get('SubProcess_2');
var expandedSubProcess = elementRegistry.get('AdHocSubProcess_1');
var collapsedSubProcess = bpmnReplace.replaceElement(expandedSubProcess,
{
type: 'bpmn:SubProcess',
type: 'bpmn:AdHocSubProcess',
isExpanded: false
}
);
Expand All @@ -447,7 +447,7 @@ describe('features/modeling - collapse and expand elements', function() {
inject(function(elementRegistry, bpmnReplace, commandStack) {

// given
var expandedSubProcess = elementRegistry.get('SubProcess_2');
var expandedSubProcess = elementRegistry.get('AdHocSubProcess_1');
var originalBounds = {
x: expandedSubProcess.x,
y: expandedSubProcess.y,
Expand All @@ -457,7 +457,7 @@ describe('features/modeling - collapse and expand elements', function() {

bpmnReplace.replaceElement(expandedSubProcess,
{
type: 'bpmn:SubProcess',
type: 'bpmn:AdHocSubProcess',
isExpanded: false
}
);
Expand All @@ -475,12 +475,12 @@ describe('features/modeling - collapse and expand elements', function() {
inject(function(elementRegistry, bpmnReplace, commandStack) {

// given
var expandedSubProcess = elementRegistry.get('SubProcess_2');
var expandedSubProcess = elementRegistry.get('AdHocSubProcess_1');
var originalChildren = expandedSubProcess.children.slice();

bpmnReplace.replaceElement(expandedSubProcess,
{
type: 'bpmn:SubProcess',
type: 'bpmn:AdHocSubProcess',
isExpanded: false
}
);
Expand Down Expand Up @@ -589,7 +589,7 @@ describe('features/modeling - collapse and expand elements', function() {
inject(function(eventBus, bpmnReplace, elementRegistry) {

// given
var expandedSubProcess = elementRegistry.get('SubProcess_2');
var expandedSubProcess = elementRegistry.get('AdHocSubProcess_1');

// should not be called
eventBus.once('commandStack.shape.toggleCollapse.execute', function(e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.30.0">
<bpmn:process id="Process_1" isExecutable="false">
<bpmn:subProcess id="SubProcess_1">
<bpmn:task id="Activity_0j5zj2x" />
</bpmn:subProcess>
<bpmn:adHocSubProcess id="AdhocSubProcess_1">
<bpmn:task id="Activity_1j5hq1s" />
</bpmn:adHocSubProcess>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
<bpmndi:BPMNShape id="SubProcess_0loe8m1_di" bpmnElement="SubProcess_1" isExpanded="true">
<dc:Bounds x="160" y="60" width="360" height="210" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0j5zj2x_di" bpmnElement="Activity_0j5zj2x">
<dc:Bounds x="290" y="120" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="AdHocSubProcess_0lfb35q_di" bpmnElement="AdhocSubProcess_1" isExpanded="true">
<dc:Bounds x="600" y="65" width="360" height="200" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_14akb0e" bpmnElement="Activity_1j5hq1s">
<dc:Bounds x="740" y="120" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
Loading

0 comments on commit 2428fba

Please sign in to comment.