This is an automated email from the ASF dual-hosted git repository.
tiagobento pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-tools.git
The following commit(s) were added to refs/heads/main by this push:
new 6e4f2aef901 kie-issues#937: On the DMN Editor, adding a DRD then
pressing "Undo", makes the Editor will crash (#2304)
6e4f2aef901 is described below
commit 6e4f2aef901c2559c3357cd9b5b229919d8fc907
Author: Luiz João Motta <[email protected]>
AuthorDate: Wed May 8 11:10:04 2024 -0300
kie-issues#937: On the DMN Editor, adding a DRD then pressing "Undo", makes
the Editor will crash (#2304)
---
packages/dmn-editor/src/DmnEditor.tsx | 1 +
.../dmn-editor/src/autolayout/AutolayoutButton.tsx | 8 ++---
.../src/boxedExpressions/BoxedExpressionScreen.tsx | 7 ++--
packages/dmn-editor/src/clipboard/Clipboard.ts | 6 ++--
packages/dmn-editor/src/diagram/Diagram.tsx | 38 +++++++++++-----------
.../dmn-editor/src/diagram/DiagramCommands.tsx | 16 ++++-----
.../dmn-editor/src/diagram/DrdSelectorPanel.tsx | 19 ++++++-----
packages/dmn-editor/src/diagram/Palette.tsx | 18 ++++++----
.../dmn-editor/src/diagram/edges/Waypoints.tsx | 8 ++---
.../diagram/edges/usePotentialWaypointControls.ts | 2 +-
packages/dmn-editor/src/diagram/nodes/Nodes.tsx | 2 +-
.../dmn-editor/src/propertiesPanel/FontOptions.tsx | 5 ++-
.../src/propertiesPanel/ShapeOptions.tsx | 10 ++++--
packages/dmn-editor/src/store/Store.ts | 24 +++++++++++---
.../src/store/computed/computeIndexes.ts | 4 +--
packages/dmn-editor/src/store/computed/initial.ts | 4 +++
16 files changed, 104 insertions(+), 68 deletions(-)
diff --git a/packages/dmn-editor/src/DmnEditor.tsx
b/packages/dmn-editor/src/DmnEditor.tsx
index 571d18ec019..8e0e26ab201 100644
--- a/packages/dmn-editor/src/DmnEditor.tsx
+++ b/packages/dmn-editor/src/DmnEditor.tsx
@@ -247,6 +247,7 @@ export const DmnEditorInternal = ({
return;
}
state.dmn.model = normalize(model);
+
dmnModelBeforeEditingRef.current = state.dmn.model;
});
}, [dmnEditorStoreApi, model]);
diff --git a/packages/dmn-editor/src/autolayout/AutolayoutButton.tsx
b/packages/dmn-editor/src/autolayout/AutolayoutButton.tsx
index 0bf61e814c2..e2d88e4aef3 100644
--- a/packages/dmn-editor/src/autolayout/AutolayoutButton.tsx
+++ b/packages/dmn-editor/src/autolayout/AutolayoutButton.tsx
@@ -372,7 +372,7 @@ export function AutolayoutButton() {
repositionNode({
definitions: s.dmn.model.definitions,
- drdIndex: s.diagram.drdIndex,
+ drdIndex: s.computed(s).getDrdIndex(),
controlWaypointsByEdge: new Map(),
change: {
nodeType: node.type as NodeType,
@@ -406,7 +406,7 @@ export function AutolayoutButton() {
resizeNode({
definitions: s.dmn.model.definitions,
- drdIndex: s.diagram.drdIndex,
+ drdIndex: s.computed(s).getDrdIndex(),
dmnShapesByHref: s.computed(s).indexedDrd().dmnShapesByHref,
snapGrid,
change: {
@@ -454,7 +454,7 @@ export function AutolayoutButton() {
updateDecisionServiceDividerLine({
definitions: s.dmn.model.definitions,
- drdIndex: s.diagram.drdIndex,
+ drdIndex: s.computed(s).getDrdIndex(),
dmnShapesByHref: s.computed(s).indexedDrd().dmnShapesByHref,
drgElementIndex: parentNode.data.index,
shapeIndex: parentNode.data.shape.index,
@@ -481,7 +481,7 @@ export function AutolayoutButton() {
addEdge({
definitions: s.dmn.model.definitions,
- drdIndex: s.diagram.drdIndex,
+ drdIndex: s.computed(s).getDrdIndex(),
edge: {
autoPositionedEdgeMarker: undefined,
type: edge.type as EdgeType,
diff --git a/packages/dmn-editor/src/boxedExpressions/BoxedExpressionScreen.tsx
b/packages/dmn-editor/src/boxedExpressions/BoxedExpressionScreen.tsx
index dbc155484f7..791ac403c1e 100644
--- a/packages/dmn-editor/src/boxedExpressions/BoxedExpressionScreen.tsx
+++ b/packages/dmn-editor/src/boxedExpressions/BoxedExpressionScreen.tsx
@@ -101,6 +101,7 @@ export function BoxedExpressionScreen({ container }: {
container: React.RefObjec
(s) =>
s.computed(s).getExternalModelTypesByNamespace(externalModelsByNamespace).pmmls
);
const isAlternativeInputDataShape = useDmnEditorStore((s) =>
s.computed(s).isAlternativeInputDataShape());
+ const drdIndex = useDmnEditorStore((s) => s.computed(s).getDrdIndex());
const onRequestFeelVariables = useCallback(() => {
const externalModels = new Map<string, DmnLatestModel>();
@@ -142,7 +143,7 @@ export function BoxedExpressionScreen({ container }: {
container: React.RefObjec
// recalculated, breaking batching.
const widthsById = useMemo(() => {
return (
-
thisDmn.model.definitions["dmndi:DMNDI"]?.["dmndi:DMNDiagram"]?.[diagram.drdIndex]["di:extension"]?.[
+
thisDmn.model.definitions["dmndi:DMNDI"]?.["dmndi:DMNDiagram"]?.[drdIndex]["di:extension"]?.[
"kie:ComponentsWidthsExtension"
]?.["kie:ComponentWidths"] ?? []
).reduce((acc, c) => {
@@ -155,7 +156,7 @@ export function BoxedExpressionScreen({ container }: {
container: React.RefObjec
);
}
}, new Map<string, number[]>());
- }, [diagram.drdIndex, thisDmn.model.definitions]);
+ }, [drdIndex, thisDmn.model.definitions]);
const expression = useMemo(() => {
if (!drgElement) {
@@ -193,7 +194,7 @@ export function BoxedExpressionScreen({ container }: {
container: React.RefObjec
updateExpressionWidths({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
widthsById: newWidthsById,
});
});
diff --git a/packages/dmn-editor/src/clipboard/Clipboard.ts
b/packages/dmn-editor/src/clipboard/Clipboard.ts
index b1b1e7e87d7..87e80ad728c 100644
--- a/packages/dmn-editor/src/clipboard/Clipboard.ts
+++ b/packages/dmn-editor/src/clipboard/Clipboard.ts
@@ -188,9 +188,9 @@ export function buildClipboardFromDiagram(rfState:
RF.ReactFlowState, dmnEditorS
.getOriginalIds();
clipboard.widths = (
-
dmnEditorState.dmn.model.definitions["dmndi:DMNDI"]?.["dmndi:DMNDiagram"]?.[dmnEditorState.diagram.drdIndex][
- "di:extension"
- ]?.["kie:ComponentsWidthsExtension"]?.["kie:ComponentWidths"] ?? []
+
dmnEditorState.dmn.model.definitions["dmndi:DMNDI"]?.["dmndi:DMNDiagram"]?.[
+ dmnEditorState.computed(dmnEditorState).getDrdIndex()
+
]["di:extension"]?.["kie:ComponentsWidthsExtension"]?.["kie:ComponentWidths"]
?? []
).filter((w: KIE__tComponentWidths) =>
idsOnDrgElementTrees.has(w["@_dmnElementRef"]!));
const artifacts = dmnEditorState.dmn.model.definitions.artifact ?? [];
diff --git a/packages/dmn-editor/src/diagram/Diagram.tsx
b/packages/dmn-editor/src/diagram/Diagram.tsx
index 57f591c6f9e..504586968f4 100644
--- a/packages/dmn-editor/src/diagram/Diagram.tsx
+++ b/packages/dmn-editor/src/diagram/Diagram.tsx
@@ -209,7 +209,7 @@ export const Diagram = React.forwardRef<DiagramRef, {
container: React.RefObject
addEdge({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
edge: {
type: sourceHandle as EdgeType,
targetHandle: targetHandle as PositionalNodeHandleId,
@@ -307,7 +307,7 @@ export const Diagram = React.forwardRef<DiagramRef, {
container: React.RefObject
dmnEditorStoreApi.setState((state) => {
const { id, href: newNodeId } = addStandaloneNode({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
newNode: {
type: typeOfNewNodeFromPalette,
bounds: {
@@ -371,7 +371,7 @@ export const Diagram = React.forwardRef<DiagramRef, {
container: React.RefObject
addExistingDecisionServiceToDrd({
decisionService: externalDrgElement,
decisionServiceNamespace:
externalNodeDmn.model.definitions["@_namespace"],
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
dropPoint,
externalDmnsIndex,
thisDmnsDefinitions: state.dmn.model.definitions,
@@ -382,7 +382,7 @@ export const Diagram = React.forwardRef<DiagramRef, {
container: React.RefObject
const externalNodeType =
getNodeTypeFromDmnObject(externalDrgElement)!;
addShape({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
nodeType: externalNodeType,
shape: {
"@_dmnElementRef": xmlHrefToQName(externalNodeHref,
state.dmn.model.definitions),
@@ -419,7 +419,7 @@ export const Diagram = React.forwardRef<DiagramRef, {
container: React.RefObject
addExistingDecisionServiceToDrd({
decisionService: drgElement,
decisionServiceNamespace:
state.dmn.model.definitions["@_namespace"],
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
dropPoint,
externalDmnsIndex:
state.computed(state).getExternalModelTypesByNamespace(externalModelsByNamespace)
.dmns,
@@ -431,7 +431,7 @@ export const Diagram = React.forwardRef<DiagramRef, {
container: React.RefObject
const nodeType = getNodeTypeFromDmnObject(drgElement)!;
addShape({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
nodeType,
shape: {
"@_dmnElementRef": buildXmlQName({ type: "xml-qname",
localPart: drgElement["@_id"]! }),
@@ -524,7 +524,7 @@ export const Diagram = React.forwardRef<DiagramRef, {
container: React.RefObject
const { id, href: newDmnObejctHref } = addConnectedNode({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
edgeType,
sourceNode: {
href: sourceNode.id,
@@ -629,7 +629,7 @@ export const Diagram = React.forwardRef<DiagramRef, {
container: React.RefObject
) {
resizeNode({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
dmnShapesByHref:
state.computed(state).indexedDrd().dmnShapesByHref,
snapGrid: state.diagram.snapGrid,
change: {
@@ -668,7 +668,7 @@ export const Diagram = React.forwardRef<DiagramRef, {
container: React.RefObject
.nodesById.get(change.id)!;
const { delta } = repositionNode({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
controlWaypointsByEdge,
change: {
type: "absolute",
@@ -713,7 +713,7 @@ export const Diagram = React.forwardRef<DiagramRef, {
container: React.RefObject
);
repositionNode({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
controlWaypointsByEdge,
change: {
type: "absolute",
@@ -739,7 +739,7 @@ export const Diagram = React.forwardRef<DiagramRef, {
container: React.RefObject
deleteNode({
drgEdges:
state.computed(state).getDiagramData(externalModelsByNamespace).drgEdges,
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
dmnObjectNamespace: node.data.dmnObjectNamespace ??
state.dmn.model.definitions["@_namespace"],
dmnObjectQName: node.data.dmnObjectQName,
dmnObjectId: node.data.dmnObject?.["@_id"],
@@ -877,7 +877,7 @@ export const Diagram = React.forwardRef<DiagramRef, {
container: React.RefObject
for (let i = 0; i < selectedNodes.length; i++) {
addDecisionToDecisionService({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
decisionId: selectedNodes[i].data.dmnObject!["@_id"]!, // We
can assume that all selected nodes are Decisions because the contaiment was
validated above.
decisionServiceId: state
.computed(state)
@@ -915,7 +915,7 @@ export const Diagram = React.forwardRef<DiagramRef, {
container: React.RefObject
if (edge?.data) {
deleteEdge({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
edge: { id: change.id, dmnObject: edge.data.dmnObject },
mode: EdgeDeletionMode.FROM_DRG_AND_ALL_DRDS,
});
@@ -966,7 +966,7 @@ export const Diagram = React.forwardRef<DiagramRef, {
container: React.RefObject
const { newDmnEdge } = addEdge({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
edge: {
autoPositionedEdgeMarker: undefined,
type: oldEdge.type as EdgeType,
@@ -999,7 +999,7 @@ export const Diagram = React.forwardRef<DiagramRef, {
container: React.RefObject
if (newDmnEdge["@_dmnElementRef"] !== oldEdge.id) {
const { deletedDmnEdgeOnCurrentDrd } = deleteEdge({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
edge: { id: oldEdge.id, dmnObject: oldEdge.data!.dmnObject },
mode: EdgeDeletionMode.FROM_DRG_AND_ALL_DRDS,
});
@@ -1229,7 +1229,7 @@ function DmnDiagramEmptyState({
dmnEditorStoreApi.setState((state) => {
const { href: decisionNodeHref } = addStandaloneNode({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
newNode: {
type: NODE_TYPES.decision,
bounds: {
@@ -1267,7 +1267,7 @@ function DmnDiagramEmptyState({
updateExpressionWidths({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
widthsById: defaultWidthsById,
});
@@ -1298,7 +1298,7 @@ function DmnDiagramEmptyState({
const { href: inputDataNodeHref, shapeId: inputDataShapeId }
= addStandaloneNode({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
newNode: {
type: NODE_TYPES.inputData,
bounds: inputDataNodeBounds,
@@ -1307,7 +1307,7 @@ function DmnDiagramEmptyState({
const { href: decisionNodeHref } = addConnectedNode({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
edgeType: EDGE_TYPES.informationRequirement,
sourceNode: {
href: inputDataNodeHref,
diff --git a/packages/dmn-editor/src/diagram/DiagramCommands.tsx
b/packages/dmn-editor/src/diagram/DiagramCommands.tsx
index 9d073b1c98c..a05ce8736df 100644
--- a/packages/dmn-editor/src/diagram/DiagramCommands.tsx
+++ b/packages/dmn-editor/src/diagram/DiagramCommands.tsx
@@ -131,7 +131,7 @@ export function DiagramCommands(props: {}) {
[...copiedEdgesById.values(),
...danglingEdgesById.values()].forEach((edge) => {
deleteEdge({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
edge: { id: edge.id, dmnObject: edge.data!.dmnObject },
mode: EdgeDeletionMode.FROM_DRG_AND_ALL_DRDS,
});
@@ -150,7 +150,7 @@ export function DiagramCommands(props: {}) {
deleteNode({
drgEdges:
state.computed(state).getDiagramData(externalModelsByNamespace).drgEdges,
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
dmnObjectNamespace: node.data.dmnObjectNamespace ??
state.dmn.model.definitions["@_namespace"],
dmnObjectQName: node.data.dmnObjectQName,
dmnObjectId: node.data.dmnObject?.["@_id"],
@@ -235,7 +235,7 @@ export function DiagramCommands(props: {}) {
const { diagramElements, widths } = addOrGetDrd({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
});
diagramElements.push(...clipboard.shapes.map((s) => ({ ...s,
__$$element: "dmndi:DMNShape" as const })));
diagramElements.push(...clipboard.edges.map((s) => ({ ...s,
__$$element: "dmndi:DMNEdge" as const })));
@@ -307,7 +307,7 @@ export function DiagramCommands(props: {}) {
const { href: newNodeId } = addStandaloneNode({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
newNode: {
type: NODE_TYPES.group,
bounds: getBounds({
@@ -368,7 +368,7 @@ export function DiagramCommands(props: {}) {
externalDmnsIndex:
state.computed(state).getExternalModelTypesByNamespace(externalModelsByNamespace)
.dmns,
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
dmnObjectNamespace:
nodesById.get(edge.source)!.data.dmnObjectNamespace ??
state.dmn.model.definitions["@_namespace"],
dmnObjectId:
nodesById.get(edge.source)!.data.dmnObject?.["@_id"],
@@ -378,7 +378,7 @@ export function DiagramCommands(props: {}) {
externalDmnsIndex:
state.computed(state).getExternalModelTypesByNamespace(externalModelsByNamespace)
.dmns,
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
dmnObjectNamespace:
nodesById.get(edge.target)!.data.dmnObjectNamespace ??
state.dmn.model.definitions["@_namespace"],
dmnObjectId:
nodesById.get(edge.target)!.data.dmnObject?.["@_id"],
@@ -386,7 +386,7 @@ export function DiagramCommands(props: {}) {
) {
deleteEdge({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
edge: { id: edge.id, dmnObject: edge.data!.dmnObject },
mode: EdgeDeletionMode.FROM_CURRENT_DRD_ONLY,
});
@@ -403,7 +403,7 @@ export function DiagramCommands(props: {}) {
drgEdges: [], // Deleting from DRD only.
definitions: state.dmn.model.definitions,
externalDmnsIndex:
state.computed(state).getExternalModelTypesByNamespace(externalModelsByNamespace).dmns,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
dmnObjectNamespace: node.data.dmnObjectNamespace ??
state.dmn.model.definitions["@_namespace"],
dmnObjectQName: node.data.dmnObjectQName,
dmnObjectId: node.data.dmnObject?.["@_id"],
diff --git a/packages/dmn-editor/src/diagram/DrdSelectorPanel.tsx
b/packages/dmn-editor/src/diagram/DrdSelectorPanel.tsx
index 465cdb16004..65f6b15cc7c 100644
--- a/packages/dmn-editor/src/diagram/DrdSelectorPanel.tsx
+++ b/packages/dmn-editor/src/diagram/DrdSelectorPanel.tsx
@@ -37,11 +37,12 @@ import { useCallback } from "react";
export function DrdSelectorPanel() {
const thisDmn = useDmnEditorStore((s) => s.dmn);
const diagram = useDmnEditorStore((s) => s.diagram);
+ const drdIndex = useDmnEditorStore((s) => s.computed(s).getDrdIndex());
const isAlternativeInputDataShape = useDmnEditorStore((s) =>
s.computed(s).isAlternativeInputDataShape());
const drdName = useDmnEditorStore(
(s) =>
-
s.dmn.model.definitions["dmndi:DMNDI"]?.["dmndi:DMNDiagram"]?.[s.diagram.drdIndex]?.["@_name"]
||
- getDefaultDrdName({ drdIndex: s.diagram.drdIndex })
+
s.dmn.model.definitions["dmndi:DMNDI"]?.["dmndi:DMNDiagram"]?.[s.computed(s).getDrdIndex()]?.["@_name"]
||
+ getDefaultDrdName({ drdIndex: s.computed(s).getDrdIndex() })
);
const dmnEditorStoreApi = useDmnEditorStoreApi();
@@ -51,8 +52,8 @@ export function DrdSelectorPanel() {
const removeDrd = useCallback(() => {
dmnEditorStoreApi.setState((s) => {
const nextDrds =
s.dmn.model.definitions["dmndi:DMNDI"]?.["dmndi:DMNDiagram"];
- nextDrds?.splice(s.diagram.drdIndex, 1);
- s.diagram.drdIndex = Math.max(0, Math.min(s.diagram.drdIndex,
(nextDrds?.length ?? 0) - 1));
+ nextDrds?.splice(s.computed(s).getDrdIndex(), 1);
+ s.diagram.__unsafeDrdIndex = Math.max(0,
Math.min(s.computed(s).getDrdIndex(), (nextDrds?.length ?? 0) - 1));
});
}, [dmnEditorStoreApi]);
@@ -89,7 +90,7 @@ export function DrdSelectorPanel() {
drdIndex: newIndex,
});
- state.diagram.drdIndex = newIndex;
+ state.diagram.__unsafeDrdIndex = newIndex;
state.diagram.openLhsPanel = DiagramLhsPanel.DRG_NODES;
state.focus.consumableId = getDrdId({ drdIndex: newIndex });
});
@@ -118,10 +119,10 @@ export function DrdSelectorPanel() {
{drds.map((drd, i) => (
<React.Fragment key={drd["@_id"]!}>
<button
- className={i === diagram.drdIndex ? "active" : undefined}
+ className={i === drdIndex ? "active" : undefined}
onClick={() => {
dmnEditorStoreApi.setState((state) => {
- state.diagram.drdIndex = i;
+ state.diagram.__unsafeDrdIndex = i;
});
}}
>
@@ -165,7 +166,7 @@ export function DrdSelectorPanel() {
dmnEditorStoreApi.setState((s) => {
const { diagram: drd } = addOrGetDrd({
definitions: s.dmn.model.definitions,
- drdIndex: s.diagram.drdIndex,
+ drdIndex: s.computed(s).getDrdIndex(),
});
drd["@_useAlternativeInputDataShape"] = false;
})
@@ -187,7 +188,7 @@ export function DrdSelectorPanel() {
dmnEditorStoreApi.setState((s) => {
const { diagram: drd } = addOrGetDrd({
definitions: s.dmn.model.definitions,
- drdIndex: s.diagram.drdIndex,
+ drdIndex: s.computed(s).getDrdIndex(),
});
drd["@_useAlternativeInputDataShape"] = true;
})
diff --git a/packages/dmn-editor/src/diagram/Palette.tsx
b/packages/dmn-editor/src/diagram/Palette.tsx
index 6d21a3a2313..77a7f980b2a 100644
--- a/packages/dmn-editor/src/diagram/Palette.tsx
+++ b/packages/dmn-editor/src/diagram/Palette.tsx
@@ -63,6 +63,7 @@ export function Palette({ pulse }: { pulse: boolean }) {
const thisDmn = useDmnEditorStore((s) => s.dmn.model);
const rfStoreApi = RF.useStoreApi();
const isAlternativeInputDataShape = useDmnEditorStore((s) =>
s.computed(s).isAlternativeInputDataShape());
+ const drdIndex = useDmnEditorStore((s) => s.computed(s).getDrdIndex());
const groupNodes = useCallback(() => {
dmnEditorStoreApi.setState((state) => {
@@ -77,7 +78,7 @@ export function Palette({ pulse }: { pulse: boolean }) {
const { href: newNodeId } = addStandaloneNode({
definitions: state.dmn.model.definitions,
- drdIndex: diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
newNode: {
type: NODE_TYPES.group,
bounds: getBounds({
@@ -89,9 +90,9 @@ export function Palette({ pulse }: { pulse: boolean }) {
state.dispatch(state).diagram.setNodeStatus(newNodeId, { selected: true
});
});
- }, [diagram.drdIndex, dmnEditorStoreApi, rfStoreApi]);
+ }, [dmnEditorStoreApi, rfStoreApi]);
- const drd =
thisDmn.definitions["dmndi:DMNDI"]?.["dmndi:DMNDiagram"]?.[diagram.drdIndex];
+ const drd =
thisDmn.definitions["dmndi:DMNDI"]?.["dmndi:DMNDiagram"]?.[drdIndex];
const drdSelectorPopoverRef = React.useRef<HTMLDivElement>(null);
const nodesPalletePopoverRef = React.useRef<HTMLDivElement>(null);
@@ -107,15 +108,18 @@ export function Palette({ pulse }: { pulse: boolean }) {
validate={() => true}
allUniqueNames={() => new Map()}
name={drd?.["@_name"] ?? ""}
- prefix={`${diagram.drdIndex + 1}.`}
- id={getDrdId({ drdIndex: diagram.drdIndex })}
+ prefix={`${drdIndex + 1}.`}
+ id={getDrdId({ drdIndex: drdIndex })}
onRenamed={(newName) => {
dmnEditorStoreApi.setState((state) => {
- const drd = addOrGetDrd({ definitions:
state.dmn.model.definitions, drdIndex: diagram.drdIndex });
+ const drd = addOrGetDrd({
+ definitions: state.dmn.model.definitions,
+ drdIndex: state.computed(state).getDrdIndex(),
+ });
drd.diagram["@_name"] = newName;
});
}}
- placeholder={getDefaultDrdName({ drdIndex: diagram.drdIndex })}
+ placeholder={getDefaultDrdName({ drdIndex: drdIndex })}
isReadonly={false}
isPlain={true}
shouldCommitOnBlur={true}
diff --git a/packages/dmn-editor/src/diagram/edges/Waypoints.tsx
b/packages/dmn-editor/src/diagram/edges/Waypoints.tsx
index e5fca361a2a..643d25185d0 100644
--- a/packages/dmn-editor/src/diagram/edges/Waypoints.tsx
+++ b/packages/dmn-editor/src/diagram/edges/Waypoints.tsx
@@ -68,7 +68,7 @@ export function Waypoint({
}) {
const circleRef = React.useRef<SVGCircleElement>(null);
const diagram = useDmnEditorStore((s) => s.diagram);
- const dispatch = useDmnEditorStore((s) => s.dispatch);
+ const drdIndex = useDmnEditorStore((s) => s.computed(s).getDrdIndex());
const { setState } = useDmnEditorStoreApi();
useEffect(() => {
@@ -85,7 +85,7 @@ export function Waypoint({
setState((state) => {
repositionEdgeWaypoint({
definitions: state.dmn.model.definitions,
- drdIndex: diagram.drdIndex,
+ drdIndex: drdIndex,
edgeIndex,
waypointIndex: index,
waypoint: snapPoint(diagram.snapGrid, { "@_x": e.x, "@_y": e.y }),
@@ -101,7 +101,7 @@ export function Waypoint({
return () => {
selection.on(".drag", null);
};
- }, [diagram.drdIndex, diagram.snapGrid, edgeId, edgeIndex, index,
onDragStop, setState]);
+ }, [drdIndex, diagram.snapGrid, edgeId, edgeIndex, index, onDragStop,
setState]);
return (
<circle
@@ -118,7 +118,7 @@ export function Waypoint({
setState((state) => {
deleteEdgeWaypoint({
definitions: state.dmn.model.definitions,
- drdIndex: diagram.drdIndex,
+ drdIndex: drdIndex,
edgeIndex,
waypointIndex: index,
});
diff --git
a/packages/dmn-editor/src/diagram/edges/usePotentialWaypointControls.ts
b/packages/dmn-editor/src/diagram/edges/usePotentialWaypointControls.ts
index 4106ae35051..1a80d491a4b 100644
--- a/packages/dmn-editor/src/diagram/edges/usePotentialWaypointControls.ts
+++ b/packages/dmn-editor/src/diagram/edges/usePotentialWaypointControls.ts
@@ -34,7 +34,7 @@ export function usePotentialWaypointControls(
interactionPathRef: React.RefObject<SVGPathElement>
) {
const snapGrid = useDmnEditorStore((s) => s.diagram.snapGrid);
- const drdIndex = useDmnEditorStore((s) => s.diagram.drdIndex);
+ const drdIndex = useDmnEditorStore((s) => s.computed(s).getDrdIndex());
const isDraggingWaypoint = useDmnEditorStore((s) =>
!!s.diagram.draggingWaypoints.find((e) => e === edgeId));
const dmnEditorStoreApi = useDmnEditorStoreApi();
const reactFlowInstance = RF.useReactFlow<DmnDiagramNodeData,
DmnDiagramEdgeData>();
diff --git a/packages/dmn-editor/src/diagram/nodes/Nodes.tsx
b/packages/dmn-editor/src/diagram/nodes/Nodes.tsx
index fed4d403ab6..cf7a7240e6b 100644
--- a/packages/dmn-editor/src/diagram/nodes/Nodes.tsx
+++ b/packages/dmn-editor/src/diagram/nodes/Nodes.tsx
@@ -962,7 +962,7 @@ export const DecisionServiceNode = React.memo(
dmnEditorStoreApi.setState((state) => {
updateDecisionServiceDividerLine({
definitions: state.dmn.model.definitions,
- drdIndex: state.diagram.drdIndex,
+ drdIndex: state.computed(state).getDrdIndex(),
dmnShapesByHref:
state.computed(state).indexedDrd().dmnShapesByHref,
drgElementIndex: index,
shapeIndex: shape.index,
diff --git a/packages/dmn-editor/src/propertiesPanel/FontOptions.tsx
b/packages/dmn-editor/src/propertiesPanel/FontOptions.tsx
index b87b0cf7b2a..fabeac4a0fc 100644
--- a/packages/dmn-editor/src/propertiesPanel/FontOptions.tsx
+++ b/packages/dmn-editor/src/propertiesPanel/FontOptions.tsx
@@ -88,7 +88,10 @@ export function FontOptions({ startExpanded, nodeIds }: {
startExpanded: boolean
const setShapeStyles = useCallback(
(callback: (shape: DMNDI15__DMNShape[], state: State) => void) => {
dmnEditorStoreApi.setState((s) => {
- const { diagramElements } = addOrGetDrd({ definitions:
s.dmn.model.definitions, drdIndex: s.diagram.drdIndex });
+ const { diagramElements } = addOrGetDrd({
+ definitions: s.dmn.model.definitions,
+ drdIndex: s.computed(s).getDrdIndex(),
+ });
const shapes = nodeIds.map((nodeId) => {
const shape = s.computed(s).indexedDrd().dmnShapesByHref.get(nodeId);
diff --git a/packages/dmn-editor/src/propertiesPanel/ShapeOptions.tsx
b/packages/dmn-editor/src/propertiesPanel/ShapeOptions.tsx
index b58e300ee03..bf3f81c8e09 100644
--- a/packages/dmn-editor/src/propertiesPanel/ShapeOptions.tsx
+++ b/packages/dmn-editor/src/propertiesPanel/ShapeOptions.tsx
@@ -109,7 +109,10 @@ export function ShapeOptions({
const setBounds = useCallback(
(callback: (bounds: DC__Bounds, state: State) => void, nodeId: string) => {
dmnEditorStoreApi.setState((s) => {
- const { diagramElements } = addOrGetDrd({ definitions:
s.dmn.model.definitions, drdIndex: s.diagram.drdIndex });
+ const { diagramElements } = addOrGetDrd({
+ definitions: s.dmn.model.definitions,
+ drdIndex: s.computed(s).getDrdIndex(),
+ });
const index =
s.computed(s).indexedDrd()?.dmnShapesByHref?.get(nodeId)?.index ?? -1;
if (index < 0) {
@@ -204,7 +207,10 @@ export function ShapeOptions({
) => void
) => {
dmnEditorStoreApi.setState((s) => {
- const { diagramElements } = addOrGetDrd({ definitions:
s.dmn.model.definitions, drdIndex: s.diagram.drdIndex });
+ const { diagramElements } = addOrGetDrd({
+ definitions: s.dmn.model.definitions,
+ drdIndex: s.computed(s).getDrdIndex(),
+ });
const shapesWithMinNodeSize = nodeIds.map((nodeId) => {
const shape = s.computed(s).indexedDrd().dmnShapesByHref.get(nodeId);
diff --git a/packages/dmn-editor/src/store/Store.ts
b/packages/dmn-editor/src/store/Store.ts
index 108f9fa5385..99ccdb6b8cd 100644
--- a/packages/dmn-editor/src/store/Store.ts
+++ b/packages/dmn-editor/src/store/Store.ts
@@ -88,7 +88,7 @@ export interface State {
tab: DmnEditorTab;
};
diagram: {
- drdIndex: number;
+ __unsafeDrdIndex: number;
edgeIdBeingUpdated: string | undefined;
dropTargetNode: DropTargetNode;
ongoingConnection: RF.OnConnectStartParams | undefined;
@@ -136,6 +136,12 @@ export type Computed = {
e: ExternalModelsIndex | undefined
) => ReturnType<typeof computeExternalModelsByType>;
+ /**
+ * Get a valid DRD index.
+ * `__unsafeDrdIndex` can point to a DRD that doens't exist.
+ */
+ getDrdIndex(): number;
+
getDataTypes(e: ExternalModelsIndex | undefined): ReturnType<typeof
computeDataTypes>;
getAllFeelVariableUniqueNames(): ReturnType<typeof
computeAllFeelVariableUniqueNames>;
@@ -181,7 +187,7 @@ export const defaultStaticState = (): Omit<State, "dmn" |
"dispatch" | "computed
expandedItemComponentIds: [],
},
diagram: {
- drdIndex: 0,
+ __unsafeDrdIndex: 0,
edgeIdBeingUpdated: undefined,
dropTargetNode: undefined,
ongoingConnection: undefined,
@@ -334,7 +340,7 @@ export function createDmnEditorStore(model:
State["dmn"]["model"], computedCache
return computedCache.cached("indexedDrd", computeIndexedDrd, [
s.dmn.model.definitions["@_namespace"],
s.dmn.model.definitions,
- s.diagram.drdIndex,
+ s.computed(s).getDrdIndex(),
]);
},
@@ -348,7 +354,7 @@ export function createDmnEditorStore(model:
State["dmn"]["model"], computedCache
computedCache.cached(
"isAlternativeInputDataShape",
(drdIndex, dmnDiagram) =>
dmnDiagram?.[drdIndex]?.["@_useAlternativeInputDataShape"] ?? false,
- [s.diagram.drdIndex,
s.dmn.model.definitions["dmndi:DMNDI"]?.["dmndi:DMNDiagram"]] as const
+ [s.computed(s).getDrdIndex(),
s.dmn.model.definitions["dmndi:DMNDI"]?.["dmndi:DMNDiagram"]] as const
),
isDropTargetNodeValidForSelection: (externalModelsByNamespace:
ExternalModelsIndex | undefined) =>
@@ -357,6 +363,16 @@ export function createDmnEditorStore(model:
State["dmn"]["model"], computedCache
s.computed(s).getDiagramData(externalModelsByNamespace),
]),
+ getDrdIndex: () =>
+ computedCache.cached(
+ "getDrdIndex",
+ (__unsafeDrdIndex, dmnDiagram) =>
+ dmnDiagram?.length && __unsafeDrdIndex > dmnDiagram.length - 1
+ ? dmnDiagram.length - 1
+ : __unsafeDrdIndex,
+ [s.diagram.__unsafeDrdIndex,
s.dmn.model.definitions["dmndi:DMNDI"]?.["dmndi:DMNDiagram"]] as const
+ ),
+
getDataTypes: (externalModelsByNamespace: ExternalModelsIndex |
undefined) =>
computedCache.cached("getDataTypes", computeDataTypes, [
s.dmn.model.definitions["@_namespace"],
diff --git a/packages/dmn-editor/src/store/computed/computeIndexes.ts
b/packages/dmn-editor/src/store/computed/computeIndexes.ts
index 3d1d4d68c5e..56ac9bac6fd 100644
--- a/packages/dmn-editor/src/store/computed/computeIndexes.ts
+++ b/packages/dmn-editor/src/store/computed/computeIndexes.ts
@@ -21,12 +21,12 @@ import { DMNDI15__DMNEdge, DMNDI15__DMNShape } from
"@kie-tools/dmn-marshaller/d
import { XmlQName, parseXmlQName } from "@kie-tools/xml-parser-ts/dist/qNames";
import { KIE_DMN_UNKNOWN_NAMESPACE } from
"@kie-tools/dmn-marshaller/dist/schemas/dmn-1_5/Dmn15Spec";
import { buildXmlHref } from "../../xml/xmlHrefs";
-import { State } from "../Store";
+import { Computed, State } from "../Store";
export function computeIndexedDrd(
thisDmnsNamespace: string,
definitions: State["dmn"]["model"]["definitions"],
- drdIndex: State["diagram"]["drdIndex"]
+ drdIndex: ReturnType<Computed["getDrdIndex"]>
) {
const dmnEdgesByDmnElementRef = new Map<string, DMNDI15__DMNEdge & { index:
number }>();
const dmnShapesByHref = new Map<string, DMNDI15__DMNShape & { index: number;
dmnElementRefQName: XmlQName }>();
diff --git a/packages/dmn-editor/src/store/computed/initial.ts
b/packages/dmn-editor/src/store/computed/initial.ts
index 89c8d98bead..7efe970d57e 100644
--- a/packages/dmn-editor/src/store/computed/initial.ts
+++ b/packages/dmn-editor/src/store/computed/initial.ts
@@ -57,4 +57,8 @@ export const INITIAL_COMPUTED_CACHE: Cache<Computed> = {
value: undefined,
dependencies: [],
},
+ getDrdIndex: {
+ value: undefined,
+ dependencies: [],
+ },
};
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]