Skip to content

Commit

Permalink
Merge pull request #1689 from ProcessMaker/feature/FOUR-10790
Browse files Browse the repository at this point in the history
Feature/FOUR-10790: Multiplayer support for boundary events
  • Loading branch information
ryancooley authored Oct 24, 2023
2 parents 7e79558 + 4c7ce84 commit 267459b
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export default {
const node = new Node(nodeType, definition, diagram);
node.pool = this.node.pool;
node.fromCrown = true;
store.commit('highlightNode', node);
Expand Down
3 changes: 2 additions & 1 deletion src/components/crown/crownButtons/crownColorDropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export default {
store.commit('updateNodeProp', { node: this.node, key: 'color', value: color });
Vue.set(this.node.definition, 'color', color);
this.$emit('save-state');
const properties = {
id: this.node.definition.id,
properties: {
Expand All @@ -148,6 +148,7 @@ export default {
width: this.node.diagram.bounds.width,
type: this.node.type,
id: this.node.definition.id,
attachedToRefId: this.node.definition.get('attachedToRef')?.id,
},
};
window.ProcessMaker.EventBus.$emit('multiplayer-updateNodes', [properties]);
Expand Down
9 changes: 6 additions & 3 deletions src/components/modeler/Modeler.vue
Original file line number Diff line number Diff line change
Expand Up @@ -1094,7 +1094,6 @@ export default {
diagram.bounds.y = y;
const newNode = this.createNode(control.type, definition, diagram);
if (newNode.isBpmnType('bpmn:BoundaryEvent')) {
this.setShapeCenterUnderCursor(diagram);
}
Expand Down Expand Up @@ -1137,9 +1136,13 @@ export default {
'processmaker-modeler-sequence-flow',
'processmaker-modeler-association',
'processmaker-modeler-data-input-association',
'processmaker-modeler-data-output-association',
'processmaker-modeler-data-input-association',
'processmaker-modeler-boundary-timer-event',
'processmaker-modeler-boundary-error-event',
'processmaker-modeler-boundary-signal-event',
'processmaker-modeler-boundary-conditional-even',
'processmaker-modeler-boundary-message-event',
];
if (!this.isMultiplayer) {
return;
}
Expand Down
42 changes: 41 additions & 1 deletion src/components/modeler/Selection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ import { id as associationId } from '@/components/nodes/association/associationC
import { id as messageFlowId } from '@/components/nodes/messageFlow/config';
import { id as dataOutputAssociationFlowId } from '@/components/nodes/dataOutputAssociation/config';
import { id as dataInputAssociationFlowId } from '@/components/nodes/dataInputAssociation/config';
import { id as boundaryErrorEventId } from '@/components/nodes/boundaryErrorEvent';
import { id as boundaryConditionalEventId } from '@/components/nodes/boundaryConditionalEvent';
import { id as boundaryEscalationEventId } from '@/components/nodes/boundaryEscalationEvent';
import { id as boundaryMessageEventId } from '@/components/nodes/boundaryMessageEvent';
import { id as boundarySignalEventId } from '@/components/nodes/boundarySignalEvent';
import { id as boundaryTimerEventId } from '@/components/nodes/boundaryTimerEvent';
import { labelWidth, poolPadding } from '../nodes/pool/poolSizes';
import { invalidNodeColor, poolColor } from '@/components/nodeColors';
Expand Down Expand Up @@ -587,7 +593,6 @@ export default {
const shapesToNotTranslate = [
'PoolLane',
'standard.Link',
'processmaker.components.nodes.boundaryEvent.Shape',
];
shapes.filter(shape => !shapesToNotTranslate.includes(shape.model.get('type')))
Expand All @@ -604,6 +609,7 @@ export default {
y: shape.model.get('position').y,
height: shape.model.get('size').height,
width: shape.model.get('size').width,
attachedToRefId: shape.model.component.node.definition.get('attachedToRef')?.id ?? null,
color: shape.model.get('color'),
},
};
Expand All @@ -612,9 +618,43 @@ export default {
}
changed.push(defaultData);
}
const boundariesChanges = this.getBoundariesChangesForShape(shape);
changed = changed.concat(boundariesChanges);
});
return changed;
},
/**
* Get properties for each boundary inside a shape
*/
getBoundariesChangesForShape(shape) {
let boundariesChanged = [];
const boundaryEventTypes = [
boundaryErrorEventId,
boundaryConditionalEventId,
boundaryEscalationEventId,
boundaryMessageEventId,
boundarySignalEventId,
boundaryTimerEventId,
];
const boundaryNodes = store.getters.nodes.filter(node => boundaryEventTypes.includes(node.type));
boundaryNodes.forEach(boundaryNode => {
if (boundaryNode.definition.attachedToRef.id === shape.model.component.node.definition.id) {
boundariesChanged.push({
id: boundaryNode.definition.id,
properties: {
x: boundaryNode.diagram.bounds.x,
y: boundaryNode.diagram.bounds.y,
height: boundaryNode.diagram.bounds.height,
width: boundaryNode.diagram.bounds.width,
attachedToRefId: boundaryNode.definition.get('attachedToRef')?.id ?? null,
color: boundaryNode.definition.get('color') ?? null,
},
});
}
});
return boundariesChanged;
},
getContainerProperties(children) {
const changed = [];
children.forEach(model => {
Expand Down
24 changes: 24 additions & 0 deletions src/components/nodes/boundaryEvent/boundaryEvent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,26 @@ export default {
this.invalidTargetElement = targetElement;
},
addMultiplayerBoundaryEvent() {
const control = {
bpmnType: this.node.diagram.$type,
id: this.node.diagram.id,
type: this.node.type,
attachedToRef: this.node.definition.get('attachedToRef'),
};
window.ProcessMaker.EventBus.$emit('multiplayer-addBoundaryEvent', {
x: this.node.diagram.bounds.x,
y: this.node.diagram.bounds.y,
height: this.node.diagram.bounds.height,
width: this.node.diagram.bounds.width,
attachedToRefId: this.node.definition.get('attachedToRef')?.id,
control,
type: this.node.type,
id: this.node.definition.id,
color: this.node.definition.get('color'),
});
},
},
async mounted() {
this.shape = new EventShape();
Expand All @@ -214,6 +234,10 @@ export default {
const task = this.getTaskUnderShape();
this.attachBoundaryEventToTask(task);
this.updateShapePosition(task);
if (this.node.fromCrown) {
this.addMultiplayerBoundaryEvent();
}
},
};
</script>
34 changes: 30 additions & 4 deletions src/multiplayer/multiplayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,11 @@ export default class Multiplayer {
});

window.ProcessMaker.EventBus.$on('multiplayer-addFlow', ( data ) => {
this.addFlow(data);
this.addCommonElement(data);
});

window.ProcessMaker.EventBus.$on('multiplayer-addBoundaryEvent', ( data ) => {
this.addCommonElement(data);
});

window.ProcessMaker.EventBus.$on('multiplayer-addLanes', ( lanes ) => {
Expand Down Expand Up @@ -246,7 +250,6 @@ export default class Multiplayer {

// Encode the state as an update and send it to the server
const stateUpdate = Y.encodeStateAsUpdate(this.yDoc);

this.clientIO.emit('updateElement', { updateDoc: stateUpdate, isReplaced: true });
}
replaceShape(updatedNode) {
Expand Down Expand Up @@ -327,6 +330,11 @@ export default class Multiplayer {
const node = this.getNodeById(data.id);
store.commit('updateNodeProp', { node, key: 'color', value: data.color });

// boundary type
if (element.component.node.definition.$type === 'bpmn:BoundaryEvent') {
this.attachBoundaryEventToNode(element, data);
}

// Trigger a rendering of the element on the paper
await paper.findViewByModel(element).update();
// validate if the parent pool was updated
Expand All @@ -337,8 +345,27 @@ export default class Multiplayer {
}
}
}
attachBoundaryEventToNode(element, data) {
const node = this.getNodeById(data.attachedToRefId);

// Find previous attached task
const previousAttachedTask = element.getParentCell();

// Find new attached task
const newAttachedTask = this.modeler.getElementByNodeId(data.attachedToRefId);

addFlow(data) {
if (previousAttachedTask) {
previousAttachedTask.unembed(element);
}

if (newAttachedTask) {
newAttachedTask.embed(element);
}

element.component.node.definition.set('attachedToRef', node.definition);
}
addCommonElement(data) {
// Add a new flow / boundary event to the shared array
const yMapNested = new Y.Map();
this.doTransact(yMapNested, data);
this.yArray.push([yMapNested]);
Expand All @@ -348,7 +375,6 @@ export default class Multiplayer {
this.clientIO.emit('createElement', { updateDoc: stateUpdate });
this.#nodeIdGenerator.updateCounters();
}

addLaneNodes(lanes) {
const pool = this.getPool(lanes);
window.ProcessMaker.EventBus.$emit('multiplayer-updateNodes', [{
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/specs/BoundaryTimerEvent.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,8 @@ describe('Boundary Timer Event', { scrollBehavior: false }, () => {
.trigger('mouseup')
.then(waitToRenderAllShapes)
.then(() => {
const task2Xml = '<bpmn:task id="node_12" name="Form Task" pm:assignment="requester" />';
const boundaryEventOnTask2Xml = '<bpmn:boundaryEvent id="node_11" name="Boundary Timer Event" attachedToRef="node_12">';
const task2Xml = '<bpmn:task id="node_13" name="Form Task" pm:assignment="requester" />';
const boundaryEventOnTask2Xml = '<bpmn:boundaryEvent id="node_11" name="Boundary Timer Event" attachedToRef="node_13">';

assertDownloadedXmlContainsExpected(task2Xml, boundaryEventOnTask2Xml);
assertDownloadedXmlDoesNotContainExpected(boundaryEventOnTaskXml);
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/specs/MessageFlows.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ describe('Message Flows', { scrollBehavior: false }, () => {
const boundaryEventId = 'node_22';
const endEventXml = `<bpmn:endEvent id="${endEventId}" name="Message End Event">`;
const boundaryEventXml = `<bpmn:boundaryEvent id="${boundaryEventId}" name="Boundary Message Event" attachedToRef="node_12">`;
const messageFlowXml = `<bpmn:messageFlow id="node_23" name="" sourceRef="${endEventId}" targetRef="${boundaryEventId}" />`;
const messageFlowXml = `<bpmn:messageFlow id="node_24" name="" sourceRef="${endEventId}" targetRef="${boundaryEventId}" />`;

assertDownloadedXmlContainsExpected(endEventXml, boundaryEventXml, messageFlowXml);
});
Expand Down

0 comments on commit 267459b

Please sign in to comment.