balibabu commited on
Commit
a83cbb2
·
1 Parent(s): 8d8af60

fix: The name of the copy operator is displayed the same as before ##3265 (#3266)

Browse files

### 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 CHANGED
@@ -3,25 +3,28 @@ import { CopyOutlined } from '@ant-design/icons';
3
  import { Flex, MenuProps } from 'antd';
4
  import { useCallback } from 'react';
5
  import { useTranslation } from 'react-i18next';
 
6
  import useGraphStore from '../../store';
7
 
8
  interface IProps {
9
  id: string;
10
  iconFontColor?: string;
 
11
  }
12
 
13
- const NodeDropdown = ({ id, iconFontColor }: IProps) => {
14
  const { t } = useTranslation();
15
  const deleteNodeById = useGraphStore((store) => store.deleteNodeById);
16
  const duplicateNodeById = useGraphStore((store) => store.duplicateNode);
 
17
 
18
  const deleteNode = useCallback(() => {
19
  deleteNodeById(id);
20
  }, [id, deleteNodeById]);
21
 
22
  const duplicateNode = useCallback(() => {
23
- duplicateNodeById(id);
24
- }, [id, duplicateNodeById]);
25
 
26
  const items: MenuProps['items'] = [
27
  {
 
3
  import { Flex, MenuProps } from 'antd';
4
  import { useCallback } from 'react';
5
  import { useTranslation } from 'react-i18next';
6
+ import { useGetNodeName } from '../../hooks';
7
  import useGraphStore from '../../store';
8
 
9
  interface IProps {
10
  id: string;
11
  iconFontColor?: string;
12
+ label: string;
13
  }
14
 
15
+ const NodeDropdown = ({ id, iconFontColor, label }: IProps) => {
16
  const { t } = useTranslation();
17
  const deleteNodeById = useGraphStore((store) => store.deleteNodeById);
18
  const duplicateNodeById = useGraphStore((store) => store.duplicateNode);
19
+ const getNodeName = useGetNodeName();
20
 
21
  const deleteNode = useCallback(() => {
22
  deleteNodeById(id);
23
  }, [id, deleteNodeById]);
24
 
25
  const duplicateNode = useCallback(() => {
26
+ duplicateNodeById(id, getNodeName(label));
27
+ }, [duplicateNodeById, id, getNodeName, label]);
28
 
29
  const items: MenuProps['items'] = [
30
  {
web/src/pages/flow/canvas/node/node-header.tsx CHANGED
@@ -9,13 +9,13 @@ import { NextNodePopover } from './popover';
9
 
10
  interface IProps {
11
  id: string;
12
- label?: string;
13
- name?: string;
14
  gap?: number;
15
  className?: string;
16
  }
17
 
18
- export function RunStatus({ id, name }: IProps) {
19
  const { t } = useTranslate('flow');
20
  return (
21
  <section className="flex justify-end items-center pb-1 ">
@@ -44,7 +44,7 @@ const NodeHeader = ({ label, id, name, gap = 4, className }: IProps) => {
44
  color={operatorMap[label as Operator].color}
45
  ></OperatorIcon>
46
  <span className={styles.nodeTitle}>{name}</span>
47
- <NodeDropdown id={id}></NodeDropdown>
48
  </Flex>
49
  </section>
50
  );
 
9
 
10
  interface IProps {
11
  id: string;
12
+ label: string;
13
+ name: string;
14
  gap?: number;
15
  className?: string;
16
  }
17
 
18
+ export function RunStatus({ id, name }: Omit<IProps, 'label'>) {
19
  const { t } = useTranslate('flow');
20
  return (
21
  <section className="flex justify-end items-center pb-1 ">
 
44
  color={operatorMap[label as Operator].color}
45
  ></OperatorIcon>
46
  <span className={styles.nodeTitle}>{name}</span>
47
+ <NodeDropdown id={id} label={label}></NodeDropdown>
48
  </Flex>
49
  </section>
50
  );
web/src/pages/flow/canvas/node/note-node.tsx CHANGED
@@ -62,7 +62,7 @@ function NoteNode({ data, id }: NodeProps<NodeData>) {
62
  onChange={handleNameChange}
63
  className={styles.noteName}
64
  ></Input>
65
- <NodeDropdown id={id}></NodeDropdown>
66
  </Flex>
67
  <Form
68
  onValuesChange={handleValuesChange}
 
62
  onChange={handleNameChange}
63
  className={styles.noteName}
64
  ></Input>
65
+ <NodeDropdown id={id} label={data.label}></NodeDropdown>
66
  </Flex>
67
  <Form
68
  onValuesChange={handleValuesChange}
web/src/pages/flow/hooks.ts CHANGED
@@ -69,6 +69,7 @@ import { ICategorizeForm, IRelevantForm, ISwitchForm } from './interface';
69
  import useGraphStore, { RFState } from './store';
70
  import {
71
  buildDslComponentsByGraph,
 
72
  generateSwitchHandleText,
73
  getNodeDragHandle,
74
  receiveMessageError,
@@ -159,12 +160,13 @@ export const useHandleDrag = () => {
159
  return { handleDragStart };
160
  };
161
 
162
- const splitName = (name: string) => {
163
- const names = name.split('_');
164
- const type = names.at(0);
165
- const index = Number(names.at(-1));
166
 
167
- return { type, index };
 
 
 
168
  };
169
 
170
  export const useHandleDrop = () => {
@@ -173,54 +175,13 @@ export const useHandleDrop = () => {
173
  const [reactFlowInstance, setReactFlowInstance] =
174
  useState<ReactFlowInstance<any, any>>();
175
  const initializeOperatorParams = useInitializeOperatorParams();
176
- const { t } = useTranslation();
177
 
178
  const onDragOver = useCallback((event: React.DragEvent<HTMLDivElement>) => {
179
  event.preventDefault();
180
  event.dataTransfer.dropEffect = 'move';
181
  }, []);
182
 
183
- const generateNodeName = useCallback(
184
- (type: string) => {
185
- const name = t(`flow.${lowerFirst(type)}`);
186
- const templateNameList = nodes
187
- .filter((x) => {
188
- const temporaryName = x.data.name;
189
-
190
- const { type, index } = splitName(temporaryName);
191
-
192
- return (
193
- temporaryName.match(/_/g)?.length === 1 &&
194
- type === name &&
195
- !isNaN(index)
196
- );
197
- })
198
- .map((x) => {
199
- const temporaryName = x.data.name;
200
- const { index } = splitName(temporaryName);
201
-
202
- return {
203
- idx: index,
204
- name: temporaryName,
205
- };
206
- })
207
- .sort((a, b) => a.idx - b.idx);
208
-
209
- let index: number = 0;
210
- for (let i = 0; i < templateNameList.length; i++) {
211
- const idx = templateNameList[i]?.idx;
212
- const nextIdx = templateNameList[i + 1]?.idx;
213
- if (idx + 1 !== nextIdx) {
214
- index = idx + 1;
215
- break;
216
- }
217
- }
218
-
219
- return `${name}_${index}`;
220
- },
221
- [t, nodes],
222
- );
223
-
224
  const onDrop = useCallback(
225
  (event: React.DragEvent<HTMLDivElement>) => {
226
  event.preventDefault();
@@ -248,7 +209,7 @@ export const useHandleDrop = () => {
248
  },
249
  data: {
250
  label: `${type}`,
251
- name: generateNodeName(type),
252
  form: initializeOperatorParams(type as Operator),
253
  },
254
  sourcePosition: Position.Right,
@@ -258,7 +219,7 @@ export const useHandleDrop = () => {
258
 
259
  addNode(newNode);
260
  },
261
- [reactFlowInstance, addNode, initializeOperatorParams, generateNodeName],
262
  );
263
 
264
  return { onDrop, onDragOver, setReactFlowInstance };
 
69
  import useGraphStore, { RFState } from './store';
70
  import {
71
  buildDslComponentsByGraph,
72
+ generateNodeNamesWithIncreasingIndex,
73
  generateSwitchHandleText,
74
  getNodeDragHandle,
75
  receiveMessageError,
 
160
  return { handleDragStart };
161
  };
162
 
163
+ export const useGetNodeName = () => {
164
+ const { t } = useTranslation();
 
 
165
 
166
+ return (type: string) => {
167
+ const name = t(`flow.${lowerFirst(type)}`);
168
+ return name;
169
+ };
170
  };
171
 
172
  export const useHandleDrop = () => {
 
175
  const [reactFlowInstance, setReactFlowInstance] =
176
  useState<ReactFlowInstance<any, any>>();
177
  const initializeOperatorParams = useInitializeOperatorParams();
178
+ const getNodeName = useGetNodeName();
179
 
180
  const onDragOver = useCallback((event: React.DragEvent<HTMLDivElement>) => {
181
  event.preventDefault();
182
  event.dataTransfer.dropEffect = 'move';
183
  }, []);
184
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  const onDrop = useCallback(
186
  (event: React.DragEvent<HTMLDivElement>) => {
187
  event.preventDefault();
 
209
  },
210
  data: {
211
  label: `${type}`,
212
+ name: generateNodeNamesWithIncreasingIndex(getNodeName(type), nodes),
213
  form: initializeOperatorParams(type as Operator),
214
  },
215
  sourcePosition: Position.Right,
 
219
 
220
  addNode(newNode);
221
  },
222
+ [reactFlowInstance, getNodeName, nodes, initializeOperatorParams, addNode],
223
  );
224
 
225
  return { onDrop, onDragOver, setReactFlowInstance };
web/src/pages/flow/store.ts CHANGED
@@ -23,7 +23,12 @@ import { devtools } from 'zustand/middleware';
23
  import { immer } from 'zustand/middleware/immer';
24
  import { Operator, SwitchElseTo } from './constant';
25
  import { NodeData } from './interface';
26
- import { getNodeDragHandle, getOperatorIndex, isEdgeEqual } from './utils';
 
 
 
 
 
27
 
28
  export type RFState = {
29
  nodes: Node<NodeData>[];
@@ -54,7 +59,7 @@ export type RFState = {
54
  target?: string | null,
55
  ) => void;
56
  deletePreviousEdgeOfClassificationNode: (connection: Connection) => void;
57
- duplicateNode: (id: string) => void;
58
  deleteEdge: () => void;
59
  deleteEdgeById: (id: string) => void;
60
  deleteNodeById: (id: string) => void;
@@ -63,6 +68,7 @@ export type RFState = {
63
  updateMutableNodeFormItem: (id: string, field: string, value: any) => void;
64
  getOperatorTypeFromId: (id?: string | null) => string | undefined;
65
  updateNodeName: (id: string, name: string) => void;
 
66
  setClickedNodeId: (id?: string) => void;
67
  };
68
 
@@ -226,8 +232,8 @@ const useGraphStore = create<RFState>()(
226
  }
227
  }
228
  },
229
- duplicateNode: (id: string) => {
230
- const { getNode, addNode } = get();
231
  const node = getNode(id);
232
  const position = {
233
  x: (node?.position?.x || 0) + 30,
@@ -236,7 +242,7 @@ const useGraphStore = create<RFState>()(
236
 
237
  addNode({
238
  ...(node || {}),
239
- data: node?.data,
240
  selected: false,
241
  dragging: false,
242
  id: `${node?.data?.label}:${humanId()}`,
@@ -383,6 +389,11 @@ const useGraphStore = create<RFState>()(
383
  setClickedNodeId: (id?: string) => {
384
  set({ clickedNodeId: id });
385
  },
 
 
 
 
 
386
  })),
387
  { name: 'graph' },
388
  ),
 
23
  import { immer } from 'zustand/middleware/immer';
24
  import { Operator, SwitchElseTo } from './constant';
25
  import { NodeData } from './interface';
26
+ import {
27
+ generateNodeNamesWithIncreasingIndex,
28
+ getNodeDragHandle,
29
+ getOperatorIndex,
30
+ isEdgeEqual,
31
+ } from './utils';
32
 
33
  export type RFState = {
34
  nodes: Node<NodeData>[];
 
59
  target?: string | null,
60
  ) => void;
61
  deletePreviousEdgeOfClassificationNode: (connection: Connection) => void;
62
+ duplicateNode: (id: string, name: string) => void;
63
  deleteEdge: () => void;
64
  deleteEdgeById: (id: string) => void;
65
  deleteNodeById: (id: string) => void;
 
68
  updateMutableNodeFormItem: (id: string, field: string, value: any) => void;
69
  getOperatorTypeFromId: (id?: string | null) => string | undefined;
70
  updateNodeName: (id: string, name: string) => void;
71
+ generateNodeName: (name: string) => string;
72
  setClickedNodeId: (id?: string) => void;
73
  };
74
 
 
232
  }
233
  }
234
  },
235
+ duplicateNode: (id: string, name: string) => {
236
+ const { getNode, addNode, generateNodeName } = get();
237
  const node = getNode(id);
238
  const position = {
239
  x: (node?.position?.x || 0) + 30,
 
242
 
243
  addNode({
244
  ...(node || {}),
245
+ data: { ...(node?.data ?? {}), name: generateNodeName(name) },
246
  selected: false,
247
  dragging: false,
248
  id: `${node?.data?.label}:${humanId()}`,
 
389
  setClickedNodeId: (id?: string) => {
390
  set({ clickedNodeId: id });
391
  },
392
+ generateNodeName: (name: string) => {
393
+ const { nodes } = get();
394
+
395
+ return generateNodeNamesWithIncreasingIndex(name, nodes);
396
+ },
397
  })),
398
  { name: 'graph' },
399
  ),
web/src/pages/flow/utils.ts CHANGED
@@ -184,11 +184,12 @@ export const buildNewPositionMap = (
184
  const intersectionKeys = intersectionWith(
185
  previousKeys,
186
  currentKeys,
187
- (categoryDataKey, positionMapKey) => categoryDataKey === positionMapKey,
 
188
  );
189
  // difference set
190
  const currentDifferenceKeys = currentKeys.filter(
191
- (x) => !intersectionKeys.some((y) => y === x),
192
  );
193
  const newPositionMap = currentDifferenceKeys.reduce<
194
  Record<string, IPosition>
@@ -240,3 +241,51 @@ export const generateSwitchHandleText = (idx: number) => {
240
  export const getNodeDragHandle = (nodeType?: string) => {
241
  return nodeType === Operator.Note ? '.note-drag-handle' : undefined;
242
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  const intersectionKeys = intersectionWith(
185
  previousKeys,
186
  currentKeys,
187
+ (categoryDataKey: string, positionMapKey: string) =>
188
+ categoryDataKey === positionMapKey,
189
  );
190
  // difference set
191
  const currentDifferenceKeys = currentKeys.filter(
192
+ (x) => !intersectionKeys.some((y: string) => y === x),
193
  );
194
  const newPositionMap = currentDifferenceKeys.reduce<
195
  Record<string, IPosition>
 
241
  export const getNodeDragHandle = (nodeType?: string) => {
242
  return nodeType === Operator.Note ? '.note-drag-handle' : undefined;
243
  };
244
+
245
+ const splitName = (name: string) => {
246
+ const names = name.split('_');
247
+ const type = names.at(0);
248
+ const index = Number(names.at(-1));
249
+
250
+ return { type, index };
251
+ };
252
+
253
+ export const generateNodeNamesWithIncreasingIndex = (
254
+ name: string,
255
+ nodes: Node[],
256
+ ) => {
257
+ const templateNameList = nodes
258
+ .filter((x) => {
259
+ const temporaryName = x.data.name;
260
+
261
+ const { type, index } = splitName(temporaryName);
262
+
263
+ return (
264
+ temporaryName.match(/_/g)?.length === 1 &&
265
+ type === name &&
266
+ !isNaN(index)
267
+ );
268
+ })
269
+ .map((x) => {
270
+ const temporaryName = x.data.name;
271
+ const { index } = splitName(temporaryName);
272
+
273
+ return {
274
+ idx: index,
275
+ name: temporaryName,
276
+ };
277
+ })
278
+ .sort((a, b) => a.idx - b.idx);
279
+
280
+ let index: number = 0;
281
+ for (let i = 0; i < templateNameList.length; i++) {
282
+ const idx = templateNameList[i]?.idx;
283
+ const nextIdx = templateNameList[i + 1]?.idx;
284
+ if (idx + 1 !== nextIdx) {
285
+ index = idx + 1;
286
+ break;
287
+ }
288
+ }
289
+
290
+ return `${name}_${index}`;
291
+ };