From 8ed6aefc16a97f14ecb24b12f312fe068e5180e3 Mon Sep 17 00:00:00 2001 From: Ivan <8611739+IRBorisov@users.noreply.github.com> Date: Wed, 26 Feb 2025 12:55:10 +0300 Subject: [PATCH] F: Improve OSS graph interactions --- .../EditorOssGraph/NodeContextMenu.tsx | 119 ++++++++++---- .../pages/OssPage/EditorOssGraph/OssFlow.tsx | 153 +++++------------- .../EditorOssGraph/ToolbarOssGraph.tsx | 78 ++++++--- .../OssPage/EditorOssGraph/graph/NodeCore.tsx | 1 + .../EditorOssGraph/useGetPositions.tsx | 12 ++ .../oss/pages/OssPage/MenuEditOss.tsx | 11 +- .../oss/pages/OssPage/OssEditContext.tsx | 100 ++---------- 7 files changed, 213 insertions(+), 261 deletions(-) create mode 100644 rsconcept/frontend/src/features/oss/pages/OssPage/EditorOssGraph/useGetPositions.tsx diff --git a/rsconcept/frontend/src/features/oss/pages/OssPage/EditorOssGraph/NodeContextMenu.tsx b/rsconcept/frontend/src/features/oss/pages/OssPage/EditorOssGraph/NodeContextMenu.tsx index c3459303..e597eb5b 100644 --- a/rsconcept/frontend/src/features/oss/pages/OssPage/EditorOssGraph/NodeContextMenu.tsx +++ b/rsconcept/frontend/src/features/oss/pages/OssPage/EditorOssGraph/NodeContextMenu.tsx @@ -1,6 +1,12 @@ 'use client'; import { useRef } from 'react'; +import { toast } from 'react-toastify'; + +import { urls, useConceptNavigation } from '@/app'; +import { useLibrary } from '@/features/library/backend/useLibrary'; +import { useInputCreate } from '@/features/oss/backend/useInputCreate'; +import { useOperationExecute } from '@/features/oss/backend/useOperationExecute'; import { Dropdown, DropdownButton } from '@/components/Dropdown'; import { @@ -13,6 +19,8 @@ import { IconRSForm } from '@/components/Icons'; import { useClickedOutside } from '@/hooks/useClickedOutside'; +import { useDialogsStore } from '@/stores/dialogs'; +import { errorMsg } from '@/utils/labels'; import { prepareTooltip } from '@/utils/utils'; import { OperationType } from '../../../backend/types'; @@ -20,12 +28,14 @@ import { useMutatingOss } from '../../../backend/useMutatingOss'; import { type IOperation } from '../../../models/oss'; import { useOssEdit } from '../OssEditContext'; +import { useGetPositions } from './useGetPositions'; + // pixels - size of OSS context menu const MENU_WIDTH = 200; const MENU_HEIGHT = 200; export interface ContextMenuData { - operation: IOperation; + operation: IOperation | null; cursorX: number; cursorY: number; } @@ -33,33 +43,25 @@ export interface ContextMenuData { interface NodeContextMenuProps extends ContextMenuData { isOpen: boolean; onHide: () => void; - onDelete: (target: number) => void; - onCreateInput: (target: number) => void; - onEditSchema: (target: number) => void; - onEditOperation: (target: number) => void; - onExecuteOperation: (target: number) => void; - onRelocateConstituents: (target: number) => void; } -export function NodeContextMenu({ - isOpen, - operation, - cursorX, - cursorY, - onHide, - onDelete, - onCreateInput, - onEditSchema, - onEditOperation, - onExecuteOperation, - onRelocateConstituents -}: NodeContextMenuProps) { +export function NodeContextMenu({ isOpen, operation, cursorX, cursorY, onHide }: NodeContextMenuProps) { + const router = useConceptNavigation(); + const { items: libraryItems } = useLibrary(); + const { schema, navigateOperationSchema, isMutable, canDeleteOperation: canDelete } = useOssEdit(); const isProcessing = useMutatingOss(); - const { schema, navigateOperationSchema, isMutable, canDelete } = useOssEdit(); + const getPositions = useGetPositions(); + + const { inputCreate } = useInputCreate(); + const { operationExecute } = useOperationExecute(); + + const showEditInput = useDialogsStore(state => state.showChangeInputSchema); + const showRelocateConstituents = useDialogsStore(state => state.showRelocateConstituents); + const showEditOperation = useDialogsStore(state => state.showEditOperation); + const showDeleteOperation = useDialogsStore(state => state.showDeleteOperation); - const ref = useRef(null); const readyForSynthesis = (() => { - if (operation.operation_type !== OperationType.SYNTHESIS) { + if (operation?.operation_type !== OperationType.SYNTHESIS) { return false; } if (operation.result) { @@ -79,40 +81,89 @@ export function NodeContextMenu({ return true; })(); + const ref = useRef(null); useClickedOutside(isOpen, ref, onHide); function handleOpenSchema() { + if (!operation) { + return; + } + onHide(); navigateOperationSchema(operation.id); } function handleEditSchema() { + if (!operation) { + return; + } onHide(); - onEditSchema(operation.id); + showEditInput({ + oss: schema, + target: operation, + positions: getPositions() + }); } function handleEditOperation() { + if (!operation) { + return; + } onHide(); - onEditOperation(operation.id); + showEditOperation({ + oss: schema, + target: operation, + positions: getPositions() + }); } function handleDeleteOperation() { + if (!operation || !canDelete(operation)) { + return; + } onHide(); - onDelete(operation.id); + showDeleteOperation({ + oss: schema, + target: operation, + positions: getPositions() + }); } - function handleCreateSchema() { + function handleOperationExecute() { + if (!operation) { + return; + } onHide(); - onCreateInput(operation.id); + void operationExecute({ + itemID: schema.id, // + data: { target: operation.id, positions: getPositions() } + }); } - function handleRunSynthesis() { + function handleInputCreate() { + if (!operation) { + return; + } + if (libraryItems.find(item => item.alias === operation.alias && item.location === schema.location)) { + toast.error(errorMsg.inputAlreadyExists); + return; + } onHide(); - onExecuteOperation(operation.id); + void inputCreate({ + itemID: schema.id, + data: { target: operation.id, positions: getPositions() } + }).then(new_schema => router.push(urls.schema(new_schema.id))); } function handleRelocateConstituents() { + if (!operation) { + return; + } onHide(); - onRelocateConstituents(operation.id); + showRelocateConstituents({ + oss: schema, + initialTarget: operation, + positions: getPositions() + }); } return ( @@ -145,7 +196,7 @@ export function NodeContextMenu({ title='Создать пустую схему для загрузки' icon={} disabled={isProcessing} - onClick={handleCreateSchema} + onClick={handleInputCreate} /> ) : null} {isMutable && operation?.operation_type === OperationType.INPUT ? ( @@ -167,7 +218,7 @@ export function NodeContextMenu({ } icon={} disabled={isProcessing || !readyForSynthesis} - onClick={handleRunSynthesis} + onClick={handleOperationExecute} /> ) : null} @@ -184,7 +235,7 @@ export function NodeContextMenu({ } - disabled={!isMutable || isProcessing || !operation || !canDelete(operation.id)} + disabled={!isMutable || isProcessing || !operation || !canDelete(operation)} onClick={handleDeleteOperation} /> diff --git a/rsconcept/frontend/src/features/oss/pages/OssPage/EditorOssGraph/OssFlow.tsx b/rsconcept/frontend/src/features/oss/pages/OssPage/EditorOssGraph/OssFlow.tsx index 993ce1c6..6345a90f 100644 --- a/rsconcept/frontend/src/features/oss/pages/OssPage/EditorOssGraph/OssFlow.tsx +++ b/rsconcept/frontend/src/features/oss/pages/OssPage/EditorOssGraph/OssFlow.tsx @@ -1,7 +1,6 @@ 'use client'; import { useEffect, useState } from 'react'; -import { toast } from 'react-toastify'; import { Background, type Node, @@ -12,18 +11,13 @@ import { useReactFlow } from 'reactflow'; -import { urls, useConceptNavigation } from '@/app'; -import { useLibrary } from '@/features/library/backend/useLibrary'; - import { Overlay } from '@/components/Container'; import { useMainHeight } from '@/stores/appLayout'; +import { useDialogsStore } from '@/stores/dialogs'; import { useTooltipsStore } from '@/stores/tooltips'; import { PARAMETER } from '@/utils/constants'; -import { errorMsg } from '@/utils/labels'; -import { useInputCreate } from '../../../backend/useInputCreate'; import { useMutatingOss } from '../../../backend/useMutatingOss'; -import { useOperationExecute } from '../../../backend/useOperationExecute'; import { useUpdatePositions } from '../../../backend/useUpdatePositions'; import { GRID_SIZE } from '../../../models/ossAPI'; import { type OssNode } from '../../../models/ossLayout'; @@ -33,9 +27,11 @@ import { useOssEdit } from '../OssEditContext'; import { OssNodeTypes } from './graph/OssNodeTypes'; import { type ContextMenuData, NodeContextMenu } from './NodeContextMenu'; import { ToolbarOssGraph } from './ToolbarOssGraph'; +import { useGetPositions } from './useGetPositions'; const ZOOM_MAX = 2; const ZOOM_MIN = 0.5; +export const VIEW_PADDING = 0.2; export function OssFlow() { const mainHeight = useMainHeight(); @@ -45,16 +41,9 @@ export function OssFlow() { setSelected, selected, isMutable, - promptCreateOperation, - canDelete, - promptDeleteOperation, - promptEditInput, - promptEditOperation, - promptRelocateConstituents + canDeleteOperation: canDelete } = useOssEdit(); - const router = useConceptNavigation(); - const { items: libraryItems } = useLibrary(); - const flow = useReactFlow(); + const { fitView, project } = useReactFlow(); const isProcessing = useMutatingOss(); @@ -64,16 +53,18 @@ export function OssFlow() { const edgeAnimate = useOSSGraphStore(state => state.edgeAnimate); const edgeStraight = useOSSGraphStore(state => state.edgeStraight); - const { inputCreate } = useInputCreate(); - const { operationExecute } = useOperationExecute(); + const getPositions = useGetPositions(); const { updatePositions } = useUpdatePositions(); const [nodes, setNodes, onNodesChange] = useNodesState([]); const [edges, setEdges, onEdgesChange] = useEdgesState([]); const [toggleReset, setToggleReset] = useState(false); - const [menuProps, setMenuProps] = useState(null); + const [menuProps, setMenuProps] = useState({ operation: null, cursorX: 0, cursorY: 0 }); const [isContextMenuOpen, setIsContextMenuOpen] = useState(false); + const showCreateOperation = useDialogsStore(state => state.showCreateOperation); + const showDeleteOperation = useDialogsStore(state => state.showDeleteOperation); + function onSelectionChange({ nodes }: { nodes: Node[] }) { const ids = nodes.map(node => Number(node.id)); setSelected(prev => [ @@ -109,15 +100,8 @@ export function OssFlow() { : 'left' })) ); - }, [schema, setNodes, setEdges, toggleReset, edgeStraight, edgeAnimate]); - - function getPositions() { - return nodes.map(node => ({ - id: Number(node.id), - position_x: node.position.x, - position_y: node.position.y - })); - } + setTimeout(() => fitView({ duration: PARAMETER.zoomDuration, padding: VIEW_PADDING }), PARAMETER.refreshTimeout); + }, [schema, setNodes, setEdges, toggleReset, edgeStraight, edgeAnimate, fitView]); function handleSavePositions() { const positions = getPositions(); @@ -132,73 +116,34 @@ export function OssFlow() { }); } - function handleCreateOperation(inputs: number[]) { - const positions = getPositions(); - const target = flow.project({ x: window.innerWidth / 2, y: window.innerHeight / 2 }); - promptCreateOperation({ - defaultX: target.x, - defaultY: target.y, - inputs: inputs, - positions: positions, - callback: () => setTimeout(() => flow.fitView({ duration: PARAMETER.zoomDuration }), PARAMETER.refreshTimeout) + function handleCreateOperation() { + const targetPosition = project({ x: window.innerWidth / 2, y: window.innerHeight / 2 }); + showCreateOperation({ + oss: schema, + defaultX: targetPosition.x, + defaultY: targetPosition.y, + positions: getPositions(), + initialInputs: selected, + onCreate: () => + setTimeout(() => fitView({ duration: PARAMETER.zoomDuration, padding: VIEW_PADDING }), PARAMETER.refreshTimeout) }); } - function handleDeleteOperation(target: number) { - if (!canDelete(target)) { - return; - } - promptDeleteOperation(target, getPositions()); - } - function handleDeleteSelected() { if (selected.length !== 1) { return; } - handleDeleteOperation(selected[0]); - } - - function handleInputCreate(target: number) { - const operation = schema.operationByID.get(target); - if (!operation) { + const operation = schema.operationByID.get(selected[0]); + if (!operation || !canDelete(operation)) { return; } - if (libraryItems.find(item => item.alias === operation.alias && item.location === schema.location)) { - toast.error(errorMsg.inputAlreadyExists); - return; - } - void inputCreate({ - itemID: schema.id, - data: { target: target, positions: getPositions() } - }).then(new_schema => router.push(urls.schema(new_schema.id))); - } - - function handleEditSchema(target: number) { - promptEditInput(target, getPositions()); - } - - function handleEditOperation(target: number) { - promptEditOperation(target, getPositions()); - } - - function handleOperationExecute(target: number) { - void operationExecute({ - itemID: schema.id, // - data: { target: target, positions: getPositions() } + showDeleteOperation({ + oss: schema, + target: operation, + positions: getPositions() }); } - function handleExecuteSelected() { - if (selected.length !== 1) { - return; - } - handleOperationExecute(selected[0]); - } - - function handleRelocateConstituents(target: number) { - promptRelocateConstituents(target, getPositions()); - } - function handleContextMenu(event: React.MouseEvent, node: OssNode) { event.preventDefault(); event.stopPropagation(); @@ -212,14 +157,6 @@ export function OssFlow() { setHoverOperation(null); } - function handleContextMenuHide() { - setIsContextMenuOpen(false); - } - - function handleCanvasClick() { - handleContextMenuHide(); - } - function handleNodeDoubleClick(event: React.MouseEvent, node: OssNode) { event.preventDefault(); event.stopPropagation(); @@ -229,10 +166,7 @@ export function OssFlow() { } function handleKeyDown(event: React.KeyboardEvent) { - if (isProcessing) { - return; - } - if (!isMutable) { + if (isProcessing || !isMutable) { return; } if ((event.ctrlKey || event.metaKey) && event.code === 'KeyS') { @@ -244,7 +178,7 @@ export function OssFlow() { if ((event.ctrlKey || event.metaKey) && event.code === 'KeyQ') { event.preventDefault(); event.stopPropagation(); - handleCreateOperation(selected); + handleCreateOperation(); return; } if (event.key === 'Delete') { @@ -262,35 +196,20 @@ export function OssFlow() { className='rounded-b-2xl cc-blur hover:bg-prim-100 hover:bg-opacity-50' > flow.fitView({ duration: PARAMETER.zoomDuration })} - onCreate={() => handleCreateOperation(selected)} + onCreate={handleCreateOperation} onDelete={handleDeleteSelected} - onEdit={() => handleEditOperation(selected[0])} - onExecute={handleExecuteSelected} onResetPositions={() => setToggleReset(prev => !prev)} - onSavePositions={handleSavePositions} /> - {menuProps ? ( - - ) : null} + + setIsContextMenuOpen(false)} {...menuProps} /> +
setIsContextMenuOpen(false)} + onNodeDoubleClick={handleNodeDoubleClick} onNodeContextMenu={handleContextMenu} - onClick={handleCanvasClick} + onNodeDragStart={() => setIsContextMenuOpen(false)} > {showGrid ? : null} diff --git a/rsconcept/frontend/src/features/oss/pages/OssPage/EditorOssGraph/ToolbarOssGraph.tsx b/rsconcept/frontend/src/features/oss/pages/OssPage/EditorOssGraph/ToolbarOssGraph.tsx index d9decbf3..1b8d3f92 100644 --- a/rsconcept/frontend/src/features/oss/pages/OssPage/EditorOssGraph/ToolbarOssGraph.tsx +++ b/rsconcept/frontend/src/features/oss/pages/OssPage/EditorOssGraph/ToolbarOssGraph.tsx @@ -1,9 +1,12 @@ 'use client'; +import { useReactFlow } from 'reactflow'; import clsx from 'clsx'; import { HelpTopic } from '@/features/help'; import { BadgeHelp } from '@/features/help/components'; +import { useOperationExecute } from '@/features/oss/backend/useOperationExecute'; +import { useUpdatePositions } from '@/features/oss/backend/useUpdatePositions'; import { MiniButton } from '@/components/Control'; import { @@ -20,6 +23,7 @@ import { IconReset, IconSave } from '@/components/Icons'; +import { useDialogsStore } from '@/stores/dialogs'; import { PARAMETER } from '@/utils/constants'; import { prepareTooltip } from '@/utils/utils'; @@ -28,28 +32,21 @@ import { useMutatingOss } from '../../../backend/useMutatingOss'; import { useOSSGraphStore } from '../../../stores/ossGraph'; import { useOssEdit } from '../OssEditContext'; +import { VIEW_PADDING } from './OssFlow'; +import { useGetPositions } from './useGetPositions'; + interface ToolbarOssGraphProps { onCreate: () => void; onDelete: () => void; - onEdit: () => void; - onExecute: () => void; - onFitView: () => void; - onSavePositions: () => void; onResetPositions: () => void; } -export function ToolbarOssGraph({ - onCreate, - onDelete, - onEdit, - onExecute, - onFitView, - onSavePositions, - onResetPositions -}: ToolbarOssGraphProps) { - const { schema, selected, isMutable, canDelete } = useOssEdit(); +export function ToolbarOssGraph({ onCreate, onDelete, onResetPositions }: ToolbarOssGraphProps) { + const { schema, selected, isMutable, canDeleteOperation: canDelete } = useOssEdit(); const isProcessing = useMutatingOss(); + const { fitView } = useReactFlow(); const selectedOperation = schema.operationByID.get(selected[0]); + const getPositions = useGetPositions(); const showGrid = useOSSGraphStore(state => state.showGrid); const edgeAnimate = useOSSGraphStore(state => state.edgeAnimate); @@ -58,6 +55,11 @@ export function ToolbarOssGraph({ const toggleEdgeAnimate = useOSSGraphStore(state => state.toggleEdgeAnimate); const toggleEdgeStraight = useOSSGraphStore(state => state.toggleEdgeStraight); + const { updatePositions } = useUpdatePositions(); + const { operationExecute } = useOperationExecute(); + + const showEditOperation = useDialogsStore(state => state.showEditOperation); + const readyForSynthesis = (() => { if (!selectedOperation || selectedOperation.operation_type !== OperationType.SYNTHESIS) { return false; @@ -79,6 +81,44 @@ export function ToolbarOssGraph({ return true; })(); + function handleFitView() { + fitView({ duration: PARAMETER.zoomDuration, padding: VIEW_PADDING }); + } + + function handleSavePositions() { + const positions = getPositions(); + void updatePositions({ itemID: schema.id, positions: positions }).then(() => { + positions.forEach(item => { + const operation = schema.operationByID.get(item.id); + if (operation) { + operation.position_x = item.position_x; + operation.position_y = item.position_y; + } + }); + }); + } + + function handleOperationExecute() { + if (selected.length !== 1 || !readyForSynthesis || !selectedOperation) { + return; + } + void operationExecute({ + itemID: schema.id, // + data: { target: selectedOperation.id, positions: getPositions() } + }); + } + + function handleEditOperation() { + if (selected.length !== 1 || !selectedOperation) { + return; + } + showEditOperation({ + oss: schema, + target: selectedOperation, + positions: getPositions() + }); + } + return (
@@ -90,7 +130,7 @@ export function ToolbarOssGraph({ } title='Сбросить вид' - onClick={onFitView} + onClick={handleFitView} /> } disabled={isProcessing} - onClick={onSavePositions} + onClick={handleSavePositions} /> } disabled={isProcessing || selected.length !== 1 || !readyForSynthesis} - onClick={onExecute} + onClick={handleOperationExecute} /> } disabled={selected.length !== 1 || isProcessing} - onClick={onEdit} + onClick={handleEditOperation} /> } - disabled={selected.length !== 1 || isProcessing || !canDelete(selected[0])} + disabled={selected.length !== 1 || isProcessing || !selectedOperation || !canDelete(selectedOperation)} onClick={onDelete} />
diff --git a/rsconcept/frontend/src/features/oss/pages/OssPage/EditorOssGraph/graph/NodeCore.tsx b/rsconcept/frontend/src/features/oss/pages/OssPage/EditorOssGraph/graph/NodeCore.tsx index c2b6e544..204cb7b1 100644 --- a/rsconcept/frontend/src/features/oss/pages/OssPage/EditorOssGraph/graph/NodeCore.tsx +++ b/rsconcept/frontend/src/features/oss/pages/OssPage/EditorOssGraph/graph/NodeCore.tsx @@ -54,6 +54,7 @@ export function NodeCore({ node }: NodeCoreProps) {
setHover(node.data.operation)} >
({ + id: Number(node.id), + position_x: node.position.x, + position_y: node.position.y + })); + }; +} diff --git a/rsconcept/frontend/src/features/oss/pages/OssPage/MenuEditOss.tsx b/rsconcept/frontend/src/features/oss/pages/OssPage/MenuEditOss.tsx index 4d74934c..38923c8f 100644 --- a/rsconcept/frontend/src/features/oss/pages/OssPage/MenuEditOss.tsx +++ b/rsconcept/frontend/src/features/oss/pages/OssPage/MenuEditOss.tsx @@ -3,6 +3,7 @@ import { useAuthSuspense } from '@/features/auth'; import { Button } from '@/components/Control'; import { Dropdown, DropdownButton, useDropdown } from '@/components/Dropdown'; import { IconChild, IconEdit2 } from '@/components/Icons'; +import { useDialogsStore } from '@/stores/dialogs'; import { useMutatingOss } from '../../backend/useMutatingOss'; @@ -11,12 +12,18 @@ import { useOssEdit } from './OssEditContext'; export function MenuEditOss() { const { isAnonymous } = useAuthSuspense(); const editMenu = useDropdown(); - const { promptRelocateConstituents, isMutable } = useOssEdit(); + const { schema, isMutable } = useOssEdit(); const isProcessing = useMutatingOss(); + const showRelocateConstituents = useDialogsStore(state => state.showRelocateConstituents); + function handleRelocate() { editMenu.hide(); - promptRelocateConstituents(undefined, []); + showRelocateConstituents({ + oss: schema, + initialTarget: undefined, + positions: [] + }); } if (isAnonymous) { diff --git a/rsconcept/frontend/src/features/oss/pages/OssPage/OssEditContext.tsx b/rsconcept/frontend/src/features/oss/pages/OssPage/OssEditContext.tsx index 39b79a37..b76157d3 100644 --- a/rsconcept/frontend/src/features/oss/pages/OssPage/OssEditContext.tsx +++ b/rsconcept/frontend/src/features/oss/pages/OssPage/OssEditContext.tsx @@ -9,13 +9,12 @@ import { useDeleteItem } from '@/features/library/backend/useDeleteItem'; import { RSTabID } from '@/features/rsform/pages/RSFormPage/RSEditContext'; import { useRoleStore, UserRole } from '@/features/users'; -import { useDialogsStore } from '@/stores/dialogs'; import { usePreferencesStore } from '@/stores/preferences'; import { promptText } from '@/utils/labels'; import { type IOperationPosition, OperationType } from '../../backend/types'; import { useOssSuspense } from '../../backend/useOSS'; -import { type IOperationSchema } from '../../models/oss'; +import { type IOperation, type IOperationSchema } from '../../models/oss'; export enum OssTabID { CARD = 0, @@ -40,15 +39,9 @@ export interface IOssEditContext { navigateTab: (tab: OssTabID) => void; navigateOperationSchema: (target: number) => void; + canDeleteOperation: (target: IOperation) => boolean; deleteSchema: () => void; setSelected: React.Dispatch>; - - canDelete: (target: number) => boolean; - promptCreateOperation: (props: ICreateOperationPrompt) => void; - promptDeleteOperation: (target: number, positions: IOperationPosition[]) => void; - promptEditInput: (target: number, positions: IOperationPosition[]) => void; - promptEditOperation: (target: number, positions: IOperationPosition[]) => void; - promptRelocateConstituents: (target: number | undefined, positions: IOperationPosition[]) => void; } const OssEditContext = createContext(null); @@ -81,12 +74,6 @@ export const OssEditState = ({ itemID, children }: React.PropsWithChildren([]); - const showEditInput = useDialogsStore(state => state.showChangeInputSchema); - const showEditOperation = useDialogsStore(state => state.showEditOperation); - const showDeleteOperation = useDialogsStore(state => state.showDeleteOperation); - const showRelocateConstituents = useDialogsStore(state => state.showRelocateConstituents); - const showCreateOperation = useDialogsStore(state => state.showCreateOperation); - const { deleteItem } = useDeleteItem(); useEffect( @@ -128,71 +115,11 @@ export const OssEditState = ({ itemID, children }: React.PropsWithChildren {children}