Skip to content

Commit

Permalink
Merge branch 'epic/FOUR-9674' of https://github.com/ProcessMaker/modeler
Browse files Browse the repository at this point in the history
 into epic/FOUR-9674
  • Loading branch information
agustinbusso committed Oct 6, 2023
2 parents 9f0be04 + 40b52e3 commit 2927735
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 14 deletions.
42 changes: 35 additions & 7 deletions src/components/modeler/Modeler.vue
Original file line number Diff line number Diff line change
Expand Up @@ -1148,7 +1148,9 @@ export default {
});
},
async removeNode(node, options) {
if (this.isMultiplayer) {
// Check if the node is not replaced
if (this.isMultiplayer && !options?.isReplaced) {
// Emit event to server to remove node
window.ProcessMaker.EventBus.$emit('multiplayer-removeNode', node);
}
this.removeNodeProcedure(node, options);
Expand Down Expand Up @@ -1201,18 +1203,44 @@ export default {
this.performSingleUndoRedoTransaction(async() => {
await this.paperManager.performAtomicAction(async() => {
const { x: clientX, y: clientY } = this.paper.localToClientPoint(node.diagram.bounds);
const newNode = await this.handleDropProcedure({
const nodeData = {
clientX, clientY,
control: { type: typeToReplaceWith },
nodeThatWillBeReplaced: node,
});
await this.removeNode(node, { removeRelationships: false });
this.highlightNode(newNode);
this.selectNewNode(newNode);
};
if (this.isMultiplayer) {
// Get all node types
const nodeTypes = nodeTypesStore.getters.getNodeTypes;
// Get the new control
const newControl = nodeTypes.flatMap(nodeType => {
return nodeType.items?.filter(item => item.type === typeToReplaceWith);
}).filter(Boolean);
// If the new control is found, emit event to server to replace node
if (newControl.length === 1) {
window.ProcessMaker.EventBus.$emit('multiplayer-replaceNode', { nodeData, newControl: newControl[0] });
}
} else {
await this.replaceNodeProcedure(nodeData);
}
});
});
},
async replaceNodeProcedure(data, isReplaced = false) {
if (isReplaced) {
// Get the clientX and clientY from the node that will be replaced
const { x: clientX, y: clientY } = this.paper.localToClientPoint(data.nodeThatWillBeReplaced.diagram.bounds);
data.clientX = clientX;
data.clientY = clientY;
}
const newNode = await this.handleDropProcedure(data);
await this.removeNode(data.nodeThatWillBeReplaced, { removeRelationships: false, isReplaced });
this.highlightNode(newNode);
this.selectNewNode(newNode);
},
replaceAiNode({ node, typeToReplaceWith, assetId, assetName, redirectTo }) {
this.performSingleUndoRedoTransaction(async() => {
await this.paperManager.performAtomicAction(async() => {
Expand Down
62 changes: 55 additions & 7 deletions src/multiplayer/multiplayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,17 @@ export default class Multiplayer {

// Listen for updates when a element is updated
this.clientIO.on('updateElement', (payload) => {
const { updateDoc, updatedNodes } = payload;
const { updateDoc, updatedNodes, isReplaced } = payload;

// Update the elements in the process
updatedNodes.forEach((data) => {
this.updateShapes(data);
});
if (isReplaced) {
// Replace the element in the process
this.replaceShape(updatedNodes[0]);
} else {
// Update the elements in the process
updatedNodes.forEach((data) => {
this.updateShapes(data);
});
}

// Update the element in the shared array
Y.applyUpdate(this.yDoc, new Uint8Array(updateDoc));
Expand All @@ -127,6 +132,11 @@ export default class Multiplayer {
window.ProcessMaker.EventBus.$on('multiplayer-updateNodes', ( data ) => {
this.updateNodes(data);
});

window.ProcessMaker.EventBus.$on('multiplayer-replaceNode', ({ nodeData, newControl }) => {
this.replaceNode(nodeData, newControl);
});

window.ProcessMaker.EventBus.$on('multiplayer-addFlow', ( data ) => {
this.addFlow(data);
});
Expand Down Expand Up @@ -208,6 +218,43 @@ export default class Multiplayer {
this.doTransact(nodeToUpdate, value.properties);
});
}
replaceNode(nodeData, newControl) {
// Get the node to update
const index = this.getIndex(nodeData.nodeThatWillBeReplaced.definition.id);
const nodeToUpdate = this.yArray.get(index);
// Update the node id in the nodeData
nodeData.id = `node_${this.#nodeIdGenerator.getDefinitionNumber()}`;
// Replace the node in the process
this.modeler.replaceNodeProcedure(nodeData, true);
// Update the node id generator
this.#nodeIdGenerator.updateCounters();
// Update the node in the shared array
this.yDoc.transact(() => {
nodeToUpdate.set('control', newControl);
nodeToUpdate.set('id', nodeData.id);
});

// 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) {
// Get the node to update
const node = this.getNodeById(updatedNode.oldNodeId);
// Update the node id in the nodeData
const nodeData = {
clientX: updatedNode.clientX,
clientY: updatedNode.clientY,
control: { type: updatedNode.control.type },
nodeThatWillBeReplaced: node,
id: updatedNode.id,
};

// Replace the node in the process
this.modeler.replaceNodeProcedure(nodeData, true);
this.#nodeIdGenerator.updateCounters();
}
doTransact(yMapNested, data) {
this.yDoc.transact(() => {
for (const key in data) {
Expand All @@ -220,7 +267,7 @@ export default class Multiplayer {
// Encode the state as an update and send it to the server
const stateUpdate = Y.encodeStateAsUpdate(this.yDoc);
// Send the update to the web socket server
this.clientIO.emit('updateElement', stateUpdate);
this.clientIO.emit('updateElement', { updateDoc: stateUpdate, isReplaced: false });
}
updateShapes(data) {
const { paper } = this.modeler;
Expand Down Expand Up @@ -261,7 +308,8 @@ export default class Multiplayer {
const actualFlow = flow.makeFlowNode(sourceElem, targetElem, data.waypoint);
// add Nodes
this.modeler.addNode(actualFlow, data.id);
this.#nodeIdGenerator.updateCounters();
}

}
}

0 comments on commit 2927735

Please sign in to comment.