Feature/message editor improved UI (#1754)

* retrieval_expressions should be a string and not an array in this context w/ burnettk

* Improve message editor ui

* Check if CorrelationProperties arent synced

* Merge Imporoved UI for messages

* some linting fixes

* more linting

* some updates for linting and updated bpmn-js-spiffworkflow w/ burnettk

* removed unused console.log w/ burnettk

* fix language w/ burnettk

---------

Co-authored-by: jasquat <jasquat@users.noreply.github.com>
This commit is contained in:
Ayoub Ait Lachgar 2024-06-18 20:15:25 +01:00 committed by GitHub
parent 9957fc144a
commit 81f2f6191b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 371 additions and 173 deletions

View File

@ -24,14 +24,13 @@ class MessageDefinitionService:
models: list[MessageCorrelationPropertyModel] = []
for identifier, definition in correlation_property_group.items():
retrieval_expressions = definition.get("retrieval_expressions")
retrieval_expression = definition.get("retrieval_expression")
if not retrieval_expressions:
if not retrieval_expression:
current_app.logger.debug(f"Malformed correlation property: '{identifier}' in file @ '{location}'")
continue
for retrieval_expression in retrieval_expressions:
models.append(MessageCorrelationPropertyModel(identifier=identifier, retrieval_expression=retrieval_expression))
models.append(MessageCorrelationPropertyModel(identifier=identifier, retrieval_expression=retrieval_expression))
return models

View File

@ -5,32 +5,31 @@
"display_order": 40,
"parent_groups": null,
"messages": {
"table_seated": {
"correlation_properties": {
"table_number": {
"retrieval_expressions": ["table_number"]
},
"franchise_id": {
"retrieval_expressions": ["franchise_id"]
}
},
"schema": {}
},
"order_ready": {
"correlation_properties": {
"table_number": {
"retrieval_expressions": ["table_number"]
},
"franchise_id": {
"retrieval_expressions": ["franchise_id"]
}
},
"schema": {}
},
"end_of_day_receipts": {
"schema": {}
}
"messages": {
"table_seated": {
"correlation_properties": {
"table_number": {
"retrieval_expression": "table_number"
},
"franchise_id": {
"retrieval_expression": "franchise_id"
}
},
"schema": {}
},
"order_ready": {
"correlation_properties": {
"table_number": {
"retrieval_expression": "table_number"
},
"franchise_id": {
"retrieval_expression": "franchise_id"
}
},
"schema": {}
},
"end_of_day_receipts": {
"schema": {}
}
}
}

View File

@ -126,10 +126,10 @@ class TestMessages(BaseTest):
"table_seated": {
"correlation_properties": {
"table_number": {
"retrieval_expressions": ["table_number"],
"retrieval_expression": "table_number",
},
"franchise_id": {
"retrieval_expressions": ["franchise_id"],
"retrieval_expression": "franchise_id",
},
},
"schema": {},
@ -137,10 +137,10 @@ class TestMessages(BaseTest):
"order_ready": {
"correlation_properties": {
"table_number": {
"retrieval_expressions": ["table_number"],
"retrieval_expression": "table_number",
},
"franchise_id": {
"retrieval_expressions": ["franchise_id"],
"retrieval_expression": "franchise_id",
},
},
"schema": {},

View File

@ -7669,7 +7669,7 @@
},
"node_modules/bpmn-js-spiffworkflow": {
"version": "0.0.8",
"resolved": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#7f7707838acc30d03fae907bb72f5bec101882b5",
"resolved": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#fd7a9489d86bd9a8bd0f8c84eeba37c234443951",
"license": "LGPL",
"dependencies": {
"inherits": "^2.0.4",
@ -31216,7 +31216,11 @@
}
},
"bpmn-js-spiffworkflow": {
<<<<<<< HEAD
"version": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#fd7a9489d86bd9a8bd0f8c84eeba37c234443951",
=======
"version": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#7f7707838acc30d03fae907bb72f5bec101882b5",
>>>>>>> origin/main
"from": "bpmn-js-spiffworkflow@github:sartography/bpmn-js-spiffworkflow#main",
"requires": {
"inherits": "^2.0.4",

View File

@ -33,6 +33,7 @@ type OwnProps = {
restrictedWidth?: boolean;
submitButtonText?: string;
reactJsonSchemaForm?: string;
hideSubmitButton?: boolean;
};
export default function CustomForm({
@ -50,6 +51,7 @@ export default function CustomForm({
restrictedWidth = false,
submitButtonText,
reactJsonSchemaForm = 'carbon',
hideSubmitButton = false,
}: OwnProps) {
// set in uiSchema using the "ui:widget" key for a property
const rjsfWidgets = {
@ -500,7 +502,12 @@ export default function CustomForm({
let childrenToUse = children;
if (submitButtonText) {
childrenToUse = (
<Button type="submit" id="submit-button" disabled={disabled}>
<Button
type="submit"
id="submit-button"
disabled={disabled}
style={{ display: hideSubmitButton ? 'none' : 'unset' }}
>
{submitButtonText}
</Button>
);

View File

@ -4,6 +4,7 @@ import {
Checkmark,
Error,
// @ts-ignore
WarningAlt,
} from '@carbon/icons-react';
// @ts-ignore
import { Button } from '@carbon/react';
@ -38,6 +39,8 @@ export function Notification({
let iconComponent = <Checkmark className="notification-icon" />;
if (type === 'error') {
iconComponent = <Error className="notification-icon" />;
} else if (type === 'warning') {
iconComponent = <WarningAlt className="notification-icon" />;
}
if (timeout && onClose) {

View File

@ -1,4 +1,4 @@
import { useEffect, useState } from 'react';
import { useCallback, useEffect, useState } from 'react';
import CustomForm from '../CustomForm';
import {
ProcessGroup,
@ -12,6 +12,7 @@ import {
} from '../../helpers';
import HttpService from '../../services/HttpService';
import {
areCorrelationPropertiesInSync,
convertCorrelationPropertiesToRJSF,
mergeCorrelationProperties,
} from './MessageHelper';
@ -19,6 +20,7 @@ import { Notification } from '../Notification';
type OwnProps = {
modifiedProcessGroupIdentifier: string;
elementId: string;
messageId: string;
messageEvent: any;
correlationProperties: any;
@ -29,12 +31,123 @@ export function MessageEditor({
messageId,
messageEvent,
correlationProperties,
elementId,
}: OwnProps) {
const [processGroup, setProcessGroup] = useState<ProcessGroup | null>(null);
const [currentFormData, setCurrentFormData] = useState<any>(null);
const [displaySaveMessageMessage, setDisplaySaveMessageMessage] =
useState<boolean>(false);
const [currentMessageId, setCurrentMessageId] = useState<string | null>(null);
const [isSynced, setSynced] = useState<boolean>(true);
const updateCorrelationPropertiesOnProcessGroup = useCallback(
(currentMessagesForId: MessageDefinition, formData: any) => {
const newCorrelationProperties: CorrelationProperties = {
...currentMessagesForId.correlation_properties,
};
(formData.correlation_properties || []).forEach((formProp: any) => {
if (!(formProp.id in newCorrelationProperties)) {
newCorrelationProperties[formProp.id] = {
retrieval_expression: formProp.retrievalExpression,
};
}
});
Object.keys(currentMessagesForId.correlation_properties || []).forEach(
(propId: string) => {
const foundProp = (formData.correlation_properties || []).find(
(formProp: any) => {
return propId === formProp.id;
},
);
if (!foundProp) {
delete newCorrelationProperties[propId];
}
},
);
return newCorrelationProperties;
},
[],
);
const handleProcessGroupUpdateResponse = useCallback(
(
response: ProcessGroup,
messageIdentifier: string,
updatedMessagesForId: MessageDefinition,
) => {
setProcessGroup(response);
setDisplaySaveMessageMessage(true);
messageEvent.eventBus.fire('spiff.add_message.returned', {
name: messageIdentifier,
correlation_properties: updatedMessagesForId.correlation_properties,
elementId,
});
setSynced(true);
},
[elementId, messageEvent.eventBus],
);
const updateProcessGroupWithMessages = useCallback(
(formObject: RJSFFormObject) => {
const { formData } = formObject;
if (!processGroup) {
return;
}
// keep track of new and old message ids so we can handle renaming a message
const newMessageId = formData.messageId;
const oldMessageId = currentMessageId || newMessageId;
const processGroupForUpdate = { ...processGroup };
if (!processGroupForUpdate.messages) {
processGroupForUpdate.messages = {};
}
const currentMessagesForId: MessageDefinition =
(processGroupForUpdate.messages || {})[oldMessageId] || {};
const updatedMessagesForId = { ...currentMessagesForId };
const newCorrelationProperties =
updateCorrelationPropertiesOnProcessGroup(
currentMessagesForId,
formData,
);
updatedMessagesForId.correlation_properties = newCorrelationProperties;
try {
updatedMessagesForId.schema = JSON.parse(formData.schema || '{}');
} catch (e) {
// TODO: display error in a tag like we normally do
// eslint-disable-next-line no-alert
alert(`Invalid schema: ${e}`);
return;
}
processGroupForUpdate.messages[newMessageId] = updatedMessagesForId;
setCurrentMessageId(newMessageId);
const path = `/process-groups/${modifiedProcessGroupIdentifier}`;
HttpService.makeCallToBackend({
path,
successCallback: (response: ProcessGroup) =>
handleProcessGroupUpdateResponse(
response,
newMessageId,
updatedMessagesForId,
),
httpMethod: 'PUT',
postBody: processGroupForUpdate,
});
},
[
currentMessageId,
handleProcessGroupUpdateResponse,
modifiedProcessGroupIdentifier,
processGroup,
updateCorrelationPropertiesOnProcessGroup,
],
);
useEffect(() => {
const setInitialFormData = (newProcessGroup: ProcessGroup) => {
@ -46,7 +159,6 @@ export function MessageEditor({
correlationProperties,
newCorrelationProperties,
);
const jsonSchema =
(newProcessGroup.messages || {})[messageId]?.schema || {};
const newFormData = {
@ -60,6 +172,12 @@ export function MessageEditor({
setCurrentFormData(newFormData);
};
const processResult = (result: ProcessGroup) => {
const newIsSynced = areCorrelationPropertiesInSync(
result,
messageId,
correlationProperties,
);
setSynced(newIsSynced);
setProcessGroup(result);
setCurrentMessageId(messageId);
setPageTitle([result.display_name]);
@ -71,108 +189,21 @@ export function MessageEditor({
});
}, [modifiedProcessGroupIdentifier, correlationProperties, messageId]);
const handleProcessGroupUpdateResponse = (
response: ProcessGroup,
messageIdentifier: string,
updatedMessagesForId: MessageDefinition,
) => {
setProcessGroup(response);
setDisplaySaveMessageMessage(true);
messageEvent.eventBus.fire('spiff.add_message.returned', {
name: messageIdentifier,
correlation_properties: updatedMessagesForId.correlation_properties,
});
};
const updateCorrelationPropertiesOnProcessGroup = (
currentMessagesForId: MessageDefinition,
formData: any,
) => {
const newCorrelationProperties: CorrelationProperties = {
...currentMessagesForId.correlation_properties,
// Setup event listeners on message.save
useEffect(() => {
const handleSaveEvent = (_event: any) => {
updateProcessGroupWithMessages({
formData: currentFormData,
});
};
(formData.correlation_properties || []).forEach((formProp: any) => {
if (!(formProp.id in newCorrelationProperties)) {
newCorrelationProperties[formProp.id] = {
retrieval_expressions: [],
};
}
if (
!newCorrelationProperties[formProp.id].retrieval_expressions.includes(
formProp.retrievalExpression,
)
) {
newCorrelationProperties[formProp.id].retrieval_expressions.push(
formProp.retrievalExpression,
);
}
});
Object.keys(currentMessagesForId.correlation_properties || []).forEach(
(propId: string) => {
const foundProp = (formData.correlation_properties || []).find(
(formProp: any) => {
return propId === formProp.id;
},
);
if (!foundProp) {
delete newCorrelationProperties[propId];
}
},
);
return newCorrelationProperties;
};
messageEvent.eventBus.on('spiff.message.save', handleSaveEvent);
const updateProcessGroupWithMessages = (formObject: RJSFFormObject) => {
const { formData } = formObject;
if (!processGroup) {
return;
}
// keep track of new and old message ids so we can handle renaming a message
const newMessageId = formData.messageId;
const oldMessageId = currentMessageId || newMessageId;
const processGroupForUpdate = { ...processGroup };
if (!processGroupForUpdate.messages) {
processGroupForUpdate.messages = {};
}
const currentMessagesForId: MessageDefinition =
(processGroupForUpdate.messages || {})[oldMessageId] || {};
const updatedMessagesForId = { ...currentMessagesForId };
const newCorrelationProperties = updateCorrelationPropertiesOnProcessGroup(
currentMessagesForId,
formData,
);
updatedMessagesForId.correlation_properties = newCorrelationProperties;
try {
updatedMessagesForId.schema = JSON.parse(formData.schema || '{}');
} catch (e) {
// TODO: display error in a tag like we normally do
// eslint-disable-next-line no-alert
alert(`Invalid schema: ${e}`);
return;
}
processGroupForUpdate.messages[newMessageId] = updatedMessagesForId;
setCurrentMessageId(newMessageId);
const path = `/process-groups/${modifiedProcessGroupIdentifier}`;
HttpService.makeCallToBackend({
path,
successCallback: (response: ProcessGroup) =>
handleProcessGroupUpdateResponse(
response,
newMessageId,
updatedMessagesForId,
),
httpMethod: 'PUT',
postBody: processGroupForUpdate,
});
};
// Cleanup event listener on unmount
return () => {
messageEvent.eventBus.off('spiff.message.save', handleSaveEvent);
};
}, [currentFormData, messageEvent.eventBus, updateProcessGroupWithMessages]);
const schema = {
type: 'object',
@ -226,6 +257,7 @@ export function MessageEditor({
},
},
};
const uischema = {
schema: {
'ui:widget': 'textarea',
@ -265,6 +297,20 @@ export function MessageEditor({
Message has been saved
</Notification>
) : null}
{!isSynced && !displaySaveMessageMessage ? (
<Notification
title="Please Save the current message configuration"
type="warning"
hideCloseButton
timeout={4000}
onClose={() => setDisplaySaveMessageMessage(false)}
>
There is a difference between the message properties in this process
model and the shared message data stored with the process group.
Updating the message properties by saving is recommended to ensure
data consistency
</Notification>
) : null}
<CustomForm
id={currentMessageId || ''}
key={currentMessageId || ''}
@ -272,11 +318,13 @@ export function MessageEditor({
uiSchema={uischema}
formData={currentFormData}
onSubmit={updateProcessGroupWithMessages}
submitButtonText="Save"
hideSubmitButton
onChange={updateFormData}
submitButtonText="Save"
/>
</>
);
}
return null;
}

View File

@ -23,11 +23,9 @@ export const convertCorrelationPropertiesToRJSF = (
const returnArray: any = [];
Object.keys(correlationPropertiesToUse).forEach((propIdentifier: string) => {
const property = correlationPropertiesToUse[propIdentifier];
return property.retrieval_expressions.forEach((retExp: string) => {
returnArray.push({
id: propIdentifier,
retrievalExpression: retExp,
});
returnArray.push({
id: propIdentifier,
retrievalExpression: property.retrieval_expression,
});
});
return returnArray;
@ -53,3 +51,55 @@ export const mergeCorrelationProperties = (
return mergedProperties;
};
export const areCorrelationPropertiesInSync = (
processGroup: ProcessGroup,
messageId: string,
messageProperties: any[],
) => {
if (!messageId) {
// About Message Creation
return true;
}
const message = processGroup.messages
? processGroup.messages[messageId]
: undefined;
if (!message) {
return false;
}
const localPropertyIds = messageProperties.map((property) => property.id);
const processGroupPropertyIds = Object.keys(message.correlation_properties);
// Check if all local properties exist in the process group data
// TODO: fix the lint
// eslint-disable-next-line
for (const property of messageProperties) {
const correlationProperty = message.correlation_properties[property.id];
if (!correlationProperty) {
return false;
}
const localRetrievalExpression = Array.isArray(property.retrievalExpression)
? property.retrievalExpression[0]
: property.retrievalExpression;
if (correlationProperty.retrieval_expression !== localRetrievalExpression) {
return false;
}
}
// Checking if all process group properties exist in the local xml
// TODO: fix the lint
// eslint-disable-next-line
for (const propertyId of processGroupPropertyIds) {
if (!localPropertyIds.includes(propertyId)) {
return false;
}
}
return true;
};

View File

@ -25,6 +25,7 @@ a.cds--header__menu-item {
background-color: #161616;
cursor: default;
}
.cds--header__action.unclickable-text:focus {
border: none;
box-shadow: none;
@ -81,6 +82,7 @@ h3 {
background-blend-mode: multiply;
border: 1px solid #393939;
}
.cds--btn.button-white-background:hover {
background: lightgrey;
}
@ -88,12 +90,15 @@ h3 {
.spiff-breadcrumb .MuiBreadcrumbs-li a:hover {
color: #525252;
}
.spiff-breadcrumb .MuiBreadcrumbs-li a:visited {
color: #525252;
}
.spiff-breadcrumb .MuiBreadcrumbs-li a:visited:hover {
color: #525252;
}
.spiff-breadcrumb .MuiBreadcrumbs-li a {
color: #525252;
}
@ -101,12 +106,15 @@ h3 {
.cds--btn--ghost {
color: black;
}
.cds--btn--ghost:visited {
color: black;
}
.cds--btn--ghost:hover {
color: black;
}
.cds--btn--ghost:visited:hover {
color: black;
}
@ -116,15 +124,18 @@ h3 {
color: #0062fe;
padding-left: 0;
}
.cds--btn--ghost.button-link:visited {
color: #0062fe;
padding-left: 0;
}
.cds--btn--ghost.button-link:hover {
color: #0062fe;
background-color: white;
padding-left: 0;
}
.cds--btn--ghost.button-link:visited:hover {
color: #0062fe;
background-color: white;
@ -136,10 +147,12 @@ h3 {
color: black;
border-color: black;
}
.cds--btn--tertiary:visited {
color: black;
border-color: black;
}
/* make the colors a little lighter black on hover
* so they match our normal scheme better
*/
@ -148,11 +161,13 @@ h3 {
border-color: #161616;
background-color: #f4f4f4;
}
.cds--btn--tertiary:hover {
color: #161616;
border-color: #161616;
background-color: #f4f4f4;
}
.cds--btn--tertiary:visited:hover {
color: #161616;
border-color: #161616;
@ -164,21 +179,25 @@ h3 {
border-color: #efefef;
background-color: #efefef;
}
.cds--btn--secondary:visited {
color: #161616;
border-color: #efefef;
background-color: #efefef;
}
.cds--btn--secondary:focus {
color: #161616;
border-color: #efefef;
background-color: #efefef;
}
.cds--btn--secondary:hover {
color: #161616;
border-color: #dddddd;
background-color: #dddddd;
}
.cds--btn--secondary:visited:hover {
color: #161616;
border-color: #dddddd;
@ -190,27 +209,58 @@ h3 {
border-color: #393939;
background-color: #393939;
}
.cds--modal-footer .cds--btn--secondary:visited {
color: #ffffff;
border-color: #393939;
background-color: #393939;
}
.cds--modal-footer .cds--btn--secondary:focus {
color: #ffffff;
border-color: #393939;
background-color: #393939;
}
.cds--modal-footer .cds--btn--secondary:hover {
color: #ffffff;
border-color: #474747;
background-color: #474747;
}
.cds--modal-footer .cds--btn--secondary:visited:hover {
color: #ffffff;
border-color: #474747;
background-color: #474747;
}
/* position the close button at the top-right corner of the modal header */
.cds--modal-close {
position: absolute;
top: 1rem;
right: 1rem;
border: none;
background: transparent;
cursor: pointer;
padding: 0;
}
.cds--modal-close__icon {
fill: #161616;
}
.cds--modal-footer .cds--btn--secondary {
color: #161616;
border-color: #e0e0e0;
background-color: #e0e0e0;
}
.cds--modal-footer .cds--btn--secondary:hover {
border-color: #c6c6c6;
background-color: #c6c6c6;
color: #161616;
}
.cds--header__global .cds--btn--primary.button-link {
color: #f4f4f4;
background-color: #393939;
@ -220,12 +270,15 @@ h3 {
.cds--header__global .cds--btn--primary {
background-color: #161616;
}
.cds--btn--primary {
background-color: #393939;
}
.cds--btn--primary:hover {
background-color: #474747;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
@ -242,20 +295,22 @@ code {
margin-bottom: 2rem;
}
.active-task-highlight:not(.djs-connection) .djs-visual > :nth-child(1) {
.active-task-highlight:not(.djs-connection) .djs-visual> :nth-child(1) {
fill: yellow !important;
opacity: 0.6;
}
.completed-task-highlight:not(.djs-connection) .djs-visual > :nth-child(1) {
.completed-task-highlight:not(.djs-connection) .djs-visual> :nth-child(1) {
fill: grey !important;
opacity: 0.4;
}
.cancelled-task-highlight:not(.djs-connection) .djs-visual > :nth-child(1) {
.cancelled-task-highlight:not(.djs-connection) .djs-visual> :nth-child(1) {
fill: blue !important;
opacity: 0.2;
}
.errored-task-highlight:not(.djs-connection) .djs-visual > :nth-child(1) {
.errored-task-highlight:not(.djs-connection) .djs-visual> :nth-child(1) {
fill: red !important;
opacity: 0.2;
}
@ -340,6 +395,7 @@ dl dd {
margin-top: 8px;
margin-right: 12px;
}
#user-profile-toggletip .cds--popover-content::before {
content: none;
}
@ -363,9 +419,7 @@ dl dd {
content: none;
}
#user-profile-toggletip
.cds--popover--tab-tip.cds--popover--open
.cds--popover--tab-tip__button {
#user-profile-toggletip .cds--popover--tab-tip.cds--popover--open .cds--popover--tab-tip__button {
background-color: #161616;
}
@ -423,16 +477,19 @@ dl dd {
font-size: 12pt;
border-collapse: collapse;
}
.markdown table thead th,
.markdown table tfoot th {
color: #777;
background: rgba(0, 0, 0, 0.1);
}
.markdown table th,
.markdown table td {
padding: 0.5rem;
border: 1px solid lightgrey;
}
/* Zebra Table Style */
.markdown tbody tr:nth-of-type(odd) {
background: rgba(0, 0, 0, 0.05);
@ -444,7 +501,7 @@ dl dd {
/* Json Web Form CSS Fix - Bootstrap now requries that each li have a "list-inline-item." Also have a PR
in on this with the react-jsonschema-form repo. This is just a patch fix to allow date inputs to layout a little more cleanly */
.list-inline > li {
.list-inline>li {
display: inline-block;
padding-right: 5px;
padding-left: 5px;
@ -589,9 +646,11 @@ th.table-header-right-align .cds--table-header-label {
.cds--btn--ghost:not([disabled]).red-icon svg {
fill: red;
}
.cds--btn--ghost:not([disabled]).green-icon svg {
fill: #198038;
}
.cds--btn--ghost:not([disabled]) svg.red-icon {
fill: red;
}
@ -613,13 +672,14 @@ svg.notification-icon {
width: 100%;
height: 2rem;
}
.filter-tag > span {
.filter-tag>span {
display: flex;
flex-direction: row;
width: 100%;
}
.filter-tag > span > span {
.filter-tag>span>span {
margin-right: 0.5px;
}
@ -668,6 +728,7 @@ svg.notification-icon {
.modal-within-table-cell .cds--modal-container {
text-align: left;
}
.modal-within-table-cell .cds--modal-container button {
padding-left: 15px;
}
@ -844,8 +905,9 @@ div.json-schema {
}
fieldset legend.header {
margin-bottom: 32px;
margin-bottom: 16px;
}
fieldset fieldset fieldset legend.header {
margin-bottom: 16px;
}
@ -876,6 +938,7 @@ blockquote,
hr {
max-width: 640px;
}
li.cds--accordion__item {
max-width: 100%;
}
@ -893,14 +956,11 @@ div.markdown-collapsed {
max-height: 200px;
overflow: hidden;
--mask: linear-gradient(
to bottom,
--mask: linear-gradient(to bottom,
rgba(0, 0, 0, 1) 0,
rgba(0, 0, 0, 1) 40%,
rgba(0, 0, 0, 0) 95%,
rgba(0, 0, 0, 0) 0
)
100% 50% / 100% 100% repeat-x;
rgba(0, 0, 0, 0) 0) 100% 50% / 100% 100% repeat-x;
font: 2em/1.6em Arial;
-webkit-mask: var(--mask);
@ -920,6 +980,7 @@ div.markdown-collapsed {
.cds--accordion {
--cds-layout-density-padding-inline-local: 0px;
}
.megacondensed-button .cds--btn {
--cds-layout-density-padding-inline-local: 0px;
}
@ -945,6 +1006,7 @@ div.onboarding {
.completed-task-modal .cds--modal-container {
background-color: #ffffff;
}
.completed-task-modal .cds--text-input:disabled,
.completed-task-modal .cds--text-area:disabled,
.completed-task-modal .cds--date-picker__input:disabled,
@ -953,6 +1015,7 @@ div.onboarding {
--cds-text-disabled: rgba(22, 22, 22, 0.5);
background-color: var(--cds-field);
}
.completed-task-modal .cds--form__helper-text--disabled {
--cds-text-disabled: rgba(22, 22, 22, 0.5);
}
@ -963,6 +1026,7 @@ div.onboarding {
overflow: hidden;
white-space: nowrap;
}
.process-model-file-table-filename {
overflow: hidden;
text-overflow: ellipsis;
@ -997,15 +1061,20 @@ div.onboarding {
}
.shortcut-description {
width: 50%; /* Adjust width as needed */
float: left; /* Floats the description to the left */
width: 50%;
/* Adjust width as needed */
float: left;
/* Floats the description to the left */
margin-top: 10px;
}
.shortcut-key-group {
width: 50%; /* Adjust width as needed */
float: right; /* Floats the keys to the right */
text-align: right; /* Aligns text to the right within the container */
width: 50%;
/* Adjust width as needed */
float: right;
/* Floats the keys to the right */
text-align: right;
/* Aligns text to the right within the container */
}
div.retrievalExpressionsForm {

View File

@ -213,7 +213,7 @@ export interface ProcessInstance {
}
export interface CorrelationProperty {
retrieval_expressions: string[];
retrieval_expression: string;
}
export interface CorrelationProperties {

View File

@ -31,6 +31,7 @@
.rjsf .rjsf-field .rjsf-field {
margin-bottom: 2rem;
}
/* only the outter rjsf-field gets the margin from the rule above but not its contents like the array-item so mention it explicitly */
.rjsf .array-item .rjsf-field .rjsf-field {
margin-bottom: 2rem;
@ -49,6 +50,7 @@
padding-bottom: 8px;
font-size: 14px;
}
/* position the remove button to align with the file description */
.rjsf .file-info span div {
position: relative;
@ -72,8 +74,10 @@
padding-top: 1rem;
padding-bottom: 1rem;
margin-bottom: 1rem;
background: rgba(0, 0, 0, 0.1);
border-radius: 0.5rem;
/* background: rgba(0, 0, 0, 0.1);
border-radius: 0.5rem; */
background: rgb(109 107 107 / 10%);
border-radius: 0.30rem;
}
.rjsf .array-item legend {
@ -123,10 +127,12 @@
.rjsf .array-field-container {
display: flex;
}
.rjsf .array-field-contents {
flex: 8;
margin-left: calc(3%);
}
.rjsf .array-field-actions {
flex: 1;
display: flex;
@ -137,4 +143,4 @@
.rjsf .radio-button-group {
padding-top: 0.5rem;
}
}

View File

@ -46,6 +46,7 @@ import {
} from '../helpers';
import {
CarbonComboBoxProcessSelection,
CorrelationProperties,
ProcessFile,
ProcessModel,
ProcessReference,
@ -83,7 +84,9 @@ export default function ProcessModelEditDiagram() {
const [showMarkdownEditor, setShowMarkdownEditor] = useState(false);
const [showMessageEditor, setShowMessageEditor] = useState(false);
const [messageId, setMessageId] = useState<string>('');
const [correlationProperties, setCorrelationProperties] = useState<any>([]);
const [elementId, setElementId] = useState<string>('');
const [correlationProperties, setCorrelationProperties] =
useState<CorrelationProperties | null>(null);
const [showProcessSearch, setShowProcessSearch] = useState(false);
const [processSearchEventBus, setProcessSearchEventBus] = useState<any>(null);
const [processSearchElement, setProcessSearchElement] = useState<any>(null);
@ -1062,6 +1065,7 @@ export default function ProcessModelEditDiagram() {
const onLaunchMessageEditor = (event: any) => {
setMessageEvent(event);
setMessageId(event.value.messageId);
setElementId(event.value.elementId);
setCorrelationProperties(event.value.correlation_properties);
handleShowMessageEditor();
};
@ -1070,6 +1074,11 @@ export default function ProcessModelEditDiagram() {
onMessagesRequested(messageEvent);
};
const handleMessageEditorSave = (_event: any) => {
// setShowMessageEditor(false);
messageEvent.eventBus.fire('spiff.message.save');
};
const messageEditor = () => {
// do not render this component until we actually want to display it
if (!showMessageEditor) {
@ -1078,12 +1087,15 @@ export default function ProcessModelEditDiagram() {
return (
<Modal
open={showMessageEditor}
modalHeading="Create/Edit Message"
primaryButtonText="Close (this does not save)"
onRequestSubmit={handleMessageEditorClose}
modalHeading="Message Editor"
modalLabel="Create or edit a message and manage its correlation properties"
primaryButtonText="Save"
secondaryButtonText="Close (this does not save)"
onRequestSubmit={handleMessageEditorSave}
onRequestClose={handleMessageEditorClose}
size="lg"
preventCloseOnClickOutside
primaryButtonKind="primary"
>
<div data-color-mode="light">
<MessageEditor
@ -1093,6 +1105,7 @@ export default function ProcessModelEditDiagram() {
messageId={messageId}
correlationProperties={correlationProperties}
messageEvent={messageEvent}
elementId={elementId}
/>
</div>
</Modal>