From e71a5baf608b3c139a4356bd06d2b9e7ace6f739 Mon Sep 17 00:00:00 2001 From: Ivan <8611739+IRBorisov@users.noreply.github.com> Date: Tue, 22 Apr 2025 00:41:13 +0300 Subject: [PATCH] F: Implementing block UI pt2 --- .../frontend/src/app/application-layout.tsx | 2 +- .../{global-loader1.tsx => global-loader.tsx} | 0 .../src/features/oss/models/oss-api.ts | 28 +++++----- .../editor-oss-graph/graph/block-node.tsx | 13 ++++- .../editor-oss-graph/graph/input-node.tsx | 2 +- .../editor-oss-graph/graph/node-core.tsx | 17 +++++- .../editor-oss-graph/graph/operation-node.tsx | 6 +- .../editor-oss-graph/graph/styles.css | 56 ++++++++++++------- .../oss-page/editor-oss-graph/oss-flow.tsx | 4 ++ .../dialogs/dlg-show-ast/graph/styles.css | 4 ++ .../dlg-show-type-graph/graph/styles.css | 5 ++ .../editor-term-graph/graph/styles.css | 4 ++ rsconcept/frontend/src/styling/reactflow.css | 8 +-- 13 files changed, 97 insertions(+), 52 deletions(-) rename rsconcept/frontend/src/app/{global-loader1.tsx => global-loader.tsx} (100%) diff --git a/rsconcept/frontend/src/app/application-layout.tsx b/rsconcept/frontend/src/app/application-layout.tsx index 9bee20b8..bfe53fd1 100644 --- a/rsconcept/frontend/src/app/application-layout.tsx +++ b/rsconcept/frontend/src/app/application-layout.tsx @@ -9,7 +9,7 @@ import { useDialogsStore } from '@/stores/dialogs'; import { NavigationState } from './navigation/navigation-context'; import { Footer } from './footer'; import { GlobalDialogs } from './global-dialogs'; -import { GlobalLoader } from './global-loader1'; +import { GlobalLoader } from './global-loader'; import { ToasterThemed } from './global-toaster'; import { GlobalTooltips } from './global-tooltips'; import { MutationErrors } from './mutation-errors'; diff --git a/rsconcept/frontend/src/app/global-loader1.tsx b/rsconcept/frontend/src/app/global-loader.tsx similarity index 100% rename from rsconcept/frontend/src/app/global-loader1.tsx rename to rsconcept/frontend/src/app/global-loader.tsx diff --git a/rsconcept/frontend/src/features/oss/models/oss-api.ts b/rsconcept/frontend/src/features/oss/models/oss-api.ts index faf71870..af8364e0 100644 --- a/rsconcept/frontend/src/features/oss/models/oss-api.ts +++ b/rsconcept/frontend/src/features/oss/models/oss-api.ts @@ -543,26 +543,26 @@ export function calculateNewBlockPosition(data: ICreateBlockDTO, layout: IOssLay let right = undefined; let bottom = undefined; - for (const node of block_nodes) { - left = !left ? node.x - GRID_SIZE : Math.min(left, node.x - GRID_SIZE); - top = !top ? node.y - GRID_SIZE : Math.min(top, node.y - GRID_SIZE); + for (const block of block_nodes) { + left = !left ? block.x - GRID_SIZE : Math.min(left, block.x - GRID_SIZE); + top = !top ? block.y - GRID_SIZE : Math.min(top, block.y - GRID_SIZE); right = !right - ? Math.max(left + data.width, node.x + node.width + GRID_SIZE) - : Math.max(right, node.x + node.width + GRID_SIZE); + ? Math.max(left + data.width, block.x + block.width + GRID_SIZE) + : Math.max(right, block.x + block.width + GRID_SIZE); bottom = !bottom - ? Math.max(top + data.height, node.y + node.height + GRID_SIZE) - : Math.max(bottom, node.y + node.height + GRID_SIZE); + ? Math.max(top + data.height, block.y + block.height + GRID_SIZE) + : Math.max(bottom, block.y + block.height + GRID_SIZE); } - for (const node of operation_nodes) { - left = !left ? node.x - GRID_SIZE : Math.min(left, node.x - GRID_SIZE); - top = !top ? node.y - GRID_SIZE : Math.min(top, node.y - GRID_SIZE); + for (const operation of operation_nodes) { + left = !left ? operation.x - GRID_SIZE : Math.min(left, operation.x - GRID_SIZE); + top = !top ? operation.y - GRID_SIZE : Math.min(top, operation.y - GRID_SIZE); right = !right - ? Math.max(left + data.width, node.x + OPERATION_NODE_WIDTH + GRID_SIZE) - : Math.max(right, node.x + OPERATION_NODE_WIDTH + GRID_SIZE); + ? Math.max(left + data.width, operation.x + OPERATION_NODE_WIDTH + GRID_SIZE) + : Math.max(right, operation.x + OPERATION_NODE_WIDTH + GRID_SIZE); bottom = !bottom - ? Math.max(top + data.height, node.y + OPERATION_NODE_HEIGHT + GRID_SIZE) - : Math.max(bottom, node.y + OPERATION_NODE_HEIGHT + GRID_SIZE); + ? Math.max(top + data.height, operation.y + OPERATION_NODE_HEIGHT + GRID_SIZE) + : Math.max(bottom, operation.y + OPERATION_NODE_HEIGHT + GRID_SIZE); } return { diff --git a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/graph/block-node.tsx b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/graph/block-node.tsx index 0735a03f..b1a2b6c3 100644 --- a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/graph/block-node.tsx +++ b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/graph/block-node.tsx @@ -16,8 +16,9 @@ export const BLOCK_NODE_MIN_HEIGHT = 100; export function BlockNode(node: BlockInternalNode) { const showCoordinates = useOSSGraphStore(state => state.showCoordinates); const { selected, schema } = useOssEdit(); - const singleSelected = selected.length === 1 ? selected[0] : null; - const isParent = !singleSelected ? false : schema.hierarchy.at(singleSelected)?.inputs.includes(node.data.block.id); + const focus = selected.length === 1 ? selected[0] : null; + const isParent = (!!focus && schema.hierarchy.at(focus)?.inputs.includes(-node.data.block.id)) ?? false; + const isChild = (!!focus && schema.hierarchy.at(focus)?.outputs.includes(-node.data.block.id)) ?? false; return ( <> @@ -34,7 +35,13 @@ export function BlockNode(node: BlockInternalNode) { {`X: ${node.xPos.toFixed(0)} Y: ${node.yPos.toFixed(0)}`} ) : null} -
+
- + ); } 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 68d4d1ca..47ff412e 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 @@ -5,12 +5,14 @@ import clsx from 'clsx'; import { useOSSGraphStore } from '@/features/oss/stores/oss-graph'; import { IconConsolidation, IconRSForm } from '@/components/icons'; +import { cn } from '@/components/utils'; import { Indicator } from '@/components/view'; import { globalIDs } from '@/utils/constants'; import { OperationType } from '../../../../backend/types'; import { type OperationInternalNode } from '../../../../models/oss-layout'; import { useOperationTooltipStore } from '../../../../stores/operation-tooltip'; +import { useOssEdit } from '../../oss-edit-context'; export const OPERATION_NODE_WIDTH = 150; export const OPERATION_NODE_HEIGHT = 40; @@ -23,6 +25,10 @@ interface NodeCoreProps { } export function NodeCore({ node }: NodeCoreProps) { + const { selected, schema } = useOssEdit(); + const focus = selected.length === 1 ? selected[0] : null; + const isChild = (!!focus && schema.hierarchy.at(focus)?.outputs.includes(node.data.operation.id)) ?? false; + const setHover = useOperationTooltipStore(state => state.setActiveOperation); const showCoordinates = useOSSGraphStore(state => state.showCoordinates); @@ -31,7 +37,11 @@ export function NodeCore({ node }: NodeCoreProps) { return (
setHover(node.data.operation)} @@ -55,7 +65,8 @@ export function NodeCore({ node }: NodeCoreProps) { className={clsx( 'absolute top-full mt-1 right-[1px]', 'text-[7px]/[8px] font-math', - 'text-muted-foreground hover:text-foreground' + 'text-muted-foreground hover:text-foreground', + node.selected && 'translate-y-[6px]' )} > {`X: ${node.xPos.toFixed(0)} Y: ${node.yPos.toFixed(0)}`} @@ -63,7 +74,7 @@ export function NodeCore({ node }: NodeCoreProps) { ) : null} {node.data.operation.operation_type === OperationType.INPUT ? ( -
+
) : null} {!node.data.operation.is_owned ? ( diff --git a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/graph/operation-node.tsx b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/graph/operation-node.tsx index 54264fb4..ec7de71e 100644 --- a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/graph/operation-node.tsx +++ b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/graph/operation-node.tsx @@ -9,10 +9,10 @@ import { NodeCore } from './node-core'; export function OperationNode(node: OperationInternalNode) { return ( <> - - + + - + ); } diff --git a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/graph/styles.css b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/graph/styles.css index 6e287510..2032d919 100644 --- a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/graph/styles.css +++ b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/graph/styles.css @@ -4,16 +4,17 @@ .react-flow__resize-control.handle { background-color: transparent; + border-color: transparent; z-index: var(--z-index-navigation); color: var(--color-muted-foreground); + width: 0; + height: 0; + &:hover { color: var(--color-foreground); } - - width: 0; - height: 0; } .react-flow__node-input, @@ -21,28 +22,15 @@ cursor: pointer; border-radius: 5px; - padding: 2px; - width: 150px; - height: fit-content; + border-width: 0; - outline-offset: -2px; - outline-style: solid; - outline-color: transparent; + padding: 0; + margin: 0; - transition-property: outline-offset; - transition-timing-function: var(--transition-bezier); - transition-duration: var(--duration-select); - - &.selected { - outline-offset: 4px; - outline-color: var(--color-graph-selected); - border-color: var(--color-foreground); - } + background-color: transparent; } .react-flow__node-block { - cursor: auto; - border-radius: 5px; border-width: 0; @@ -53,7 +41,34 @@ pointer-events: none; } +.cc-node-operation { + cursor: pointer; + + border-radius: 5px; + border-color: var(--color-muted-foreground); + border-width: 1px; + + color: var(--color-foreground); + background-color: var(--color-card); + + outline-offset: -2px; + outline-style: solid; + outline-color: transparent; + + transition-property: outline-offset; + transition-timing-function: var(--transition-bezier); + transition-duration: var(--duration-select); + + .selected & { + outline-offset: 4px; + outline-color: var(--color-graph-selected); + border-color: var(--color-foreground); + } +} + .cc-node-block { + cursor: default; + border-radius: 5px; border-style: dashed; border-width: 2px; @@ -61,6 +76,7 @@ padding: 4px; color: var(--color-muted-foreground); + background-color: transparent; .selected & { color: var(--color-foreground); 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 e5c8028f..066adfd1 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 @@ -200,6 +200,10 @@ export function OssFlow() { event.preventDefault(); event.stopPropagation(); + if (node.type === 'block') { + return; + } + setMenuProps({ operation: node.data.operation, cursorX: event.clientX, diff --git a/rsconcept/frontend/src/features/rsform/dialogs/dlg-show-ast/graph/styles.css b/rsconcept/frontend/src/features/rsform/dialogs/dlg-show-ast/graph/styles.css index 4235ca97..3e13cd3b 100644 --- a/rsconcept/frontend/src/features/rsform/dialogs/dlg-show-ast/graph/styles.css +++ b/rsconcept/frontend/src/features/rsform/dialogs/dlg-show-ast/graph/styles.css @@ -3,9 +3,13 @@ /* stylelint-disable selector-class-pattern */ .react-flow__node-token { + font-size: 14px; cursor: default; + border: 1px solid; + border-color: var(--color-border); border-radius: 100%; + width: 40px; height: 40px; diff --git a/rsconcept/frontend/src/features/rsform/dialogs/dlg-show-type-graph/graph/styles.css b/rsconcept/frontend/src/features/rsform/dialogs/dlg-show-type-graph/graph/styles.css index 4944e0d9..56dad892 100644 --- a/rsconcept/frontend/src/features/rsform/dialogs/dlg-show-type-graph/graph/styles.css +++ b/rsconcept/frontend/src/features/rsform/dialogs/dlg-show-type-graph/graph/styles.css @@ -3,9 +3,14 @@ /* stylelint-disable selector-class-pattern */ .react-flow__node-step { + font-size: 14px; cursor: default; + color: var(--color-foreground); + border: 1px solid; + border-color: var(--color-border); border-radius: 100%; + width: 40px; height: 40px; diff --git a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-term-graph/graph/styles.css b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-term-graph/graph/styles.css index 98473237..87dd7ddc 100644 --- a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-term-graph/graph/styles.css +++ b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-term-graph/graph/styles.css @@ -4,8 +4,12 @@ .react-flow__node-concept { cursor: default; + font-size: 14px; + border: 1px solid; + border-color: var(--color-border); border-radius: 100%; + width: 40px; height: 40px; diff --git a/rsconcept/frontend/src/styling/reactflow.css b/rsconcept/frontend/src/styling/reactflow.css index a8d14771..0f9b4f46 100644 --- a/rsconcept/frontend/src/styling/reactflow.css +++ b/rsconcept/frontend/src/styling/reactflow.css @@ -6,6 +6,7 @@ /* stylelint-disable selector-class-pattern */ .react-flow__handle { + z-index: var(--z-index-navigation); cursor: default !important; border-radius: 9999px; @@ -36,13 +37,6 @@ } [class*='react-flow__node-'] { - font-size: 14px; - border: 1px solid; - - color: var(--color-foreground); - border-color: var(--color-border); - background-color: var(--color-card); - &:hover:not(.selected) { box-shadow: 0 0 0 2px var(--color-selected) !important; }