Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/FOUR-10790: Multiplayer support for boundary events #1689

Merged
merged 31 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
b8d1a50
Add support for boundaries
agustinbusso Oct 11, 2023
be8fcda
Remove unused parameter
agustinbusso Oct 11, 2023
0ef9b59
Emit only if boundary was created from crown
agustinbusso Oct 11, 2023
38e9e1b
Remove comments and unneeded code
agustinbusso Oct 11, 2023
d8338bc
Add position change when dragging the boundary
agustinbusso Oct 11, 2023
c2ae3a1
Remove logs and unused code
agustinbusso Oct 12, 2023
e78fdd6
Fix issue with position when moving the parent task
agustinbusso Oct 12, 2023
0e1ae3f
Remove unused
agustinbusso Oct 12, 2023
49a4d5c
Improve code
agustinbusso Oct 12, 2023
2b6bbb3
Remove unused const
agustinbusso Oct 12, 2023
a377c74
Attach boundary to new task
agustinbusso Oct 12, 2023
5a5bba3
Merge branch 'next' into feature/FOUR-10790
agustinbusso Oct 12, 2023
3430b2d
Address comments
agustinbusso Oct 12, 2023
b992a77
Merge branch 'feature/FOUR-10790' of https://github.com/ProcessMaker/…
agustinbusso Oct 12, 2023
4e8b766
Merge branch 'next' into feature/FOUR-10790
agustinbusso Oct 16, 2023
4e380f8
Comments addressed
agustinbusso Oct 16, 2023
f8f3fb1
Merge branch 'feature/FOUR-10790' of https://github.com/ProcessMaker/…
agustinbusso Oct 16, 2023
e748b9a
Merge branch 'next' into feature/FOUR-10790
agustinbusso Oct 17, 2023
a290038
merge boundary with containers
Oct 17, 2023
95c0017
remove unsed file
Oct 17, 2023
ce89a4b
solve merge conflicts
Oct 18, 2023
3d467ea
Merge branch 'next' into feature/FOUR-10790
agustinbusso Oct 18, 2023
1aac724
merge with next
Oct 20, 2023
9b690e1
Merge branch 'next' into feature/FOUR-10790
agustinbusso Oct 20, 2023
7e4d1ce
Fix color issue in boundaries
agustinbusso Oct 20, 2023
26b4c03
Merge branch 'next' into feature/FOUR-10790
agustinbusso Oct 20, 2023
16b7f12
test: update boundary timer event, message flow e2e
Oct 23, 2023
cc210c6
Merge branch 'next' into feature/FOUR-10790
Oct 23, 2023
e9617aa
feat: refactor multiplayer for boundary events and flows
Oct 23, 2023
dc31662
ref: rename fn for common elements
Oct 23, 2023
4c7ce84
test: enable skiped tests in boundary timer event
Oct 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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