From 87e227da7c58448b18be801def3180ac150402b6 Mon Sep 17 00:00:00 2001
From: Kbowers <92726146+kbowers-ibm@users.noreply.github.com>
Date: Wed, 16 Oct 2024 15:27:59 +0200
Subject: [PATCH] NO-ISSUE: Adding new SVGS to the BPMN editor (#132)
* NO-ISSUE: Adding new SVGs to the new BPMN Editor
* fixing fill changes
---
.../src/diagram/nodes/NodeIcons.tsx | 8 +-
.../src/diagram/nodes/NodeSvgs.tsx | 623 ++++++++++++++----
.../morphing/useEventNodeMorphingActions.tsx | 22 +-
3 files changed, 522 insertions(+), 131 deletions(-)
diff --git a/packages/bpmn-editor/src/diagram/nodes/NodeIcons.tsx b/packages/bpmn-editor/src/diagram/nodes/NodeIcons.tsx
index db6772074bc..d32bf47c998 100644
--- a/packages/bpmn-editor/src/diagram/nodes/NodeIcons.tsx
+++ b/packages/bpmn-editor/src/diagram/nodes/NodeIcons.tsx
@@ -52,11 +52,11 @@ export function NodeIcon({ nodeType }: { nodeType: BpmnNodeType }) {
export function EventDefitnitionIcon({
variant,
- fill,
+ filled,
stroke,
}: {
variant?: EventVariant;
- fill: boolean;
+ filled: boolean;
stroke: string;
}) {
const cx = nodeSvgProps.x + nodeSvgProps.width / 2;
@@ -69,14 +69,14 @@ export function EventDefitnitionIcon({
);
diff --git a/packages/bpmn-editor/src/diagram/nodes/NodeSvgs.tsx b/packages/bpmn-editor/src/diagram/nodes/NodeSvgs.tsx
index ef94d23379f..253d9735a81 100644
--- a/packages/bpmn-editor/src/diagram/nodes/NodeSvgs.tsx
+++ b/packages/bpmn-editor/src/diagram/nodes/NodeSvgs.tsx
@@ -159,14 +159,15 @@ export function StartEventNodeSvg(__props: NodeSvgProps & { variant: EventVarian
/>
>
);
@@ -185,8 +186,8 @@ export function IntermediateCatchEventNodeSvg(
const { rimWidth, variant, ...props } = { ..._props };
- const outerCirculeRadius = width / 2;
- const innerCircleRadius = outerCirculeRadius - (rimWidth ?? 5);
+ const outerCircleRadius = width / 2;
+ const innerCircleRadius = outerCircleRadius - (rimWidth ?? 5);
const cx = x + width / 2;
const cy = y + height / 2;
@@ -202,7 +203,7 @@ export function IntermediateCatchEventNodeSvg(
fill={NODE_COLORS.intermediateCatchEvent.background}
stroke={NODE_COLORS.intermediateCatchEvent.foreground}
strokeLinejoin={"round"}
- r={outerCirculeRadius}
+ r={outerCircleRadius}
{...props}
/>
>
);
@@ -245,8 +247,8 @@ export function IntermediateThrowEventNodeSvg(
const { rimWidth, variant, ...props } = { ..._props };
- const outerCirculeRadius = width / 2;
- const innerCircleRadius = outerCirculeRadius - (rimWidth ?? 5);
+ const outerCircleRadius = width / 2;
+ const innerCircleRadius = outerCircleRadius - (rimWidth ?? 5);
const cx = x + width / 2;
const cy = y + height / 2;
@@ -262,7 +264,7 @@ export function IntermediateThrowEventNodeSvg(
fill={NODE_COLORS.intermediateThrowEvent.background}
stroke={NODE_COLORS.intermediateThrowEvent.foreground}
strokeLinejoin={"round"}
- r={outerCirculeRadius}
+ r={outerCircleRadius}
{...props}
/>
>
);
@@ -324,14 +327,15 @@ export function EndEventNodeSvg(__props: NodeSvgProps & { variant: EventVariant
/>
>
);
@@ -749,8 +753,9 @@ export function EventVariantSymbolSvg({
x,
y,
innerCircleRadius,
- outerCirculeRadius,
+ outerCircleRadius,
fill,
+ filled,
}: {
variant: EventVariant | "none";
stroke: string;
@@ -760,118 +765,81 @@ export function EventVariantSymbolSvg({
x: number;
y: number;
innerCircleRadius: number;
- outerCirculeRadius: number;
- fill: boolean;
+ outerCircleRadius: number;
+ fill?: string;
+ filled: boolean;
}) {
return (
<>
- {/* FIXME: Tiago: tmp icon */}
{variant === "messageEventDefinition" && (
- <>
-
- ✉️
-
- >
+
)}
- {/* FIXME: Tiago: tmp icon */}
{variant === "timerEventDefinition" && (
- <>
-
- 🕑
-
- >
+
)}
- {/* FIXME: Tiago: tmp icon */}
{variant === "errorEventDefinition" && (
- <>
-
- ⚡️
-
- >
+
)}
- {/* FIXME: Tiago: tmp icon */}
{variant === "escalationEventDefinition" && (
- <>
-
- ☝️
-
- >
+
)}
- {/* FIXME: Tiago: tmp icon */}
{variant === "cancelEventDefinition" && (
- <>
-
- ❌
-
- >
+
)}
- {/* FIXME: Tiago: tmp icon */}
{variant === "compensateEventDefinition" && (
- <>
-
- ⏪
-
- >
+
)}
- {/* FIXME: Tiago: tmp icon */}
{variant === "conditionalEventDefinition" && (
- <>
-
- ≣
-
- >
+
)}
- {/* FIXME: Tiago: tmp icon */}
{variant === "linkEventDefinition" && (
- <>
-
- ⇨
-
- >
+
)}
{variant === "signalEventDefinition" && (
)}
@@ -892,7 +860,7 @@ export function EventVariantSymbolSvg({
fill={NODE_COLORS.endEvent.foreground}
stroke={NODE_COLORS.endEvent.foreground}
strokeLinejoin={"round"}
- r={outerCirculeRadius / 2}
+ r={outerCircleRadius / 2}
/>
>
)}
@@ -902,6 +870,429 @@ export function EventVariantSymbolSvg({
);
}
+export function MessageEventSymbolSvg({
+ stroke,
+ cx,
+ cy,
+ innerCircleRadius,
+ fill,
+ filled,
+}: {
+ stroke: string;
+ cx: number;
+ cy: number;
+ innerCircleRadius: number;
+ fill: string;
+ filled: boolean;
+}) {
+ const bodyWidth = innerCircleRadius * 1.2;
+ const bodyHeight = innerCircleRadius * 0.8;
+
+ const envelopeBody = {
+ topLeft: { x: cx - bodyWidth / 2, y: cy - bodyHeight / 2 },
+ bottomRight: { x: cx + bodyWidth / 2, y: cy + bodyHeight / 2 },
+ };
+
+ const flapHeight = bodyHeight * 0.5;
+ const envelopeFlap = [
+ { x: envelopeBody.topLeft.x, y: envelopeBody.topLeft.y },
+ { x: envelopeBody.bottomRight.x, y: envelopeBody.topLeft.y },
+ { x: cx, y: envelopeBody.topLeft.y + flapHeight },
+ ];
+
+ return (
+ <>
+
+
+ `${point.x},${point.y}`).join(" ")}
+ strokeWidth={1.5}
+ strokeLinejoin={"round"}
+ fill={filled ? stroke : fill}
+ stroke={stroke}
+ />
+
+ {filled && (
+ <>
+
+
+ >
+ )}
+ >
+ );
+}
+
+export function TimerEventSymbolSvg({
+ stroke,
+ cx,
+ cy,
+ innerCircleRadius,
+ outerCircleRadius,
+ filled,
+}: {
+ stroke: string;
+ cx: number;
+ cy: number;
+ innerCircleRadius: number;
+ outerCircleRadius: number;
+ filled: boolean;
+}) {
+ const padding = 1.2 * (outerCircleRadius - innerCircleRadius);
+ const clockRadius = innerCircleRadius - padding;
+
+ const shortHandLength = clockRadius * 0.5;
+ const longHandLength = clockRadius * 0.9;
+
+ const hourHandAngle = Math.PI / 12;
+ const minuteHandAngle = (-5 * Math.PI) / 12;
+
+ const hourHand = {
+ x: cx + shortHandLength * Math.cos(hourHandAngle),
+ y: cy + shortHandLength * Math.sin(hourHandAngle),
+ };
+
+ const minuteHand = {
+ x: cx + longHandLength * Math.cos(minuteHandAngle),
+ y: cy + longHandLength * Math.sin(minuteHandAngle),
+ };
+
+ return (
+ <>
+
+
+
+
+
+
+ {Array.from({ length: 12 }, (_, index) => {
+ const angle = (index / 12) * 2 * Math.PI;
+ const x1 = cx + clockRadius * Math.cos(angle);
+ const y1 = cy + clockRadius * Math.sin(angle);
+ const x2 = cx + (clockRadius - padding * 0.5) * Math.cos(angle);
+ const y2 = cy + (clockRadius - padding * 0.5) * Math.sin(angle);
+
+ return ;
+ })}
+ >
+ );
+}
+
+export function ErrorEventSymbolSvg({
+ stroke,
+ cx,
+ cy,
+ innerCircleRadius,
+ outerCircleRadius,
+ filled,
+}: {
+ stroke: string;
+ cx: number;
+ cy: number;
+ innerCircleRadius: number;
+ outerCircleRadius: number;
+ filled: boolean;
+}) {
+ const padding = 1.5 * (outerCircleRadius - innerCircleRadius);
+ const hx = innerCircleRadius - padding;
+ const hy = innerCircleRadius - padding;
+
+ const scaleFactor = 20;
+ const shiftLeft = 3.5;
+ const shiftUp = 1;
+
+ const points = [
+ { x: cx - shiftLeft, y: cy },
+ { x: cx - hx * 0.037 * scaleFactor - shiftLeft, y: cy + hy * 0.052 * scaleFactor - shiftUp },
+ { x: cx - hx * 0.003 * scaleFactor - shiftLeft, y: cy - hy * 0.05 * scaleFactor - shiftUp },
+ { x: cx + hx * 0.027 * scaleFactor - shiftLeft, y: cy + hy * 0.016 * scaleFactor - shiftUp },
+ { x: cx + hx * 0.058 * scaleFactor - shiftLeft, y: cy - hy * 0.046 * scaleFactor - shiftUp },
+ { x: cx + hx * 0.029 * scaleFactor - shiftLeft, y: cy + hy * 0.066 * scaleFactor - shiftUp },
+ { x: cx - shiftLeft, y: cy },
+ ];
+
+ return (
+ <>
+ `${point.x},${point.y}`).join(" ")}
+ strokeWidth={1.5}
+ strokeLinejoin={"round"}
+ fill={filled ? stroke : "transparent"}
+ stroke={stroke}
+ />
+ >
+ );
+}
+
+export function EscalationEventSymbolSvg({
+ stroke,
+ cx,
+ cy,
+ innerCircleRadius,
+ filled,
+}: {
+ stroke: string;
+ cx: number;
+ cy: number;
+ innerCircleRadius: number;
+ filled: boolean;
+}) {
+ const arrowHeight = innerCircleRadius * 1.2;
+ const arrowBaseWidth = innerCircleRadius * 1;
+
+ const arrow = [
+ { x: cx - arrowBaseWidth / 2, y: cy + arrowHeight / 2 }, // left
+ { x: cx, y: cy - arrowHeight / 2 }, // top center
+ { x: cx + arrowBaseWidth / 2, y: cy + arrowHeight / 2 }, // right
+ { x: cx, y: cy + arrowHeight / 20 }, // mid center
+ ] as const;
+
+ return (
+ <>
+ `${point.x},${point.y}`).join(" ")}
+ strokeWidth={1.5}
+ strokeLinejoin={"round"}
+ fill={filled ? stroke : "transparent"}
+ stroke={stroke}
+ />
+ >
+ );
+}
+
+export function CancelEventSymbolSvg({
+ stroke,
+ cx,
+ cy,
+ innerCircleRadius,
+ filled,
+}: {
+ stroke: string;
+ cx: number;
+ cy: number;
+ innerCircleRadius: number;
+ filled: boolean;
+}) {
+ const farXPoint = 1.3;
+ const closeXPoint = 1.7;
+ const lowYPoint = 9;
+ const highYPoint = 5;
+
+ const cross = [
+ { x: cx - innerCircleRadius / farXPoint, y: cy - innerCircleRadius + lowYPoint }, // upper left point 1
+ { x: cx - innerCircleRadius / closeXPoint, y: cy - innerCircleRadius + highYPoint }, // upper left point 2
+ { x: cx, y: cy - innerCircleRadius / highYPoint }, // upper joiner
+ { x: cx + innerCircleRadius / closeXPoint, y: cy - innerCircleRadius + highYPoint }, // upper right point 2
+ { x: cx + innerCircleRadius / farXPoint, y: cy - innerCircleRadius + lowYPoint }, // upper right point 1
+ { x: cx + innerCircleRadius / highYPoint, y: cy }, // right joiner
+ { x: cx + innerCircleRadius / farXPoint, y: cy + innerCircleRadius - lowYPoint }, // lower right point 2
+ { x: cx + innerCircleRadius / closeXPoint, y: cy + innerCircleRadius - highYPoint }, // lower right point 1
+ { x: cx, y: cy + innerCircleRadius / highYPoint }, // lower joiner
+ { x: cx - innerCircleRadius / closeXPoint, y: cy + innerCircleRadius - highYPoint }, // lower left point 1
+ { x: cx - innerCircleRadius / farXPoint, y: cy + innerCircleRadius - lowYPoint }, // lower left point 2
+ { x: cx - innerCircleRadius / highYPoint, y: cy }, // left joiner
+ ] as const;
+
+ return (
+ <>
+ `${point.x},${point.y}`).join(" ")}
+ strokeWidth={1.5}
+ strokeLinejoin={"round"}
+ fill={filled ? stroke : "transparent"}
+ stroke={stroke}
+ />
+ >
+ );
+}
+
+export function CompensationEventSymbolSvg({
+ stroke,
+ cx,
+ cy,
+ x,
+ y,
+ innerCircleRadius,
+ outerCircleRadius,
+ filled,
+}: {
+ stroke: string;
+ cx: number;
+ cy: number;
+ x: number;
+ y: number;
+ innerCircleRadius: number;
+ outerCircleRadius: number;
+ filled: boolean;
+}) {
+ const padding = 1.5 * (outerCircleRadius - innerCircleRadius);
+
+ const hx = x + innerCircleRadius - padding * 0.6;
+ const hy = y + innerCircleRadius - padding * 0.2;
+
+ const rightOffset = 0.15 * innerCircleRadius;
+
+ const firstTriangle = [
+ { x: cx + hx - rightOffset, y: cy - hy + (outerCircleRadius - innerCircleRadius) },
+ { x: cx - rightOffset, y: cy },
+ { x: cx + hx - rightOffset, y: cy + hy - (outerCircleRadius - innerCircleRadius) },
+ ] as const;
+
+ const secondTriangle = [
+ { x: cx - rightOffset, y: cy - hy + (outerCircleRadius - innerCircleRadius) },
+ { x: cx - hx - rightOffset, y: cy },
+ { x: cx - rightOffset, y: cy + hy - (outerCircleRadius - innerCircleRadius) },
+ ] as const;
+
+ return (
+ <>
+ `${point.x},${point.y}`).join(" ")}
+ strokeWidth={1.5}
+ strokeLinejoin={"round"}
+ fill={filled ? stroke : "transparent"}
+ stroke={stroke}
+ />
+ `${point.x},${point.y}`).join(" ")}
+ strokeWidth={1.5}
+ strokeLinejoin={"round"}
+ fill={filled ? stroke : "transparent"}
+ stroke={stroke}
+ />
+ >
+ );
+}
+
+export function ConditionalEventSymbolSvg({
+ stroke,
+ cx,
+ cy,
+ outerCircleRadius,
+ filled,
+}: {
+ stroke: string;
+ cx: number;
+ cy: number;
+ outerCircleRadius: number;
+ filled: boolean;
+}) {
+ const squareSize = outerCircleRadius * 1.1;
+ const lineSpacing = squareSize / 5;
+ const lineThickness = 2;
+
+ return (
+ <>
+
+
+ {[...Array(4)].map((_, index) => (
+
+ ))}
+ >
+ );
+}
+
+export function LinkEventSymbolSvg({
+ stroke,
+ cx,
+ cy,
+ innerCircleRadius,
+ filled,
+}: {
+ stroke: string;
+ cx: number;
+ cy: number;
+ innerCircleRadius: number;
+ filled: boolean;
+}) {
+ const arrowHeight = innerCircleRadius * 1.2;
+ const arrowBaseWidth = innerCircleRadius * 1;
+ const shiftLeft = 7;
+ const rectangleHeight = 5;
+ const arrowPadding = 2;
+
+ const arrow = [
+ { x: cx - arrowBaseWidth / 2 - shiftLeft, y: cy + arrowHeight / 2 - rectangleHeight }, // bottom left rectangle
+ { x: cx - arrowBaseWidth / 2 - shiftLeft, y: cy - arrowHeight / 2 + rectangleHeight }, // top left rectangle
+ { x: cx + arrowBaseWidth / 2, y: cy - arrowHeight / 2 + rectangleHeight }, // top right rectangle
+ { x: cx + arrowBaseWidth / 2, y: cy - arrowHeight / 2 - arrowPadding }, // upper arrow start
+ { x: cx + arrowBaseWidth / 2 + 8, y: cy }, // arrow point
+ { x: cx + arrowBaseWidth / 2, y: cy + arrowHeight / 2 + arrowPadding }, // lower arrow start
+ { x: cx + arrowBaseWidth / 2, y: cy + arrowHeight / 2 - rectangleHeight }, // bottom right rectangle
+ ] as const;
+
+ return (
+ <>
+ `${point.x},${point.y}`).join(" ")}
+ strokeWidth={1.5}
+ strokeLinejoin={"round"}
+ fill={filled ? stroke : "transparent"}
+ stroke={stroke}
+ />
+ >
+ );
+}
+
export function SignalEventSymbolSvg({
stroke,
strokeWidth,
@@ -910,8 +1301,8 @@ export function SignalEventSymbolSvg({
x,
y,
innerCircleRadius,
- outerCirculeRadius,
- fill,
+ outerCircleRadius,
+ filled,
}: {
stroke: string;
strokeWidth?: number;
@@ -920,10 +1311,10 @@ export function SignalEventSymbolSvg({
x: number;
y: number;
innerCircleRadius: number;
- outerCirculeRadius: number;
- fill: boolean;
+ outerCircleRadius: number;
+ filled: boolean;
}) {
- const padding = 1.5 * (outerCirculeRadius - innerCircleRadius);
+ const padding = 1.5 * (outerCircleRadius - innerCircleRadius);
const hx = x + innerCircleRadius - padding;
const hy = y + innerCircleRadius - padding;
const triangle = [
@@ -935,10 +1326,10 @@ export function SignalEventSymbolSvg({
return (
<>
`${point.x},${point.y}`).join(" ")}
+ strokeWidth={strokeWidth ?? 1.5}
strokeLinejoin={"round"}
- fill={fill ? stroke : "transparent"}
+ fill={filled ? stroke : "transparent"}
stroke={stroke}
/>
>
diff --git a/packages/bpmn-editor/src/diagram/nodes/morphing/useEventNodeMorphingActions.tsx b/packages/bpmn-editor/src/diagram/nodes/morphing/useEventNodeMorphingActions.tsx
index c3f35494286..bf5ba008eb6 100644
--- a/packages/bpmn-editor/src/diagram/nodes/morphing/useEventNodeMorphingActions.tsx
+++ b/packages/bpmn-editor/src/diagram/nodes/morphing/useEventNodeMorphingActions.tsx
@@ -41,7 +41,7 @@ export function useEventNodeMorphingActions(event: Event) {
const bpmnEditorStoreApi = useBpmnEditorStoreApi();
const foregroundColor = NODE_COLORS[event.__$$element].foreground;
- const fill = event.__$$element === "intermediateThrowEvent" || event.__$$element === "endEvent";
+ const filled = event.__$$element === "intermediateThrowEvent" || event.__$$element === "endEvent";
const morphEvent = useCallback(
(eventDefinitionElement: undefined | Unpacked["__$$element"]) => {
@@ -165,63 +165,63 @@ export function useEventNodeMorphingActions(event: Event) {
action: () => morphEvent(undefined),
} as const, // none
{
- icon: ,
+ icon: ,
key: "2",
title: "Message",
id: "messageEventDefinition",
action: () => morphEvent("messageEventDefinition"),
} as const,
{
- icon: ,
+ icon: ,
key: "3",
title: "Timer",
id: "timerEventDefinition",
action: () => morphEvent("timerEventDefinition"),
} as const,
{
- icon: ,
+ icon: ,
key: "4",
title: "Error",
id: "errorEventDefinition",
action: () => morphEvent("errorEventDefinition"),
} as const,
{
- icon: ,
+ icon: ,
key: "5",
title: "Escalation",
id: "escalationEventDefinition",
action: () => morphEvent("escalationEventDefinition"),
} as const,
{
- icon: ,
+ icon: ,
key: "6",
title: "Cancelation",
id: "cancelEventDefinition",
action: () => morphEvent("cancelEventDefinition"),
} as const,
{
- icon: ,
+ icon: ,
key: "7",
title: "Compensation",
id: "compensateEventDefinition",
action: () => morphEvent("compensateEventDefinition"),
} as const,
{
- icon: ,
+ icon: ,
key: "8",
title: "Conditional",
id: "conditionalEventDefinition",
action: () => morphEvent("conditionalEventDefinition"),
} as const,
{
- icon: ,
+ icon: ,
key: "9",
title: "Link",
id: "linkEventDefinition",
action: () => morphEvent("linkEventDefinition"),
} as const,
{
- icon: ,
+ icon: ,
key: "0",
title: "Signal",
id: "signalEventDefinition",
@@ -235,7 +235,7 @@ export function useEventNodeMorphingActions(event: Event) {
action: () => morphEvent("terminateEventDefinition"),
} as const,
];
- }, [event.__$$element, foregroundColor, fill, morphEvent]);
+ }, [event.__$$element, foregroundColor, filled, morphEvent]);
return morphingActions;
}