Skip to content

Commit

Permalink
feat: allow to replace between variants of typed events
Browse files Browse the repository at this point in the history
  • Loading branch information
barmac committed Feb 18, 2025
1 parent c3ab26b commit 0a7c5f3
Show file tree
Hide file tree
Showing 4 changed files with 375 additions and 19 deletions.
49 changes: 38 additions & 11 deletions lib/features/popup-menu/ReplaceMenuProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ ReplaceMenuProvider.prototype.getPopupMenuEntries = function(target) {

var rules = this._rules;

var sameTypeEventOptions = [],
eventDefinitionType;

var filteredReplaceOptions = [];

if (isArray(target) || !rules.allowed('shape.replace', { element: target })) {
Expand All @@ -116,10 +119,26 @@ ReplaceMenuProvider.prototype.getPopupMenuEntries = function(target) {
return this._createEntries(target, replaceOptions.DATA_STORE_REFERENCE);
}

// typed start, intermediate, and end events
if (is(businessObject, 'bpmn:Event') && !is(businessObject, 'bpmn:BoundaryEvent')) {
eventDefinitionType = businessObject.get('eventDefinitions')[0]?.$type;

sameTypeEventOptions = replaceOptions.TYPED_EVENT[eventDefinitionType] || [];

if (!isEventSubProcess(businessObject.$parent) && is(businessObject.$parent, 'bpmn:SubProcess')) {
sameTypeEventOptions = filter(sameTypeEventOptions, function(option) {
return option.target.type !== 'bpmn:StartEvent';
});
}
}

// start events outside sub processes
if (is(businessObject, 'bpmn:StartEvent') && !is(businessObject.$parent, 'bpmn:SubProcess')) {

filteredReplaceOptions = filter(replaceOptions.START_EVENT, differentType);
filteredReplaceOptions = filter(
replaceOptions.START_EVENT.concat(sameTypeEventOptions),
differentType
);

return this._createEntries(target, filteredReplaceOptions);
}
Expand All @@ -136,34 +155,39 @@ ReplaceMenuProvider.prototype.getPopupMenuEntries = function(target) {

// start events inside event sub processes
if (is(businessObject, 'bpmn:StartEvent') && isEventSubProcess(businessObject.$parent)) {
filteredReplaceOptions = filter(replaceOptions.EVENT_SUB_PROCESS_START_EVENT, function(replaceOption) {
filteredReplaceOptions = filter(
replaceOptions.EVENT_SUB_PROCESS_START_EVENT.concat(sameTypeEventOptions), function(replaceOption) {

var target = replaceOption.target;
var target = replaceOption.target;

var isInterrupting = target.isInterrupting !== false;
var isInterrupting = target.isInterrupting !== false;

var isInterruptingEqual = businessObject.isInterrupting === isInterrupting;
var isInterruptingEqual = businessObject.isInterrupting === isInterrupting;

// filters elements which types and event definition are equal but have have different interrupting types
return differentType(replaceOption) || !differentType(replaceOption) && !isInterruptingEqual;
// filters elements which types and event definition are equal but have have different interrupting types
return differentType(replaceOption) || !differentType(replaceOption) && !isInterruptingEqual;

});
}
);

return this._createEntries(target, filteredReplaceOptions);
}

// start events inside sub processes
if (is(businessObject, 'bpmn:StartEvent') && !isEventSubProcess(businessObject.$parent)
&& is(businessObject.$parent, 'bpmn:SubProcess')) {
filteredReplaceOptions = filter(replaceOptions.START_EVENT_SUB_PROCESS, differentType);
filteredReplaceOptions = filter(
replaceOptions.START_EVENT_SUB_PROCESS.concat(sameTypeEventOptions),
differentType
);

return this._createEntries(target, filteredReplaceOptions);
}

// end events
if (is(businessObject, 'bpmn:EndEvent')) {

filteredReplaceOptions = filter(replaceOptions.END_EVENT, function(replaceOption) {
filteredReplaceOptions = filter(replaceOptions.END_EVENT.concat(sameTypeEventOptions), function(replaceOption) {
var target = replaceOption.target;

// hide cancel end events outside transactions
Expand Down Expand Up @@ -202,7 +226,10 @@ ReplaceMenuProvider.prototype.getPopupMenuEntries = function(target) {
if (is(businessObject, 'bpmn:IntermediateCatchEvent') ||
is(businessObject, 'bpmn:IntermediateThrowEvent')) {

filteredReplaceOptions = filter(replaceOptions.INTERMEDIATE_EVENT, differentType);
filteredReplaceOptions = filter(
replaceOptions.INTERMEDIATE_EVENT.concat(sameTypeEventOptions),
differentType
);

return this._createEntries(target, filteredReplaceOptions);
}
Expand Down
200 changes: 200 additions & 0 deletions lib/features/replace/ReplaceOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -996,3 +996,203 @@ export var PARTICIPANT = [
}
}
];

/**
* @type {{ [key: string]: ReplaceOption[]}}
*/
export var TYPED_EVENT = {
'bpmn:MessageEventDefinition': [
{
label: 'Message start event',
actionName: 'replace-with-message-start',
className: 'bpmn-icon-start-event-message',
target: {
type: 'bpmn:StartEvent',
eventDefinitionType: 'bpmn:MessageEventDefinition'
}
},
{
label: 'Message intermediate catch event',
actionName: 'replace-with-message-intermediate-catch',
className: 'bpmn-icon-intermediate-event-catch-message',
target: {
type: 'bpmn:IntermediateCatchEvent',
eventDefinitionType: 'bpmn:MessageEventDefinition'
}
},
{
label: 'Message intermediate throw event',
actionName: 'replace-with-message-intermediate-throw',
className: 'bpmn-icon-intermediate-event-throw-message',
target: {
type: 'bpmn:IntermediateThrowEvent',
eventDefinitionType: 'bpmn:MessageEventDefinition'
}
},
{
label: 'Message end event',
actionName: 'replace-with-message-end',
className: 'bpmn-icon-end-event-message',
target: {
type: 'bpmn:EndEvent',
eventDefinitionType: 'bpmn:MessageEventDefinition'
}
}
],
'bpmn:TimerEventDefinition': [
{
label: 'Timer start event',
actionName: 'replace-with-timer-start',
className: 'bpmn-icon-start-event-timer',
target: {
type: 'bpmn:StartEvent',
eventDefinitionType: 'bpmn:TimerEventDefinition'
}
},
{
label: 'Timer intermediate catch event',
actionName: 'replace-with-timer-intermediate-catch',
className: 'bpmn-icon-intermediate-event-catch-timer',
target: {
type: 'bpmn:IntermediateCatchEvent',
eventDefinitionType: 'bpmn:TimerEventDefinition'
}
}
],
'bpmn:ConditionalEventDefinition': [
{
label: 'Conditional start event',
actionName: 'replace-with-conditional-start',
className: 'bpmn-icon-start-event-condition',
target: {
type: 'bpmn:StartEvent',
eventDefinitionType: 'bpmn:ConditionalEventDefinition'
}
},
{
label: 'Conditional intermediate catch event',
actionName: 'replace-with-conditional-intermediate-catch',
className: 'bpmn-icon-intermediate-event-catch-condition',
target: {
type: 'bpmn:IntermediateCatchEvent',
eventDefinitionType: 'bpmn:ConditionalEventDefinition'
}
}
],
'bpmn:SignalEventDefinition': [
{
label: 'Signal start event',
actionName: 'replace-with-signal-start',
className: 'bpmn-icon-start-event-signal',
target: {
type: 'bpmn:StartEvent',
eventDefinitionType: 'bpmn:SignalEventDefinition'
}
},
{
label: 'Signal intermediate catch event',
actionName: 'replace-with-signal-intermediate-catch',
className: 'bpmn-icon-intermediate-event-catch-signal',
target: {
type: 'bpmn:IntermediateCatchEvent',
eventDefinitionType: 'bpmn:SignalEventDefinition'
}
},
{
label: 'Signal intermediate throw event',
actionName: 'replace-with-signal-intermediate-throw',
className: 'bpmn-icon-intermediate-event-throw-signal',
target: {
type: 'bpmn:IntermediateThrowEvent',
eventDefinitionType: 'bpmn:SignalEventDefinition'
}
},
{
label: 'Signal end event',
actionName: 'replace-with-signal-end',
className: 'bpmn-icon-end-event-signal',
target: {
type: 'bpmn:EndEvent',
eventDefinitionType: 'bpmn:SignalEventDefinition'
}
}
],
'bpmn:ErrorEventDefinition': [
{
label: 'Error start event',
actionName: 'replace-with-error-start',
className: 'bpmn-icon-start-event-error',
target: {
type: 'bpmn:StartEvent',
eventDefinitionType: 'bpmn:ErrorEventDefinition'
}
},
{
label: 'Error end event',
actionName: 'replace-with-error-end',
className: 'bpmn-icon-end-event-error',
target: {
type: 'bpmn:EndEvent',
eventDefinitionType: 'bpmn:ErrorEventDefinition'
}
}
],
'bpmn:EscalationEventDefinition': [
{
label: 'Escalation start event',
actionName: 'replace-with-escalation-start',
className: 'bpmn-icon-start-event-escalation',
target: {
type: 'bpmn:StartEvent',
eventDefinitionType: 'bpmn:EscalationEventDefinition'
}
},
{
label: 'Escalation intermediate throw event',
actionName: 'replace-with-escalation-intermediate-throw',
className: 'bpmn-icon-intermediate-event-throw-escalation',
target: {
type: 'bpmn:IntermediateThrowEvent',
eventDefinitionType: 'bpmn:EscalationEventDefinition'
}
},
{
label: 'Escalation end event',
actionName: 'replace-with-escalation-end',
className: 'bpmn-icon-end-event-escalation',
target: {
type: 'bpmn:EndEvent',
eventDefinitionType: 'bpmn:EscalationEventDefinition'
}
}
],
'bpmn:CompensateEventDefinition': [
{
label: 'Compensation start event',
actionName: 'replace-with-compensation-start',
className: 'bpmn-icon-start-event-compensation',
target: {
type: 'bpmn:StartEvent',
eventDefinitionType: 'bpmn:CompensateEventDefinition'
}
},
{
label: 'Compensation intermediate throw event',
actionName: 'replace-with-compensation-intermediate-throw',
className: 'bpmn-icon-intermediate-event-throw-compensation',
target: {
type: 'bpmn:IntermediateThrowEvent',
eventDefinitionType: 'bpmn:CompensateEventDefinition'
}
},
{
label: 'Compensation end event',
actionName: 'replace-with-compensation-end',
className: 'bpmn-icon-end-event-compensation',
target: {
type: 'bpmn:EndEvent',
eventDefinitionType: 'bpmn:CompensateEventDefinition'
}
}
]
};
38 changes: 33 additions & 5 deletions test/fixtures/bpmn/features/replace/01_replace.bpmn
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?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:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.1.1">
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.23.0">
<bpmn:process id="Process_1" isExecutable="false">
<bpmn:startEvent id="StartEvent_1" name="KEEP ME">
<bpmn:outgoing>SequenceFlow_1</bpmn:outgoing>
Expand Down Expand Up @@ -70,9 +70,25 @@
<bpmn:startEvent id="StartEvent_5">
<bpmn:messageEventDefinition id="MessageEventDefinition_0mynzm8" />
</bpmn:startEvent>
<bpmn:subProcess id="SubProcess_2" />
<bpmn:subProcess id="EventSubProcess_2" triggeredByEvent="true" />
<bpmn:subProcess id="SubProcess_2">
<bpmn:intermediateCatchEvent id="IntermediateCatchMessageEvent">
<bpmn:messageEventDefinition id="MessageEventDefinition_0ntrjf5" />
</bpmn:intermediateCatchEvent>
<bpmn:intermediateThrowEvent id="CompensationEvent">
<bpmn:compensateEventDefinition id="CompensateEventDefinition_0xibqo0" />
</bpmn:intermediateThrowEvent>
</bpmn:subProcess>
<bpmn:subProcess id="EventSubProcess_2" triggeredByEvent="true">
<bpmn:endEvent id="ErrorEvent">
<bpmn:errorEventDefinition id="ErrorEventDefinition_1wj8dp2" />
</bpmn:endEvent>
</bpmn:subProcess>
<bpmn:complexGateway id="ComplexGateway_1" />
<bpmn:intermediateCatchEvent id="ConditionalEvent">
<bpmn:conditionalEventDefinition id="ConditionalEventDefinition_0ubws14">
<bpmn:condition xsi:type="bpmn:tFormalExpression" />
</bpmn:conditionalEventDefinition>
</bpmn:intermediateCatchEvent>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
Expand All @@ -97,8 +113,8 @@
<dc:Bounds x="669" y="70" width="90" height="20" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Gateway_1g9qldn_di" bpmnElement="ComplexGateway_1">
<dc:Bounds x="212" y="825" width="50" height="50" />
<bpmndi:BPMNShape id="Event_0o3fiwu_di" bpmnElement="ConditionalEvent">
<dc:Bounds x="872" y="480" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="SubProcess_1_di" bpmnElement="SubProcess_1" isExpanded="true">
<dc:Bounds x="221" y="208" width="350" height="200" />
Expand Down Expand Up @@ -165,9 +181,21 @@
<bpmndi:BPMNShape id="Activity_0cb78c0_di" bpmnElement="SubProcess_2" isExpanded="true">
<dc:Bounds x="221" y="590" width="350" height="200" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0snvrjf_di" bpmnElement="IntermediateCatchMessageEvent">
<dc:Bounds x="262" y="672" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0jo3l8m_di" bpmnElement="CompensationEvent">
<dc:Bounds x="412" y="672" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0cmryx4_di" bpmnElement="EventSubProcess_2" isExpanded="true">
<dc:Bounds x="659" y="590" width="193" height="200" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0pr5js5_di" bpmnElement="ErrorEvent">
<dc:Bounds x="752" y="662" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Gateway_1g9qldn_di" bpmnElement="ComplexGateway_1">
<dc:Bounds x="212" y="825" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BoundaryEvent_2_di" bpmnElement="BoundaryEvent_2">
<dc:Bounds x="382" y="144" width="36" height="36" />
<bpmndi:BPMNLabel>
Expand Down
Loading

0 comments on commit 0a7c5f3

Please sign in to comment.