Colaboration messages vs API messages

This commit is contained in:
Ayoub Ait Lachgar 2024-02-06 09:44:16 +01:00
parent c5562046de
commit 450cd42b0c
5 changed files with 203 additions and 125 deletions

View File

@ -218,6 +218,15 @@ IoPalette.prototype.getPaletteEntries = function (e) {
click: createShape('bpmn:BusinessRuleTask')
}
},
'create.send-task': {
group: 'advanced',
className: 'bpmn-icon-send-task',
title: translate('Send Task'),
action: {
dragstart: createShape('bpmn:SendTask'),
click: createShape('bpmn:SendTask')
}
},
'create.participant': {
group: 'advanced',
className: 'bpmn-icon-participant',

View File

@ -33,11 +33,15 @@ export function isMessageElement(shapeElement) {
}
export function isMessageEvent(shapeElement) {
const { eventDefinitions } = shapeElement.businessObject;
if (eventDefinitions && eventDefinitions[0]) {
return eventDefinitions[0].$type === 'bpmn:MessageEventDefinition';
try {
const { eventDefinitions } = shapeElement.businessObject;
if (eventDefinitions && eventDefinitions[0]) {
return eventDefinitions[0].$type === 'bpmn:MessageEventDefinition';
}
return false;
} catch (error) {
return false;
}
return false;
}
export function canReceiveMessage(shapeElement) {
@ -158,6 +162,34 @@ export function findCorrelationProperties(businessObject, moddle) {
return correlationProperties;
}
export function findCorrelationPropertiesByMessage(element) {
let messageId;
const { businessObject } = element;
const root = getRoot(businessObject);
const correlationProperties = [];
if(isMessageEvent(element)){
messageId = businessObject.eventDefinitions[0].messageRef.id;
} else if(isMessageElement(element)){
if(!businessObject.messageRef) return;
messageId = businessObject.messageRef.id;
}
if (isIterable(root.rootElements)) {
for (const rootElement of root.rootElements) {
if (rootElement.$type === 'bpmn:CorrelationProperty') {
rootElement.correlationPropertyRetrievalExpression = (rootElement.correlationPropertyRetrievalExpression)? rootElement.correlationPropertyRetrievalExpression : [];
const existingExpressionIndex = rootElement.correlationPropertyRetrievalExpression.findIndex(retrievalExpr =>
retrievalExpr.messageRef && retrievalExpr.messageRef.id === messageId
);
(existingExpressionIndex !== -1) ? correlationProperties.push(rootElement): null;
}
}
}
return correlationProperties;
}
function isIterable(obj) {
// checks for null and undefined
if (obj == null) {
@ -209,32 +241,34 @@ export function findMessageElement(businessObject, messageId) {
return null;
}
export function createOrUpdateCorrelationProperties(bpmnFactory, commandStack, element, definitions, propertiesConfig, messageId) {
export function createOrUpdateCorrelationProperties(bpmnFactory, commandStack, element, propertiesConfig, messageId) {
let definitions = getRoot(element.businessObject);
// Iterate over each property configuration
propertiesConfig.forEach(propConfig => {
if (isMessageIdInRetrievalExpressions(propConfig, messageId)) {
let correlationProperty = findCorrelationPropertyById(definitions, propConfig.id);
let correlationProperty = findCorrelationPropertyById(definitions, propConfig.id);
// If the correlationProperty does not exist, create it
if (!correlationProperty) {
let isCorrelated = false;
const correlationProperty = bpmnFactory.create(
'bpmn:CorrelationProperty'
);
correlationProperty.id = propConfig.id;
correlationProperty.name = propConfig.id;
if (!correlationProperty.correlationPropertyRetrievalExpression) {
// If the correlationProperty does not exist, create it
if (correlationProperty === null) {
correlationProperty = bpmnFactory.create(
'bpmn:CorrelationProperty'
);
correlationProperty.id = propConfig.id;
correlationProperty.name = propConfig.id;
correlationProperty.correlationPropertyRetrievalExpression = [];
} else if (correlationProperty && !correlationProperty.correlationPropertyRetrievalExpression) {
correlationProperty.correlationPropertyRetrievalExpression = [];
}
// Iterate over retrieval expressions and add them to the correlationProperty
propConfig.retrieval_expressions.forEach(expr => {
if(expr.message_ref == messageId){
const existingExpressionIndex = correlationProperty.correlationPropertyRetrievalExpression.findIndex(retrievalExpr =>
retrievalExpr.messageRef && retrievalExpr.messageRef.id === messageId
);
if (expr.message_ref == messageId && existingExpressionIndex === -1) {
const retrievalExpression = bpmnFactory.create('bpmn:CorrelationPropertyRetrievalExpression');
const formalExpression = bpmnFactory.create('bpmn:FormalExpression');
formalExpression.body = (expr.formal_expression) ? expr.formal_expression : '';
@ -242,36 +276,54 @@ export function createOrUpdateCorrelationProperties(bpmnFactory, commandStack, e
const msgElement = findMessageElement(element.businessObject, expr.message_ref);
retrievalExpression.messageRef = msgElement;
correlationProperty.correlationPropertyRetrievalExpression.push(retrievalExpression);
isCorrelated = true;
}
});
if(isCorrelated){
const existingIndex = definitions.rootElements.findIndex(element =>
element.id === correlationProperty.id && element.$type === correlationProperty.$type);
if (existingIndex !== -1) {
// Update existing correlationProperty
definitions.rootElements[existingIndex] = correlationProperty;
} else {
// Add new correlationProperty
definitions.rootElements.push(correlationProperty);
commandStack.execute('element.updateProperties', {
element,
properties: {},
});
}
commandStack.execute('element.updateProperties', {
element,
properties: {},
});
}
});
// Save or re-render the model as needed
}
export function findCorrelationPropertyById(definitions, id) {
let foundCorrelationProperty = null;
definitions.rootElements.forEach(rootElement => {
if (rootElement.correlationProperties && rootElement.correlationProperties.length > 0) {
const correlationProperty = rootElement.correlationProperties.find(cp => cp.id === id);
if (correlationProperty) {
foundCorrelationProperty = correlationProperty;
return;
}
if (rootElement.$type === 'bpmn:CorrelationProperty' && rootElement.id === id) {
foundCorrelationProperty = rootElement;
}
});
return foundCorrelationProperty;
}
export function isMessageRefUsed(definitions, messageRef) {
definitions.rootElements.forEach(rootElement => {
if (rootElement.$type == 'bpmn:Process') {
const process = rootElement;
process.flowElements.forEach(element => {
if (isMessageElement(element)) {
if (element.messageRef === messageRef) {
return true;
}
}
});
}
});
return false;
}
function isMessageIdInRetrievalExpressions(propConfig, messageId) {
return propConfig.retrieval_expressions.some(expr => expr.message_ref === messageId);
}

View File

@ -7,9 +7,10 @@ import {
import {
getRoot,
findCorrelationKeys,
findCorrelationProperties,
findCorrelationKeyForCorrelationProperty,
findCorrelationPropertyById,
findCorrelationPropertiesByMessage,
isMessageEvent,
isMessageElement
} from '../MessageHelpers';
import { removeFirstInstanceOfItemFromArrayInPlace } from '../../helpers';
@ -22,15 +23,12 @@ export function CorrelationPropertiesList(props) {
const { commandStack } = props;
const { translate } = props;
const correlationPropertyArray = findCorrelationProperties(
element.businessObject
const correlationPropertyArray = findCorrelationPropertiesByMessage(
element
);
// console.log('correlationPropertyArray', correlationPropertyArray)
const items = correlationPropertyArray.map(
const items = (correlationPropertyArray) ? correlationPropertyArray.map(
(correlationPropertyModdleElement, index) => {
// console.log('correlationPropertyModdleElement', correlationPropertyModdleElement)
const id = `correlation-${index}`;
@ -56,7 +54,7 @@ export function CorrelationPropertiesList(props) {
// }),
};
}
);
): [];
function add(event) {
event.stopPropagation();
@ -93,13 +91,11 @@ export function CorrelationPropertiesList(props) {
});
}
// console.log({ items, add });
return { items, add };
}
function removeFactory(props) {
const { element, correlationPropertyModdleElement, moddle, commandStack } =
props;
const { element, correlationPropertyModdleElement, moddle, commandStack } = props;
return function (event) {
event.stopPropagation();
@ -167,25 +163,25 @@ function CorrelationPropertyRetrivialExpressionTextField(props) {
const setValue = (value) => {
const message = (isMessageEvent(element)) ? element.businessObject.eventDefinitions[0].messageRef : element.businessObject.messageRef;
const process = element.businessObject.$parent;
const definitions = process.$parent;
if (!definitions.get('rootElements')) {
definitions.set('rootElements', []);
}
definitions.rootElements.forEach(rootElement => {
if(rootElement.id == correlationPropertyModdleElement.id && rootElement.$type == 'bpmn:CorrelationProperty'){
if (rootElement.correlationPropertyRetrievalExpression && rootElement.correlationPropertyRetrievalExpression.length > 0) {
const correlationProperty = rootElement.correlationPropertyRetrievalExpression.find(cp => cp.messageRef === element.businessObject.messageRef);
if(correlationProperty){
correlationProperty.messagePath.body = value;
commandStack.execute('element.updateProperties', {
element,
properties: {},
});
return;
}
const matchingRetrievalExpression = rootElement.correlationPropertyRetrievalExpression.find(expr =>
expr.messageRef && expr.messageRef === message
);
if(matchingRetrievalExpression){
matchingRetrievalExpression.messagePath.body = value;
commandStack.execute('element.updateProperties', {
element,
properties: {},
});
return;
}
}
});
@ -193,7 +189,14 @@ function CorrelationPropertyRetrivialExpressionTextField(props) {
};
const getValue = () => {
return correlationPropertyModdleElement.correlationPropertyRetrievalExpression[0].messagePath.body;
const message = (isMessageEvent(element)) ? element.businessObject.eventDefinitions[0].messageRef : element.businessObject.messageRef;
const matchingRetrievalExpression = correlationPropertyModdleElement.correlationPropertyRetrievalExpression.find(expr =>
expr.messageRef && expr.messageRef === message
);
return (matchingRetrievalExpression) ? matchingRetrievalExpression.messagePath.body : '' ;
};
return TextFieldEntry({

View File

@ -2,10 +2,12 @@ import { useService } from 'bpmn-js-properties-panel';
import { SelectEntry } from '@bpmn-io/properties-panel';
import {
createOrUpdateCorrelationProperties,
findCorrelationPropertiesAndRetrievalExpressionsForMessage,
findMessageModdleElements,
getMessageRefElement,
getRoot,
isMessageElement,
isMessageEvent,
isMessageRefUsed,
} from '../MessageHelpers';
export const spiffExtensionOptions = {};
@ -28,62 +30,68 @@ export function MessageSelect(props) {
return '';
};
const setValue = (value) => {
const setValue = async (value) => {
// Define variables
const messageId = value;
const { businessObject } = element;
const oldMessageRef = businessObject.messageRef;
const { businessObject } = shapeElement;
/* Need to add the selected message as the messageRef on the current message task */
// const messages = spiffExtensionOptions['spiff.messages']
const messages = findMessageModdleElements(shapeElement.businessObject);
// Check if message selected is already created
// Message Creation
// console.log('setValue ', messageId);
// console.log('spiffExtensionOptions', spiffExtensionOptions);
// console.log('businessObject ', businessObject);
// console.log('messages', messages);
// console.log('commandStack', commandStack);
// Add DataStore to the BPMN model
const process = element.businessObject.$parent;
const definitions = process.$parent;
let definitions = getRoot(element.businessObject);
if (!definitions.get('rootElements')) {
definitions.set('rootElements', []);
}
// console.log('process', process);
// console.log('definitions', definitions);
// Retrieve Message
let bpmnMessage = definitions.get('rootElements').find(element =>
element.$type === 'bpmn:Message' && element.name === messageId
element.$type === 'bpmn:Message' && (element.id === messageId || element.name === messageId)
);
// If the Message doesn't exist, create new one
if (!bpmnMessage) {
bpmnMessage = bpmnFactory.create('bpmn:Message', {
id: messageId,
name: messageId
});
definitions.get('rootElements').push(bpmnMessage);
}
// Update Element messageReg with new Message Created
commandStack.execute('element.updateModdleProperties', {
element: shapeElement,
moddleElement: businessObject,
properties: {
messageRef: bpmnMessage,
},
});
// Update messageRef of current Element
if (isMessageEvent(shapeElement)) {
const messageEventDefinition = element.businessObject.eventDefinitions[0];
messageEventDefinition.messageRef = bpmnMessage;
// call this to update the other elements in the props panel like payload
commandStack.execute('element.updateModdleProperties', {
element: element,
moddleElement: element.businessObject,
properties: {}
});
} else if (isMessageElement(shapeElement)) {
element.businessObject.messageRef = bpmnMessage;
commandStack.execute('element.updateProperties', {
element: element,
properties: {},
});
}
createOrUpdateCorrelationProperties(bpmnFactory, commandStack, element, definitions, spiffExtensionOptions['spiff.correlation_properties'], messageId)
// Add Correlation Properties of for the new message
createOrUpdateCorrelationProperties(bpmnFactory, commandStack, element, spiffExtensionOptions['spiff.correlation_properties'], messageId);
return;
// Remove previous message in case it's not used anymore
if (oldMessageRef && !isMessageRefUsed(definitions, oldMessageRef)) {
const rootElements = definitions.get('rootElements');
const oldMessageIndex = rootElements.findIndex(element => element.$type === 'bpmn:Message' && element.id === oldMessageRef.id);
if (oldMessageIndex !== -1) {
rootElements.splice(oldMessageIndex, 1);
definitions.rootElements = rootElements;
}
}
};
const oldsetValue = (value) => {
const messages = findMessageModdleElements(shapeElement.businessObject);
for (const message of messages) {
if (message.id === value) {
if (isMessageEvent(shapeElement)) {
@ -118,7 +126,6 @@ export function MessageSelect(props) {
}
}
}
};
requestOptions(eventBus);
@ -141,7 +148,9 @@ export function MessageSelect(props) {
});
});
}
return options;
const uniqueArray = removeDuplicatesByLabel(options);
return uniqueArray;
};
return (
@ -167,3 +176,9 @@ function requestOptions(eventBus) {
eventBus.fire(`spiff.messages.requested`, { eventBus });
}
function removeDuplicatesByLabel(array) {
const seen = new Map();
return array.filter(item => {
return seen.has(item.label) ? false : seen.set(item.label, true);
});
}

View File

@ -6,7 +6,6 @@ import { MessagePayload } from './MessagePayload';
import { MessageVariable } from './MessageVariable';
import { CorrelationPropertiesArray } from './CorrelationPropertiesArray';
import { CorrelationPropertiesList } from './CorrelationPropertiesList';
import { MessageCorrelationPropertiesArray } from './MessageCorrelationPropertiesArray';
import { MessageArray } from './MessageArray';
import { isMessageElement, canReceiveMessage } from '../MessageHelpers';
import { CorrelationCheckboxEntry } from './CorrelationCheckbox';
@ -98,19 +97,6 @@ function createCollaborationGroup(
translate,
}),
},
{
id: 'correlation_properties',
label: translate('Correlation Properties'),
isDefault: true,
component: ListGroup,
...CorrelationPropertiesArray({
element,
moddle,
commandStack,
elementRegistry,
translate,
}),
},
{
id: 'correlation_keys',
label: translate('Correlation Keys'),
@ -124,6 +110,19 @@ function createCollaborationGroup(
translate,
}),
},
{
id: 'correlation_properties',
label: translate('Correlation Properties'),
isDefault: true,
component: ListGroup,
...CorrelationPropertiesArray({
element,
moddle,
commandStack,
elementRegistry,
translate,
}),
}
];
}
@ -171,18 +170,18 @@ function createMessageGroup(
});
}
entries.push({
id: 'correlationProperties',
label: translate('Correlation'),
component: ListGroup,
...MessageCorrelationPropertiesArray({
element,
moddle,
commandStack,
elementRegistry,
translate,
}),
});
// entries.push({
// id: 'correlationProperties',
// label: translate('Correlation'),
// component: ListGroup,
// ...MessageCorrelationPropertiesArray({
// element,
// moddle,
// commandStack,
// elementRegistry,
// translate,
// }),
// });
entries.push({
id: 'isCorrelated',