From 96b5d2b3a9c7b2a5ced4e23fc14868686d5acc5e Mon Sep 17 00:00:00 2001 From: balibabu Date: Thu, 7 Nov 2024 17:53:31 +0800 Subject: [PATCH] fix: The name of the copy operator is displayed the same as before ##3265 (#3266) ### What problem does this PR solve? fix: The name of the copy operator is displayed the same as before ##3265 ### Type of change - [x] New Feature (non-breaking change which adds functionality) --- web/src/pages/flow/canvas/node/dropdown.tsx | 9 ++- .../pages/flow/canvas/node/node-header.tsx | 8 +-- web/src/pages/flow/canvas/node/note-node.tsx | 2 +- web/src/pages/flow/hooks.ts | 59 ++++--------------- web/src/pages/flow/store.ts | 21 +++++-- web/src/pages/flow/utils.ts | 53 ++++++++++++++++- 6 files changed, 88 insertions(+), 64 deletions(-) diff --git a/web/src/pages/flow/canvas/node/dropdown.tsx b/web/src/pages/flow/canvas/node/dropdown.tsx index aefa81475..ea8fcc1fd 100644 --- a/web/src/pages/flow/canvas/node/dropdown.tsx +++ b/web/src/pages/flow/canvas/node/dropdown.tsx @@ -3,25 +3,28 @@ import { CopyOutlined } from '@ant-design/icons'; import { Flex, MenuProps } from 'antd'; import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; +import { useGetNodeName } from '../../hooks'; import useGraphStore from '../../store'; interface IProps { id: string; iconFontColor?: string; + label: string; } -const NodeDropdown = ({ id, iconFontColor }: IProps) => { +const NodeDropdown = ({ id, iconFontColor, label }: IProps) => { const { t } = useTranslation(); const deleteNodeById = useGraphStore((store) => store.deleteNodeById); const duplicateNodeById = useGraphStore((store) => store.duplicateNode); + const getNodeName = useGetNodeName(); const deleteNode = useCallback(() => { deleteNodeById(id); }, [id, deleteNodeById]); const duplicateNode = useCallback(() => { - duplicateNodeById(id); - }, [id, duplicateNodeById]); + duplicateNodeById(id, getNodeName(label)); + }, [duplicateNodeById, id, getNodeName, label]); const items: MenuProps['items'] = [ { diff --git a/web/src/pages/flow/canvas/node/node-header.tsx b/web/src/pages/flow/canvas/node/node-header.tsx index 89c1b332a..dafddf137 100644 --- a/web/src/pages/flow/canvas/node/node-header.tsx +++ b/web/src/pages/flow/canvas/node/node-header.tsx @@ -9,13 +9,13 @@ import { NextNodePopover } from './popover'; interface IProps { id: string; - label?: string; - name?: string; + label: string; + name: string; gap?: number; className?: string; } -export function RunStatus({ id, name }: IProps) { +export function RunStatus({ id, name }: Omit) { const { t } = useTranslate('flow'); return (
@@ -44,7 +44,7 @@ const NodeHeader = ({ label, id, name, gap = 4, className }: IProps) => { color={operatorMap[label as Operator].color} > {name} - +
); diff --git a/web/src/pages/flow/canvas/node/note-node.tsx b/web/src/pages/flow/canvas/node/note-node.tsx index 5028baa1d..3ef9cbbb2 100644 --- a/web/src/pages/flow/canvas/node/note-node.tsx +++ b/web/src/pages/flow/canvas/node/note-node.tsx @@ -62,7 +62,7 @@ function NoteNode({ data, id }: NodeProps) { onChange={handleNameChange} className={styles.noteName} > - +
{ return { handleDragStart }; }; -const splitName = (name: string) => { - const names = name.split('_'); - const type = names.at(0); - const index = Number(names.at(-1)); +export const useGetNodeName = () => { + const { t } = useTranslation(); - return { type, index }; + return (type: string) => { + const name = t(`flow.${lowerFirst(type)}`); + return name; + }; }; export const useHandleDrop = () => { @@ -173,54 +175,13 @@ export const useHandleDrop = () => { const [reactFlowInstance, setReactFlowInstance] = useState>(); const initializeOperatorParams = useInitializeOperatorParams(); - const { t } = useTranslation(); + const getNodeName = useGetNodeName(); const onDragOver = useCallback((event: React.DragEvent) => { event.preventDefault(); event.dataTransfer.dropEffect = 'move'; }, []); - const generateNodeName = useCallback( - (type: string) => { - const name = t(`flow.${lowerFirst(type)}`); - const templateNameList = nodes - .filter((x) => { - const temporaryName = x.data.name; - - const { type, index } = splitName(temporaryName); - - return ( - temporaryName.match(/_/g)?.length === 1 && - type === name && - !isNaN(index) - ); - }) - .map((x) => { - const temporaryName = x.data.name; - const { index } = splitName(temporaryName); - - return { - idx: index, - name: temporaryName, - }; - }) - .sort((a, b) => a.idx - b.idx); - - let index: number = 0; - for (let i = 0; i < templateNameList.length; i++) { - const idx = templateNameList[i]?.idx; - const nextIdx = templateNameList[i + 1]?.idx; - if (idx + 1 !== nextIdx) { - index = idx + 1; - break; - } - } - - return `${name}_${index}`; - }, - [t, nodes], - ); - const onDrop = useCallback( (event: React.DragEvent) => { event.preventDefault(); @@ -248,7 +209,7 @@ export const useHandleDrop = () => { }, data: { label: `${type}`, - name: generateNodeName(type), + name: generateNodeNamesWithIncreasingIndex(getNodeName(type), nodes), form: initializeOperatorParams(type as Operator), }, sourcePosition: Position.Right, @@ -258,7 +219,7 @@ export const useHandleDrop = () => { addNode(newNode); }, - [reactFlowInstance, addNode, initializeOperatorParams, generateNodeName], + [reactFlowInstance, getNodeName, nodes, initializeOperatorParams, addNode], ); return { onDrop, onDragOver, setReactFlowInstance }; diff --git a/web/src/pages/flow/store.ts b/web/src/pages/flow/store.ts index 18edc9b0d..cd15a4089 100644 --- a/web/src/pages/flow/store.ts +++ b/web/src/pages/flow/store.ts @@ -23,7 +23,12 @@ import { devtools } from 'zustand/middleware'; import { immer } from 'zustand/middleware/immer'; import { Operator, SwitchElseTo } from './constant'; import { NodeData } from './interface'; -import { getNodeDragHandle, getOperatorIndex, isEdgeEqual } from './utils'; +import { + generateNodeNamesWithIncreasingIndex, + getNodeDragHandle, + getOperatorIndex, + isEdgeEqual, +} from './utils'; export type RFState = { nodes: Node[]; @@ -54,7 +59,7 @@ export type RFState = { target?: string | null, ) => void; deletePreviousEdgeOfClassificationNode: (connection: Connection) => void; - duplicateNode: (id: string) => void; + duplicateNode: (id: string, name: string) => void; deleteEdge: () => void; deleteEdgeById: (id: string) => void; deleteNodeById: (id: string) => void; @@ -63,6 +68,7 @@ export type RFState = { updateMutableNodeFormItem: (id: string, field: string, value: any) => void; getOperatorTypeFromId: (id?: string | null) => string | undefined; updateNodeName: (id: string, name: string) => void; + generateNodeName: (name: string) => string; setClickedNodeId: (id?: string) => void; }; @@ -226,8 +232,8 @@ const useGraphStore = create()( } } }, - duplicateNode: (id: string) => { - const { getNode, addNode } = get(); + duplicateNode: (id: string, name: string) => { + const { getNode, addNode, generateNodeName } = get(); const node = getNode(id); const position = { x: (node?.position?.x || 0) + 30, @@ -236,7 +242,7 @@ const useGraphStore = create()( addNode({ ...(node || {}), - data: node?.data, + data: { ...(node?.data ?? {}), name: generateNodeName(name) }, selected: false, dragging: false, id: `${node?.data?.label}:${humanId()}`, @@ -383,6 +389,11 @@ const useGraphStore = create()( setClickedNodeId: (id?: string) => { set({ clickedNodeId: id }); }, + generateNodeName: (name: string) => { + const { nodes } = get(); + + return generateNodeNamesWithIncreasingIndex(name, nodes); + }, })), { name: 'graph' }, ), diff --git a/web/src/pages/flow/utils.ts b/web/src/pages/flow/utils.ts index 2abafd194..e53a67b04 100644 --- a/web/src/pages/flow/utils.ts +++ b/web/src/pages/flow/utils.ts @@ -184,11 +184,12 @@ export const buildNewPositionMap = ( const intersectionKeys = intersectionWith( previousKeys, currentKeys, - (categoryDataKey, positionMapKey) => categoryDataKey === positionMapKey, + (categoryDataKey: string, positionMapKey: string) => + categoryDataKey === positionMapKey, ); // difference set const currentDifferenceKeys = currentKeys.filter( - (x) => !intersectionKeys.some((y) => y === x), + (x) => !intersectionKeys.some((y: string) => y === x), ); const newPositionMap = currentDifferenceKeys.reduce< Record @@ -240,3 +241,51 @@ export const generateSwitchHandleText = (idx: number) => { export const getNodeDragHandle = (nodeType?: string) => { return nodeType === Operator.Note ? '.note-drag-handle' : undefined; }; + +const splitName = (name: string) => { + const names = name.split('_'); + const type = names.at(0); + const index = Number(names.at(-1)); + + return { type, index }; +}; + +export const generateNodeNamesWithIncreasingIndex = ( + name: string, + nodes: Node[], +) => { + const templateNameList = nodes + .filter((x) => { + const temporaryName = x.data.name; + + const { type, index } = splitName(temporaryName); + + return ( + temporaryName.match(/_/g)?.length === 1 && + type === name && + !isNaN(index) + ); + }) + .map((x) => { + const temporaryName = x.data.name; + const { index } = splitName(temporaryName); + + return { + idx: index, + name: temporaryName, + }; + }) + .sort((a, b) => a.idx - b.idx); + + let index: number = 0; + for (let i = 0; i < templateNameList.length; i++) { + const idx = templateNameList[i]?.idx; + const nextIdx = templateNameList[i + 1]?.idx; + if (idx + 1 !== nextIdx) { + index = idx + 1; + break; + } + } + + return `${name}_${index}`; +};