diff --git a/rsconcept/frontend/src/features/help/items/ui/help-oss-graph.tsx b/rsconcept/frontend/src/features/help/items/ui/help-oss-graph.tsx index a9dba114..bb916b6d 100644 --- a/rsconcept/frontend/src/features/help/items/ui/help-oss-graph.tsx +++ b/rsconcept/frontend/src/features/help/items/ui/help-oss-graph.tsx @@ -107,7 +107,7 @@ export function HelpOssGraph() { Space – перемещение экрана
  • - Shift – перемещение выделенных элементов в границах родителя + Shift – перемещение в границах блока
  • diff --git a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/graph/node-core.tsx b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/graph/node-core.tsx index de087696..6be90695 100644 --- a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/graph/node-core.tsx +++ b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/graph/node-core.tsx @@ -31,10 +31,6 @@ export function NodeCore({ node }: NodeCoreProps) { const hasFile = !!node.data.operation.result; const longLabel = node.data.label.length > LONG_LABEL_CHARS; - function handleTouchStart(event: React.TouchEvent) { - console.log('handleTouchStart', event); - } - return (
    (null); - const longPressTarget = useRef(null); - function handleSavePositions() { void updateLayout({ itemID: schema.id, data: getLayout() }); } @@ -193,62 +189,23 @@ export function OssFlow() { openContextMenu(node, event.clientX, event.clientY); } - function handleTouchStart(event: React.TouchEvent) { - if (!isIOS() || event.touches.length !== 1) { - return; - } - - // Long-press support for iOS/iPadOS - const touch = event.touches[0]; - longPressTarget.current = touch.target; - longPressTimeout.current = setTimeout(() => { - let targetID = null; - let element = touch.target as HTMLElement | null; - while (element) { - if (element?.getAttribute?.('data-id')) { - targetID = element.getAttribute('data-id'); - break; - } - element = element.parentElement; - } - if (targetID) { - const targetNode = nodes.find(node => node.id === targetID); - if (targetNode) { - openContextMenu(targetNode, touch.clientX, touch.clientY); - } - } - }, PARAMETER.ossContextMenuDuration); - } - - function handleTouchEnd() { - if (!isIOS()) return; - if (longPressTimeout.current) { - clearTimeout(longPressTimeout.current); - longPressTimeout.current = null; - } - } - - function handleTouchMove() { - if (!isIOS()) return; - if (longPressTimeout.current) { - clearTimeout(longPressTimeout.current); - longPressTimeout.current = null; - } - } - return (
    {showCoordinates ? : null} + + + - -
    ); diff --git a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/toolbar-oss-graph.tsx b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/toolbar-oss-graph.tsx index 8748213e..c74202e1 100644 --- a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/toolbar-oss-graph.tsx +++ b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/toolbar-oss-graph.tsx @@ -1,14 +1,16 @@ 'use client'; +import React from 'react'; + import { HelpTopic } from '@/features/help'; import { BadgeHelp } from '@/features/help/components'; +import { type OssNode } from '@/features/oss/models/oss-layout'; import { MiniButton } from '@/components/control'; import { IconConceptBlock, IconDestroy, IconEdit2, - IconExecute, IconFitImage, IconNewItem, IconReset, @@ -18,14 +20,11 @@ import { import { type Styling } from '@/components/props'; import { cn } from '@/components/utils'; import { useDialogsStore } from '@/stores/dialogs'; -import { prepareTooltip } from '@/utils/utils'; +import { isIOS, prepareTooltip } from '@/utils/utils'; -import { OperationType } from '../../../backend/types'; -import { useExecuteOperation } from '../../../backend/use-execute-operation'; import { useMutatingOss } from '../../../backend/use-mutating-oss'; import { useUpdateLayout } from '../../../backend/use-update-layout'; import { NodeType } from '../../../models/oss'; -import { LayoutManager } from '../../../models/oss-layout-api'; import { useOssEdit } from '../oss-edit-context'; import { useOssFlow } from './oss-flow-context'; @@ -36,6 +35,10 @@ interface ToolbarOssGraphProps extends Styling { onCreateBlock: () => void; onDelete: () => void; onResetPositions: () => void; + + isContextMenuOpen: boolean; + openContextMenu: (node: OssNode, clientX: number, clientY: number) => void; + hideContextMenu: () => void; } export function ToolbarOssGraph({ @@ -43,12 +46,16 @@ export function ToolbarOssGraph({ onCreateBlock, onDelete, onResetPositions, + + isContextMenuOpen, + openContextMenu, + hideContextMenu, className, ...restProps }: ToolbarOssGraphProps) { const { schema, selectedItems, isMutable, canDeleteOperation: canDelete } = useOssEdit(); const isProcessing = useMutatingOss(); - const { resetView } = useOssFlow(); + const { resetView, nodes } = useOssFlow(); const selectedOperation = selectedItems.length === 1 && selectedItems[0].nodeType === NodeType.OPERATION ? selectedItems[0] : null; const selectedBlock = @@ -56,33 +63,9 @@ export function ToolbarOssGraph({ const getLayout = useGetLayout(); const { updateLayout } = useUpdateLayout(); - const { executeOperation } = useExecuteOperation(); - const showEditOperation = useDialogsStore(state => state.showEditOperation); - const showEditBlock = useDialogsStore(state => state.showEditBlock); const showOssOptions = useDialogsStore(state => state.showOssOptions); - const readyForSynthesis = (() => { - if (!selectedOperation || selectedOperation.operation_type !== OperationType.SYNTHESIS) { - return false; - } - if (selectedOperation.result) { - return false; - } - - const argumentIDs = schema.graph.expandInputs([selectedOperation.id]); - if (!argumentIDs || argumentIDs.length < 1) { - return false; - } - - const argumentOperations = argumentIDs.map(id => schema.operationByID.get(id)!); - if (argumentOperations.some(item => item.result === null)) { - return false; - } - - return true; - })(); - function handleShowOptions() { showOssOptions(); } @@ -91,27 +74,18 @@ export function ToolbarOssGraph({ void updateLayout({ itemID: schema.id, data: getLayout() }); } - function handleOperationExecute() { - if (!readyForSynthesis || !selectedOperation) { + function handleEditItem(event: React.MouseEvent) { + if (isContextMenuOpen) { + hideContextMenu(); return; } - void executeOperation({ - itemID: schema.id, // - data: { target: selectedOperation.id, layout: getLayout() } - }); - } - - function handleEditItem() { - if (selectedOperation) { - showEditOperation({ - manager: new LayoutManager(schema, getLayout()), - target: selectedOperation - }); - } else if (selectedBlock) { - showEditBlock({ - manager: new LayoutManager(schema, getLayout()), - target: selectedBlock - }); + const nodeID = selectedOperation?.nodeID ?? selectedBlock?.nodeID; + if (!nodeID) { + return; + } + const node = nodes.find(node => node.id === nodeID); + if (node) { + openContextMenu(node, event.clientX, event.clientY); } } @@ -153,11 +127,12 @@ export function ToolbarOssGraph({ disabled={isProcessing} /> } - onClick={onCreateBlock} - disabled={isProcessing} + titleHtml={prepareTooltip('Редактировать выбранную', isIOS() ? '' : 'Правый клик')} + hideTitle={isContextMenuOpen} + aria-label='Редактировать выбранную' + icon={} + onClick={handleEditItem} + disabled={selectedItems.length !== 1 || isProcessing} /> } - onClick={handleOperationExecute} - disabled={isProcessing || selectedItems.length !== 1 || !readyForSynthesis} - /> - } - onClick={handleEditItem} - disabled={selectedItems.length !== 1 || isProcessing} + titleHtml={prepareTooltip('Новый блок', 'Ctrl + Shift + Q')} + aria-label='Новый блок' + icon={} + onClick={onCreateBlock} + disabled={isProcessing} /> + state.showRelocateConstituents); - - function handleRelocate() { - menu.hide(); - showRelocateConstituents({ - oss: schema, - initialTarget: undefined - }); - } - - if (isAnonymous) { - return null; - } - - return ( -
    - } - onClick={menu.toggle} - /> - - } - disabled={isProcessing || !isMutable} - onClick={handleRelocate} - /> - -
    - ); -} diff --git a/rsconcept/frontend/src/features/oss/pages/oss-page/menu-main.tsx b/rsconcept/frontend/src/features/oss/pages/oss-page/menu-main.tsx index af206779..0748e607 100644 --- a/rsconcept/frontend/src/features/oss/pages/oss-page/menu-main.tsx +++ b/rsconcept/frontend/src/features/oss/pages/oss-page/menu-main.tsx @@ -53,7 +53,7 @@ export function MenuMain() { title='Меню' hideTitle={menu.isOpen} icon={} - className='h-full pl-2 text-muted-foreground hover:text-primary cc-animate-color' + className='h-full px-2 text-muted-foreground hover:text-primary cc-animate-color' onClick={menu.toggle} /> diff --git a/rsconcept/frontend/src/features/oss/pages/oss-page/menu-oss-tabs.tsx b/rsconcept/frontend/src/features/oss/pages/oss-page/menu-oss-tabs.tsx index d207dc12..e5ad4899 100644 --- a/rsconcept/frontend/src/features/oss/pages/oss-page/menu-oss-tabs.tsx +++ b/rsconcept/frontend/src/features/oss/pages/oss-page/menu-oss-tabs.tsx @@ -3,7 +3,6 @@ import { useAuthSuspense } from '@/features/auth'; import { MenuRole } from '@/features/library/components'; -import { MenuEditOss } from './menu-edit-oss'; import { MenuMain } from './menu-main'; import { useOssEdit } from './oss-edit-context'; @@ -14,8 +13,6 @@ export function MenuOssTabs() {
    - -
    ); diff --git a/rsconcept/frontend/src/utils/constants.ts b/rsconcept/frontend/src/utils/constants.ts index 09871961..16b543d0 100644 --- a/rsconcept/frontend/src/utils/constants.ts +++ b/rsconcept/frontend/src/utils/constants.ts @@ -11,7 +11,6 @@ export const PARAMETER = { notificationDelay: 300, // milliseconds delay for notifications zoomDuration: 500, // milliseconds animation duration navigationPopupDelay: 300, // milliseconds delay for navigation popup - ossContextMenuDuration: 500, // milliseconds - duration of long-press to trigger context menu on iOS/iPadOS moveDuration: 500, // milliseconds - duration of move animation