From 9e4baa25649928049c9440faa9b98bca05f64e20 Mon Sep 17 00:00:00 2001 From: Janis Joderi Shoferi Date: Thu, 23 Nov 2023 18:03:07 +0100 Subject: [PATCH 1/3] Fixed: breadcrumbs that show the current position in the subprocess hierarchy of a process not displayed correctly. Related to: #168 --- src/management-system-v2/app/globals.css | 9 ++++++++- src/management-system-v2/components/modeler.tsx | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/management-system-v2/app/globals.css b/src/management-system-v2/app/globals.css index a7cc15549..918cd8ad5 100644 --- a/src/management-system-v2/app/globals.css +++ b/src/management-system-v2/app/globals.css @@ -1,5 +1,12 @@ .bpmn-js-modeler-with-toolbar .djs-palette { - top: 125px; + top: 70px; +} + +.bpmn-js-modeler-with-toolbar .bjs-breadcrumbs { + top: unset; + left: 15px !important; + bottom: 10px; + font-size: 20px; } /* Workaround to make flex with breakpoints work. See: https://github.com/ant-design/ant-design/issues/28961#issuecomment-1712966521 */ diff --git a/src/management-system-v2/components/modeler.tsx b/src/management-system-v2/components/modeler.tsx index 1a5263f20..e2a9f06ed 100644 --- a/src/management-system-v2/components/modeler.tsx +++ b/src/management-system-v2/components/modeler.tsx @@ -1,6 +1,7 @@ 'use client'; import React, { FC, useEffect, useRef, useState } from 'react'; +import 'bpmn-js/dist/assets/bpmn-js.css'; import 'bpmn-js/dist/assets/diagram-js.css'; import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'; import type ModelerType from 'bpmn-js/lib/Modeler'; From ba05ba86de716849e8482382121573ea66081df4 Mon Sep 17 00:00:00 2001 From: Janis Joderi Shoferi Date: Fri, 24 Nov 2023 12:13:25 +0100 Subject: [PATCH 2/3] Added undo and redo buttons to the modeler toolbar. Related to: #168 --- .../components/modeler-toolbar.tsx | 95 ++++++++++++------- .../components/modeler.tsx | 6 +- .../lib/use-modeler-state-store.ts | 5 + 3 files changed, 73 insertions(+), 33 deletions(-) diff --git a/src/management-system-v2/components/modeler-toolbar.tsx b/src/management-system-v2/components/modeler-toolbar.tsx index 5f2c5a46e..6879d674f 100644 --- a/src/management-system-v2/components/modeler-toolbar.tsx +++ b/src/management-system-v2/components/modeler-toolbar.tsx @@ -1,18 +1,19 @@ 'use client'; -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import type ElementRegistry from 'diagram-js/lib/core/ElementRegistry'; +import type CommandStack from 'diagram-js/lib/command/CommandStack'; -import { Row, Col, Tooltip, Button } from 'antd'; +import { Tooltip, Button, Space } from 'antd'; import { Toolbar, ToolbarGroup } from './toolbar'; import Icon, { - FormOutlined, ExportOutlined, - EyeOutlined, SettingOutlined, PlusOutlined, + UndoOutlined, + RedoOutlined, } from '@ant-design/icons'; import { SvgXML, SvgShare } from '@/components/svg'; @@ -26,7 +27,7 @@ import ProcessExportModal from './process-export'; import { createNewProcessVersion } from '@/lib/helpers/processVersioning'; import VersionCreationButton from './version-creation-button'; -import { useQueryClient } from '@tanstack/react-query'; + import { useInvalidateAsset } from '@/lib/fetch-data'; type ModelerToolbarProps = { @@ -40,7 +41,11 @@ const ModelerToolbar: React.FC = ({ onOpenXmlEditor }) => { const [showPropertiesPanel, setShowPropertiesPanel] = useState(false); const [showProcessExportModal, setShowProcessExportModal] = useState(false); + const [canUndo, setCanUndo] = useState(false); + const [canRedo, setCanRedo] = useState(false); + const modeler = useModelerStateStore((state) => state.modeler); + const editingDisabled = useModelerStateStore((state) => state.editingDisabled); const selectedElementId = useModelerStateStore((state) => state.selectedElementId); const { processId } = useParams(); @@ -65,6 +70,16 @@ const ModelerToolbar: React.FC = ({ onOpenXmlEditor }) => { : elementRegistry.getAll().filter((el) => el.businessObject.$type === 'bpmn:Process')[0]; } + useEffect(() => { + if (modeler) { + modeler.on('commandStack.changed', () => { + const commandStack = modeler.get('commandStack') as CommandStack; + setCanUndo(commandStack.canUndo()); + setCanRedo(commandStack.canRedo()); + }); + } + }, [modeler]); + const createProcessVersion = async (values: { versionName: string; versionDescription: string; @@ -91,44 +106,60 @@ const ModelerToolbar: React.FC = ({ onOpenXmlEditor }) => { const selectedVersion = useSearchParams().get('version'); + const handleUndo = () => { + if (modeler) (modeler.get('commandStack') as CommandStack).undo(); + }; + + const handleRedo = () => { + if (modeler) (modeler.get('commandStack') as CommandStack).redo(); + }; + return ( <> - - - - {/* + + + {/* - - - - - - + + + + + + + + + + + } + createVersion={createProcessVersion} + > + + + {!editingDisabled && modeler && ( + + + - - } - createVersion={createProcessVersion} - > + + - {showPropertiesPanel &&
} - - {/* {showPropertiesPanel && } */} - {showPropertiesPanel && selectedElement && ( - <> - - )} -
+ {showPropertiesPanel &&
} + + {/* {showPropertiesPanel && } */} + {showPropertiesPanel && selectedElement && ( + <> + + + )}
{/* {showPropertiesPanel && selectedElement && ( diff --git a/src/management-system-v2/components/modeler.tsx b/src/management-system-v2/components/modeler.tsx index e2a9f06ed..1cc832f0c 100644 --- a/src/management-system-v2/components/modeler.tsx +++ b/src/management-system-v2/components/modeler.tsx @@ -48,6 +48,7 @@ const Modeler: FC = ({ minimized, ...props }) => { const setModeler = useModelerStateStore((state) => state.setModeler); const setSelectedElementId = useModelerStateStore((state) => state.setSelectedElementId); + const setEditingDisabled = useModelerStateStore((state) => state.setEditingDisabled); /// Derived State const selectedVersionId = query.get('version'); @@ -70,6 +71,7 @@ const Modeler: FC = ({ minimized, ...props }) => { proceed: schema, }, }); + setEditingDisabled(true); } else { modeler.current = new Modeler!({ container: canvas.current!, @@ -80,7 +82,7 @@ const Modeler: FC = ({ minimized, ...props }) => { // update process after change with 2 second debounce let timer: ReturnType; - modeler.current.on('commandStack.changed', async () => { + modeler.current.on('commandStack.changed', () => { clearTimeout(timer); timer = setTimeout(async () => { try { @@ -95,6 +97,8 @@ const Modeler: FC = ({ minimized, ...props }) => { } }, 2000); }); + + setEditingDisabled(false); } // allow keyboard shortcuts like copy (strg+c) and paste (strg+v) etc. diff --git a/src/management-system-v2/lib/use-modeler-state-store.ts b/src/management-system-v2/lib/use-modeler-state-store.ts index 01a89d6ef..8f3e647c6 100644 --- a/src/management-system-v2/lib/use-modeler-state-store.ts +++ b/src/management-system-v2/lib/use-modeler-state-store.ts @@ -10,6 +10,7 @@ type ModelerStateStore = { editingDisabled: boolean; setModeler: (newModeler: Modeler | Viewer | null) => void; setSelectedElementId: (newId: null | string) => void; + setEditingDisabled: (isDisabled: boolean) => void; }; const useModelerStateStore = create()( @@ -25,6 +26,10 @@ const useModelerStateStore = create()( set((state) => { state.selectedElementId = newId; }), + setEditingDisabled: (isDisabled: boolean) => + set((state) => { + state.editingDisabled = isDisabled; + }), })), ); From 6b6ab6440cfb497e4c3132ad7e170efd48db843e Mon Sep 17 00:00:00 2001 From: Janis Joderi Shoferi Date: Fri, 24 Nov 2023 12:26:48 +0100 Subject: [PATCH 3/3] Fixed: the state of canUndo and canRedo is not correctly reset when switching between the modeler and the viewer and back --- src/management-system-v2/components/modeler-toolbar.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/management-system-v2/components/modeler-toolbar.tsx b/src/management-system-v2/components/modeler-toolbar.tsx index 6879d674f..b0ccebb59 100644 --- a/src/management-system-v2/components/modeler-toolbar.tsx +++ b/src/management-system-v2/components/modeler-toolbar.tsx @@ -72,8 +72,15 @@ const ModelerToolbar: React.FC = ({ onOpenXmlEditor }) => { useEffect(() => { if (modeler) { + const commandStack = modeler.get('commandStack', false) as CommandStack; + // check if there is a commandStack (does not exist on the viewer used when editing is disabled) + if (commandStack) { + // init canUndo and canRedo + setCanUndo(commandStack.canUndo()); + setCanRedo(commandStack.canRedo()); + } modeler.on('commandStack.changed', () => { - const commandStack = modeler.get('commandStack') as CommandStack; + // update canUndo and canRedo when the state of the modelers commandStack changes setCanUndo(commandStack.canUndo()); setCanRedo(commandStack.canRedo()); });