From cac508451d8ee9e70ad393f8d9daf658324cff51 Mon Sep 17 00:00:00 2001 From: Ivan <8611739+IRBorisov@users.noreply.github.com> Date: Tue, 8 Jul 2025 11:22:43 +0300 Subject: [PATCH] M: Improve UI for creating new elements --- rsconcept/frontend/src/components/icons.tsx | 1 + .../context-menu/menu-operation.tsx | 4 +- .../oss-page/editor-oss-graph/oss-flow.tsx | 18 +-- .../editor-oss-graph/toolbar-oss-graph.tsx | 112 +++++++++++++----- rsconcept/frontend/src/utils/utils.ts | 19 +++ 5 files changed, 116 insertions(+), 38 deletions(-) diff --git a/rsconcept/frontend/src/components/icons.tsx b/rsconcept/frontend/src/components/icons.tsx index dfd1aaaa..4e8bd635 100644 --- a/rsconcept/frontend/src/components/icons.tsx +++ b/rsconcept/frontend/src/components/icons.tsx @@ -1,5 +1,6 @@ // Search new icons at https://reactsvgicons.com/ // Note: save this file using Ctrl + K, Ctrl + Shift + S to disable autoformat +// Note: For Cursor hotkeys are Ctrl + M, Ctrl + Shift + S /* eslint-disable simple-import-sort/exports */ // ==== General actions ======= diff --git a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/context-menu/menu-operation.tsx b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/context-menu/menu-operation.tsx index 5e5be8c1..ae3ede5b 100644 --- a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/context-menu/menu-operation.tsx +++ b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/context-menu/menu-operation.tsx @@ -1,7 +1,6 @@ 'use client'; import { toast } from 'react-toastify'; -import { urls, useConceptNavigation } from '@/app'; import { useLibrary } from '@/features/library/backend/use-library'; import { DropdownButton } from '@/components/dropdown'; @@ -33,7 +32,6 @@ interface MenuOperationProps { } export function MenuOperation({ operation, onHide }: MenuOperationProps) { - const router = useConceptNavigation(); const { items: libraryItems } = useLibrary(); const { schema, navigateOperationSchema, isMutable, canDeleteOperation } = useOssEdit(); const isProcessing = useMutatingOss(); @@ -134,7 +132,7 @@ export function MenuOperation({ operation, onHide }: MenuOperationProps) { void inputCreate({ itemID: schema.id, data: { target: operation.id, layout: getLayout() } - }).then(new_schema => router.push({ path: urls.schema(new_schema.id), force: true })); + }); } function handleRelocateConstituents() { diff --git a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/oss-flow.tsx b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/oss-flow.tsx index c9232482..41046bcb 100644 --- a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/oss-flow.tsx +++ b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/oss-flow.tsx @@ -163,14 +163,16 @@ export function OssFlow() { handleSavePositions(); return; } - if ((event.ctrlKey || event.metaKey) && event.code === 'KeyQ') { + if (event.altKey && event.code === 'Key1') { event.preventDefault(); event.stopPropagation(); - if (event.shiftKey) { - handleCreateBlock(); - } else { - handleCreateOperation(); - } + handleCreateBlock(); + return; + } + if (event.altKey && event.code === 'Key2') { + event.preventDefault(); + event.stopPropagation(); + handleCreateOperation(); return; } if (event.key === 'Delete') { @@ -200,8 +202,10 @@ export function OssFlow() { void; onCreateBlock: () => void; + onCreateSchema: () => void; + onImportSchema: () => void; + onCreateSynthesis: () => void; onDelete: () => void; onResetPositions: () => void; @@ -44,8 +51,10 @@ interface ToolbarOssGraphProps extends Styling { } export function ToolbarOssGraph({ - onCreateOperation, onCreateBlock, + onCreateSchema, + onImportSchema, + onCreateSynthesis, onDelete, onResetPositions, @@ -58,18 +67,25 @@ export function ToolbarOssGraph({ const { schema, selectedItems, isMutable, canDeleteOperation: canDelete } = useOssEdit(); const isProcessing = useMutatingOss(); const { resetView, nodes } = useOssFlow(); - const selectedOperation = - selectedItems.length === 1 && selectedItems[0].nodeType === NodeType.OPERATION ? selectedItems[0] : null; - const selectedBlock = - selectedItems.length === 1 && selectedItems[0].nodeType === NodeType.BLOCK ? selectedItems[0] : null; const getLayout = useGetLayout(); - const { updateLayout } = useUpdateLayout(); + const { user } = useAuthSuspense(); + const menu = useDropdown(); const showOptions = useDialogsStore(state => state.showOssOptions); const showSidePanel = usePreferencesStore(state => state.showOssSidePanel); const toggleShowSidePanel = usePreferencesStore(state => state.toggleShowOssSidePanel); + const selectedOperation = + selectedItems.length === 1 && selectedItems[0].nodeType === NodeType.OPERATION ? selectedItems[0] : null; + const selectedBlock = + selectedItems.length === 1 && selectedItems[0].nodeType === NodeType.BLOCK ? selectedItems[0] : null; + + function handleMenuToggle() { + hideContextMenu(); + menu.toggle(); + } + function handleShowOptions() { showOptions(); } @@ -127,40 +143,80 @@ export function ToolbarOssGraph({ {isMutable ? ( -
+
} onClick={handleSavePositions} disabled={isProcessing} /> } onClick={handleEditItem} disabled={selectedItems.length !== 1 || isProcessing} /> +
+ } + onClick={handleMenuToggle} + disabled={isProcessing} + /> + + } + onClick={onCreateBlock} + /> + } + onClick={onCreateSchema} + /> + } + onClick={onImportSchema} + /> + } + onClick={onCreateSynthesis} + /> + {user.is_staff ? ( + } + onClick={notImplemented} + /> + ) : null} + {user.is_staff ? ( + } + onClick={notImplemented} + /> + ) : null} + +
} - onClick={onCreateOperation} - disabled={isProcessing} - /> - } - onClick={onCreateBlock} - disabled={isProcessing} - /> - - } onClick={onDelete} disabled={ diff --git a/rsconcept/frontend/src/utils/utils.ts b/rsconcept/frontend/src/utils/utils.ts index fe11fe15..faa72b04 100644 --- a/rsconcept/frontend/src/utils/utils.ts +++ b/rsconcept/frontend/src/utils/utils.ts @@ -176,6 +176,25 @@ export function sharePage() { .catch(console.error); } +/** + * Show error message about not implemented function. + */ +export function notImplemented() { + toast.error('Данная функция еще не реализована'); + console.error('Not implemented'); +} + +/** + * Wrap event handler to prevent default and stop propagation. + */ +export function withPreventDefault(handler: (event: T) => void) { + return (event: T) => { + event.preventDefault(); + event.stopPropagation(); + handler(event); + }; +} + /** * Remove html tags from target string. */