balibabu commited on
Commit
0a9da14
·
1 Parent(s): 70153b9

feat: Display input parameters on operator nodes #3240 (#3241)

Browse files

### What problem does this PR solve?
feat: Display input parameters on operator nodes #3240


### Type of change


- [x] New Feature (non-breaking change which adds functionality)

web/package-lock.json CHANGED
@@ -17,6 +17,7 @@
17
  "@radix-ui/react-dropdown-menu": "^2.1.2",
18
  "@radix-ui/react-icons": "^1.3.1",
19
  "@radix-ui/react-label": "^2.1.0",
 
20
  "@radix-ui/react-select": "^2.1.2",
21
  "@radix-ui/react-separator": "^1.1.0",
22
  "@radix-ui/react-slot": "^1.1.0",
@@ -4370,6 +4371,42 @@
4370
  }
4371
  }
4372
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4373
  "node_modules/@radix-ui/react-popper": {
4374
  "version": "1.2.0",
4375
  "resolved": "https://registry.npmmirror.com/@radix-ui/react-popper/-/react-popper-1.2.0.tgz",
 
17
  "@radix-ui/react-dropdown-menu": "^2.1.2",
18
  "@radix-ui/react-icons": "^1.3.1",
19
  "@radix-ui/react-label": "^2.1.0",
20
+ "@radix-ui/react-popover": "^1.1.2",
21
  "@radix-ui/react-select": "^2.1.2",
22
  "@radix-ui/react-separator": "^1.1.0",
23
  "@radix-ui/react-slot": "^1.1.0",
 
4371
  }
4372
  }
4373
  },
4374
+ "node_modules/@radix-ui/react-popover": {
4375
+ "version": "1.1.2",
4376
+ "resolved": "https://registry.npmmirror.com/@radix-ui/react-popover/-/react-popover-1.1.2.tgz",
4377
+ "integrity": "sha512-u2HRUyWW+lOiA2g0Le0tMmT55FGOEWHwPFt1EPfbLly7uXQExFo5duNKqG2DzmFXIdqOeNd+TpE8baHWJCyP9w==",
4378
+ "dependencies": {
4379
+ "@radix-ui/primitive": "1.1.0",
4380
+ "@radix-ui/react-compose-refs": "1.1.0",
4381
+ "@radix-ui/react-context": "1.1.1",
4382
+ "@radix-ui/react-dismissable-layer": "1.1.1",
4383
+ "@radix-ui/react-focus-guards": "1.1.1",
4384
+ "@radix-ui/react-focus-scope": "1.1.0",
4385
+ "@radix-ui/react-id": "1.1.0",
4386
+ "@radix-ui/react-popper": "1.2.0",
4387
+ "@radix-ui/react-portal": "1.1.2",
4388
+ "@radix-ui/react-presence": "1.1.1",
4389
+ "@radix-ui/react-primitive": "2.0.0",
4390
+ "@radix-ui/react-slot": "1.1.0",
4391
+ "@radix-ui/react-use-controllable-state": "1.1.0",
4392
+ "aria-hidden": "^1.1.1",
4393
+ "react-remove-scroll": "2.6.0"
4394
+ },
4395
+ "peerDependencies": {
4396
+ "@types/react": "*",
4397
+ "@types/react-dom": "*",
4398
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
4399
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
4400
+ },
4401
+ "peerDependenciesMeta": {
4402
+ "@types/react": {
4403
+ "optional": true
4404
+ },
4405
+ "@types/react-dom": {
4406
+ "optional": true
4407
+ }
4408
+ }
4409
+ },
4410
  "node_modules/@radix-ui/react-popper": {
4411
  "version": "1.2.0",
4412
  "resolved": "https://registry.npmmirror.com/@radix-ui/react-popper/-/react-popper-1.2.0.tgz",
web/package.json CHANGED
@@ -28,6 +28,7 @@
28
  "@radix-ui/react-dropdown-menu": "^2.1.2",
29
  "@radix-ui/react-icons": "^1.3.1",
30
  "@radix-ui/react-label": "^2.1.0",
 
31
  "@radix-ui/react-select": "^2.1.2",
32
  "@radix-ui/react-separator": "^1.1.0",
33
  "@radix-ui/react-slot": "^1.1.0",
 
28
  "@radix-ui/react-dropdown-menu": "^2.1.2",
29
  "@radix-ui/react-icons": "^1.3.1",
30
  "@radix-ui/react-label": "^2.1.0",
31
+ "@radix-ui/react-popover": "^1.1.2",
32
  "@radix-ui/react-select": "^2.1.2",
33
  "@radix-ui/react-separator": "^1.1.0",
34
  "@radix-ui/react-slot": "^1.1.0",
web/src/components/ui/popover.tsx ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 'use client';
2
+
3
+ import * as PopoverPrimitive from '@radix-ui/react-popover';
4
+ import * as React from 'react';
5
+
6
+ import { cn } from '@/lib/utils';
7
+
8
+ const Popover = PopoverPrimitive.Root;
9
+
10
+ const PopoverTrigger = PopoverPrimitive.Trigger;
11
+
12
+ const PopoverContent = React.forwardRef<
13
+ React.ElementRef<typeof PopoverPrimitive.Content>,
14
+ React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
15
+ >(({ className, align = 'center', sideOffset = 4, ...props }, ref) => (
16
+ <PopoverPrimitive.Portal>
17
+ <PopoverPrimitive.Content
18
+ ref={ref}
19
+ align={align}
20
+ sideOffset={sideOffset}
21
+ className={cn(
22
+ 'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
23
+ className,
24
+ )}
25
+ {...props}
26
+ />
27
+ </PopoverPrimitive.Portal>
28
+ ));
29
+ PopoverContent.displayName = PopoverPrimitive.Content.displayName;
30
+
31
+ export { Popover, PopoverContent, PopoverTrigger };
web/src/components/ui/table.tsx ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from 'react';
2
+
3
+ import { cn } from '@/lib/utils';
4
+
5
+ const Table = React.forwardRef<
6
+ HTMLTableElement,
7
+ React.HTMLAttributes<HTMLTableElement>
8
+ >(({ className, ...props }, ref) => (
9
+ <div className="relative w-full overflow-auto">
10
+ <table
11
+ ref={ref}
12
+ className={cn('w-full caption-bottom text-sm', className)}
13
+ {...props}
14
+ />
15
+ </div>
16
+ ));
17
+ Table.displayName = 'Table';
18
+
19
+ const TableHeader = React.forwardRef<
20
+ HTMLTableSectionElement,
21
+ React.HTMLAttributes<HTMLTableSectionElement>
22
+ >(({ className, ...props }, ref) => (
23
+ <thead ref={ref} className={cn('[&_tr]:border-b', className)} {...props} />
24
+ ));
25
+ TableHeader.displayName = 'TableHeader';
26
+
27
+ const TableBody = React.forwardRef<
28
+ HTMLTableSectionElement,
29
+ React.HTMLAttributes<HTMLTableSectionElement>
30
+ >(({ className, ...props }, ref) => (
31
+ <tbody
32
+ ref={ref}
33
+ className={cn('[&_tr:last-child]:border-0', className)}
34
+ {...props}
35
+ />
36
+ ));
37
+ TableBody.displayName = 'TableBody';
38
+
39
+ const TableFooter = React.forwardRef<
40
+ HTMLTableSectionElement,
41
+ React.HTMLAttributes<HTMLTableSectionElement>
42
+ >(({ className, ...props }, ref) => (
43
+ <tfoot
44
+ ref={ref}
45
+ className={cn(
46
+ 'border-t bg-muted/50 font-medium [&>tr]:last:border-b-0',
47
+ className,
48
+ )}
49
+ {...props}
50
+ />
51
+ ));
52
+ TableFooter.displayName = 'TableFooter';
53
+
54
+ const TableRow = React.forwardRef<
55
+ HTMLTableRowElement,
56
+ React.HTMLAttributes<HTMLTableRowElement>
57
+ >(({ className, ...props }, ref) => (
58
+ <tr
59
+ ref={ref}
60
+ className={cn(
61
+ 'border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted',
62
+ className,
63
+ )}
64
+ {...props}
65
+ />
66
+ ));
67
+ TableRow.displayName = 'TableRow';
68
+
69
+ const TableHead = React.forwardRef<
70
+ HTMLTableCellElement,
71
+ React.ThHTMLAttributes<HTMLTableCellElement>
72
+ >(({ className, ...props }, ref) => (
73
+ <th
74
+ ref={ref}
75
+ className={cn(
76
+ 'h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0',
77
+ className,
78
+ )}
79
+ {...props}
80
+ />
81
+ ));
82
+ TableHead.displayName = 'TableHead';
83
+
84
+ const TableCell = React.forwardRef<
85
+ HTMLTableCellElement,
86
+ React.TdHTMLAttributes<HTMLTableCellElement>
87
+ >(({ className, ...props }, ref) => (
88
+ <td
89
+ ref={ref}
90
+ className={cn('p-4 align-middle [&:has([role=checkbox])]:pr-0', className)}
91
+ {...props}
92
+ />
93
+ ));
94
+ TableCell.displayName = 'TableCell';
95
+
96
+ const TableCaption = React.forwardRef<
97
+ HTMLTableCaptionElement,
98
+ React.HTMLAttributes<HTMLTableCaptionElement>
99
+ >(({ className, ...props }, ref) => (
100
+ <caption
101
+ ref={ref}
102
+ className={cn('mt-4 text-sm text-muted-foreground', className)}
103
+ {...props}
104
+ />
105
+ ));
106
+ TableCaption.displayName = 'TableCaption';
107
+
108
+ export {
109
+ Table,
110
+ TableBody,
111
+ TableCaption,
112
+ TableCell,
113
+ TableFooter,
114
+ TableHead,
115
+ TableHeader,
116
+ TableRow,
117
+ };
web/src/interfaces/common.ts CHANGED
@@ -11,7 +11,8 @@ export interface BaseState {
11
 
12
  export interface IModalProps<T> {
13
  showModal?(): void;
14
- hideModal(): void;
 
15
  visible?: boolean;
16
  loading?: boolean;
17
  onOk?(payload?: T): Promise<any> | void;
 
11
 
12
  export interface IModalProps<T> {
13
  showModal?(): void;
14
+ hideModal?(): void;
15
+ switchVisible?(visible: boolean): void;
16
  visible?: boolean;
17
  loading?: boolean;
18
  onOk?(payload?: T): Promise<any> | void;
web/src/locales/en.ts CHANGED
@@ -1031,8 +1031,11 @@ The above is the content you need to summarize.`,
1031
  'If the response is HTML formatted and only the primary content wanted, please toggle it on.',
1032
  reference: 'Reference',
1033
  input: 'Input',
 
1034
  parameter: 'Parameter',
1035
  howUseId: 'How to use agent ID?',
 
 
1036
  },
1037
  footer: {
1038
  profile: 'All rights reserved @ React',
 
1031
  'If the response is HTML formatted and only the primary content wanted, please toggle it on.',
1032
  reference: 'Reference',
1033
  input: 'Input',
1034
+ output: 'Output',
1035
  parameter: 'Parameter',
1036
  howUseId: 'How to use agent ID?',
1037
+ content: 'Content',
1038
+ operationResults: 'Operation Results',
1039
  },
1040
  footer: {
1041
  profile: 'All rights reserved @ React',
web/src/locales/zh-traditional.ts CHANGED
@@ -979,8 +979,11 @@ export default {
979
  cleanHtmlTip: '如果回應是 HTML 格式並且只需要主要內容,請將其開啟。',
980
  reference: '引用',
981
  input: '輸入',
 
982
  parameter: '參數',
983
  howUseId: '如何使用Agent ID?',
 
 
984
  },
985
  footer: {
986
  profile: '“保留所有權利 @ react”',
 
979
  cleanHtmlTip: '如果回應是 HTML 格式並且只需要主要內容,請將其開啟。',
980
  reference: '引用',
981
  input: '輸入',
982
+ output: '輸出',
983
  parameter: '參數',
984
  howUseId: '如何使用Agent ID?',
985
+ content: '內容',
986
+ operationResults: '運行結果',
987
  },
988
  footer: {
989
  profile: '“保留所有權利 @ react”',
web/src/locales/zh.ts CHANGED
@@ -999,8 +999,11 @@ export default {
999
  cleanHtmlTip: '如果响应是 HTML 格式且只需要主要内容,请将其打开。',
1000
  reference: '引用',
1001
  input: '输入',
 
1002
  parameter: '参数',
1003
  howUseId: '如何使用Agent ID?',
 
 
1004
  },
1005
  footer: {
1006
  profile: 'All rights reserved @ React',
 
999
  cleanHtmlTip: '如果响应是 HTML 格式且只需要主要内容,请将其打开。',
1000
  reference: '引用',
1001
  input: '输入',
1002
+ output: '输出',
1003
  parameter: '参数',
1004
  howUseId: '如何使用Agent ID?',
1005
+ content: '内容',
1006
+ operationResults: '运行结果',
1007
  },
1008
  footer: {
1009
  profile: 'All rights reserved @ React',
web/src/pages/flow/canvas/node/card.tsx ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Button } from '@/components/ui/button';
2
+ import {
3
+ Card,
4
+ CardContent,
5
+ CardDescription,
6
+ CardFooter,
7
+ CardHeader,
8
+ CardTitle,
9
+ } from '@/components/ui/card';
10
+ import { Input } from '@/components/ui/input';
11
+ import { Label } from '@/components/ui/label';
12
+ import {
13
+ Select,
14
+ SelectContent,
15
+ SelectItem,
16
+ SelectTrigger,
17
+ SelectValue,
18
+ } from '@/components/ui/select';
19
+
20
+ export function CardWithForm() {
21
+ return (
22
+ <Card className="w-[350px]">
23
+ <CardHeader>
24
+ <CardTitle>Create project</CardTitle>
25
+ <CardDescription>Deploy your new project in one-click.</CardDescription>
26
+ </CardHeader>
27
+ <CardContent>
28
+ <form>
29
+ <div className="grid w-full items-center gap-4">
30
+ <div className="flex flex-col space-y-1.5">
31
+ <Label htmlFor="name">Name</Label>
32
+ <Input id="name" placeholder="Name of your project" />
33
+ </div>
34
+ <div className="flex flex-col space-y-1.5">
35
+ <Label htmlFor="framework">Framework</Label>
36
+ <Select>
37
+ <SelectTrigger id="framework">
38
+ <SelectValue placeholder="Select" />
39
+ </SelectTrigger>
40
+ <SelectContent position="popper">
41
+ <SelectItem value="next">Next.js</SelectItem>
42
+ <SelectItem value="sveltekit">SvelteKit</SelectItem>
43
+ <SelectItem value="astro">Astro</SelectItem>
44
+ <SelectItem value="nuxt">Nuxt.js</SelectItem>
45
+ </SelectContent>
46
+ </Select>
47
+ </div>
48
+ </div>
49
+ </form>
50
+ </CardContent>
51
+ <CardFooter className="flex justify-between">
52
+ <Button variant="outline">Cancel</Button>
53
+ <Button>Deploy</Button>
54
+ </CardFooter>
55
+ </Card>
56
+ );
57
+ }
web/src/pages/flow/canvas/node/categorize-node.tsx CHANGED
@@ -8,55 +8,52 @@ import { RightHandleStyle } from './handle-icon';
8
  import { useBuildCategorizeHandlePositions } from './hooks';
9
  import styles from './index.less';
10
  import NodeHeader from './node-header';
11
- import NodePopover from './popover';
12
 
13
  export function CategorizeNode({ id, data, selected }: NodeProps<NodeData>) {
14
  const { positions } = useBuildCategorizeHandlePositions({ data, id });
15
 
16
  return (
17
- <NodePopover nodeId={id}>
18
- <section
19
- className={classNames(styles.logicNode, {
20
- [styles.selectedNode]: selected,
21
- })}
22
- >
23
- <Handle
24
- type="target"
25
- position={Position.Left}
26
- isConnectable
27
- className={styles.handle}
28
- id={'a'}
29
- ></Handle>
30
 
31
- <NodeHeader
32
- id={id}
33
- name={data.name}
34
- label={data.label}
35
- className={styles.nodeHeader}
36
- ></NodeHeader>
37
 
38
- <Flex vertical gap={8}>
39
- <div className={styles.nodeText}>
40
- <LLMLabel value={get(data, 'form.llm_id')}></LLMLabel>
41
- </div>
42
- {positions.map((position, idx) => {
43
- return (
44
- <div key={idx}>
45
- <div className={styles.nodeText}>{position.text}</div>
46
- <Handle
47
- key={position.text}
48
- id={position.text}
49
- type="source"
50
- position={Position.Right}
51
- isConnectable
52
- className={styles.handle}
53
- style={{ ...RightHandleStyle, top: position.top }}
54
- ></Handle>
55
- </div>
56
- );
57
- })}
58
- </Flex>
59
- </section>
60
- </NodePopover>
61
  );
62
  }
 
8
  import { useBuildCategorizeHandlePositions } from './hooks';
9
  import styles from './index.less';
10
  import NodeHeader from './node-header';
 
11
 
12
  export function CategorizeNode({ id, data, selected }: NodeProps<NodeData>) {
13
  const { positions } = useBuildCategorizeHandlePositions({ data, id });
14
 
15
  return (
16
+ <section
17
+ className={classNames(styles.logicNode, {
18
+ [styles.selectedNode]: selected,
19
+ })}
20
+ >
21
+ <Handle
22
+ type="target"
23
+ position={Position.Left}
24
+ isConnectable
25
+ className={styles.handle}
26
+ id={'a'}
27
+ ></Handle>
 
28
 
29
+ <NodeHeader
30
+ id={id}
31
+ name={data.name}
32
+ label={data.label}
33
+ className={styles.nodeHeader}
34
+ ></NodeHeader>
35
 
36
+ <Flex vertical gap={8}>
37
+ <div className={styles.nodeText}>
38
+ <LLMLabel value={get(data, 'form.llm_id')}></LLMLabel>
39
+ </div>
40
+ {positions.map((position, idx) => {
41
+ return (
42
+ <div key={idx}>
43
+ <div className={styles.nodeText}>{position.text}</div>
44
+ <Handle
45
+ key={position.text}
46
+ id={position.text}
47
+ type="source"
48
+ position={Position.Right}
49
+ isConnectable
50
+ className={styles.handle}
51
+ style={{ ...RightHandleStyle, top: position.top }}
52
+ ></Handle>
53
+ </div>
54
+ );
55
+ })}
56
+ </Flex>
57
+ </section>
 
58
  );
59
  }
web/src/pages/flow/canvas/node/generate-node.tsx CHANGED
@@ -8,7 +8,6 @@ import { IGenerateParameter, NodeData } from '../../interface';
8
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
9
  import styles from './index.less';
10
  import NodeHeader from './node-header';
11
- import NodePopover from './popover';
12
 
13
  export function GenerateNode({
14
  id,
@@ -20,55 +19,53 @@ export function GenerateNode({
20
  const getLabel = useGetComponentLabelByValue(id);
21
 
22
  return (
23
- <NodePopover nodeId={id}>
24
- <section
25
- className={classNames(styles.logicNode, {
26
- [styles.selectedNode]: selected,
27
- })}
28
- >
29
- <Handle
30
- id="c"
31
- type="source"
32
- position={Position.Left}
33
- isConnectable={isConnectable}
34
- className={styles.handle}
35
- style={LeftHandleStyle}
36
- ></Handle>
37
- <Handle
38
- type="source"
39
- position={Position.Right}
40
- isConnectable={isConnectable}
41
- className={styles.handle}
42
- style={RightHandleStyle}
43
- id="b"
44
- ></Handle>
45
 
46
- <NodeHeader
47
- id={id}
48
- name={data.name}
49
- label={data.label}
50
- className={styles.nodeHeader}
51
- ></NodeHeader>
52
 
53
- <div className={styles.nodeText}>
54
- <LLMLabel value={get(data, 'form.llm_id')}></LLMLabel>
55
- </div>
56
- <Flex gap={8} vertical className={styles.generateParameters}>
57
- {parameters.map((x) => (
58
- <Flex
59
- key={x.id}
60
- align="center"
61
- gap={6}
62
- className={styles.conditionBlock}
63
- >
64
- <label htmlFor="">{x.key}</label>
65
- <span className={styles.parameterValue}>
66
- {getLabel(x.component_id)}
67
- </span>
68
- </Flex>
69
- ))}
70
- </Flex>
71
- </section>
72
- </NodePopover>
73
  );
74
  }
 
8
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
9
  import styles from './index.less';
10
  import NodeHeader from './node-header';
 
11
 
12
  export function GenerateNode({
13
  id,
 
19
  const getLabel = useGetComponentLabelByValue(id);
20
 
21
  return (
22
+ <section
23
+ className={classNames(styles.logicNode, {
24
+ [styles.selectedNode]: selected,
25
+ })}
26
+ >
27
+ <Handle
28
+ id="c"
29
+ type="source"
30
+ position={Position.Left}
31
+ isConnectable={isConnectable}
32
+ className={styles.handle}
33
+ style={LeftHandleStyle}
34
+ ></Handle>
35
+ <Handle
36
+ type="source"
37
+ position={Position.Right}
38
+ isConnectable={isConnectable}
39
+ className={styles.handle}
40
+ style={RightHandleStyle}
41
+ id="b"
42
+ ></Handle>
 
43
 
44
+ <NodeHeader
45
+ id={id}
46
+ name={data.name}
47
+ label={data.label}
48
+ className={styles.nodeHeader}
49
+ ></NodeHeader>
50
 
51
+ <div className={styles.nodeText}>
52
+ <LLMLabel value={get(data, 'form.llm_id')}></LLMLabel>
53
+ </div>
54
+ <Flex gap={8} vertical className={styles.generateParameters}>
55
+ {parameters.map((x) => (
56
+ <Flex
57
+ key={x.id}
58
+ align="center"
59
+ gap={6}
60
+ className={styles.conditionBlock}
61
+ >
62
+ <label htmlFor="">{x.key}</label>
63
+ <span className={styles.parameterValue}>
64
+ {getLabel(x.component_id)}
65
+ </span>
66
+ </Flex>
67
+ ))}
68
+ </Flex>
69
+ </section>
 
70
  );
71
  }
web/src/pages/flow/canvas/node/index.tsx CHANGED
@@ -4,7 +4,6 @@ import { NodeData } from '../../interface';
4
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
5
  import styles from './index.less';
6
  import NodeHeader from './node-header';
7
- import NodePopover from './popover';
8
 
9
  export function RagNode({
10
  id,
@@ -13,30 +12,28 @@ export function RagNode({
13
  selected,
14
  }: NodeProps<NodeData>) {
15
  return (
16
- <NodePopover nodeId={id}>
17
- <section
18
- className={classNames(styles.ragNode, {
19
- [styles.selectedNode]: selected,
20
- })}
21
- >
22
- <Handle
23
- id="c"
24
- type="source"
25
- position={Position.Left}
26
- isConnectable={isConnectable}
27
- className={styles.handle}
28
- style={LeftHandleStyle}
29
- ></Handle>
30
- <Handle
31
- type="source"
32
- position={Position.Right}
33
- isConnectable={isConnectable}
34
- className={styles.handle}
35
- id="b"
36
- style={RightHandleStyle}
37
- ></Handle>
38
- <NodeHeader id={id} name={data.name} label={data.label}></NodeHeader>
39
- </section>
40
- </NodePopover>
41
  );
42
  }
 
4
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
5
  import styles from './index.less';
6
  import NodeHeader from './node-header';
 
7
 
8
  export function RagNode({
9
  id,
 
12
  selected,
13
  }: NodeProps<NodeData>) {
14
  return (
15
+ <section
16
+ className={classNames(styles.ragNode, {
17
+ [styles.selectedNode]: selected,
18
+ })}
19
+ >
20
+ <Handle
21
+ id="c"
22
+ type="source"
23
+ position={Position.Left}
24
+ isConnectable={isConnectable}
25
+ className={styles.handle}
26
+ style={LeftHandleStyle}
27
+ ></Handle>
28
+ <Handle
29
+ type="source"
30
+ position={Position.Right}
31
+ isConnectable={isConnectable}
32
+ className={styles.handle}
33
+ id="b"
34
+ style={RightHandleStyle}
35
+ ></Handle>
36
+ <NodeHeader id={id} name={data.name} label={data.label}></NodeHeader>
37
+ </section>
 
 
38
  );
39
  }
web/src/pages/flow/canvas/node/invoke-node.tsx CHANGED
@@ -7,7 +7,6 @@ import { NodeData } from '../../interface';
7
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
8
  import styles from './index.less';
9
  import NodeHeader from './node-header';
10
- import NodePopover from './popover';
11
 
12
  export function InvokeNode({
13
  id,
@@ -18,39 +17,37 @@ export function InvokeNode({
18
  const { t } = useTranslation();
19
  const url = get(data, 'form.url');
20
  return (
21
- <NodePopover nodeId={id}>
22
- <section
23
- className={classNames(styles.ragNode, {
24
- [styles.selectedNode]: selected,
25
- })}
26
- >
27
- <Handle
28
- id="c"
29
- type="source"
30
- position={Position.Left}
31
- isConnectable={isConnectable}
32
- className={styles.handle}
33
- style={LeftHandleStyle}
34
- ></Handle>
35
- <Handle
36
- type="source"
37
- position={Position.Right}
38
- isConnectable={isConnectable}
39
- className={styles.handle}
40
- id="b"
41
- style={RightHandleStyle}
42
- ></Handle>
43
- <NodeHeader
44
- id={id}
45
- name={data.name}
46
- label={data.label}
47
- className={styles.nodeHeader}
48
- ></NodeHeader>
49
- <Flex vertical>
50
- <div>{t('flow.url')}</div>
51
- <div className={styles.nodeText}>{url}</div>
52
- </Flex>
53
- </section>
54
- </NodePopover>
55
  );
56
  }
 
7
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
8
  import styles from './index.less';
9
  import NodeHeader from './node-header';
 
10
 
11
  export function InvokeNode({
12
  id,
 
17
  const { t } = useTranslation();
18
  const url = get(data, 'form.url');
19
  return (
20
+ <section
21
+ className={classNames(styles.ragNode, {
22
+ [styles.selectedNode]: selected,
23
+ })}
24
+ >
25
+ <Handle
26
+ id="c"
27
+ type="source"
28
+ position={Position.Left}
29
+ isConnectable={isConnectable}
30
+ className={styles.handle}
31
+ style={LeftHandleStyle}
32
+ ></Handle>
33
+ <Handle
34
+ type="source"
35
+ position={Position.Right}
36
+ isConnectable={isConnectable}
37
+ className={styles.handle}
38
+ id="b"
39
+ style={RightHandleStyle}
40
+ ></Handle>
41
+ <NodeHeader
42
+ id={id}
43
+ name={data.name}
44
+ label={data.label}
45
+ className={styles.nodeHeader}
46
+ ></NodeHeader>
47
+ <Flex vertical>
48
+ <div>{t('flow.url')}</div>
49
+ <div className={styles.nodeText}>{url}</div>
50
+ </Flex>
51
+ </section>
 
 
52
  );
53
  }
web/src/pages/flow/canvas/node/keyword-node.tsx CHANGED
@@ -6,7 +6,6 @@ import { NodeData } from '../../interface';
6
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
7
  import styles from './index.less';
8
  import NodeHeader from './node-header';
9
- import NodePopover from './popover';
10
 
11
  export function KeywordNode({
12
  id,
@@ -15,40 +14,38 @@ export function KeywordNode({
15
  selected,
16
  }: NodeProps<NodeData>) {
17
  return (
18
- <NodePopover nodeId={id}>
19
- <section
20
- className={classNames(styles.logicNode, {
21
- [styles.selectedNode]: selected,
22
- })}
23
- >
24
- <Handle
25
- id="c"
26
- type="source"
27
- position={Position.Left}
28
- isConnectable={isConnectable}
29
- className={styles.handle}
30
- style={LeftHandleStyle}
31
- ></Handle>
32
- <Handle
33
- type="source"
34
- position={Position.Right}
35
- isConnectable={isConnectable}
36
- className={styles.handle}
37
- style={RightHandleStyle}
38
- id="b"
39
- ></Handle>
40
 
41
- <NodeHeader
42
- id={id}
43
- name={data.name}
44
- label={data.label}
45
- className={styles.nodeHeader}
46
- ></NodeHeader>
47
 
48
- <div className={styles.nodeText}>
49
- <LLMLabel value={get(data, 'form.llm_id')}></LLMLabel>
50
- </div>
51
- </section>
52
- </NodePopover>
53
  );
54
  }
 
6
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
7
  import styles from './index.less';
8
  import NodeHeader from './node-header';
 
9
 
10
  export function KeywordNode({
11
  id,
 
14
  selected,
15
  }: NodeProps<NodeData>) {
16
  return (
17
+ <section
18
+ className={classNames(styles.logicNode, {
19
+ [styles.selectedNode]: selected,
20
+ })}
21
+ >
22
+ <Handle
23
+ id="c"
24
+ type="source"
25
+ position={Position.Left}
26
+ isConnectable={isConnectable}
27
+ className={styles.handle}
28
+ style={LeftHandleStyle}
29
+ ></Handle>
30
+ <Handle
31
+ type="source"
32
+ position={Position.Right}
33
+ isConnectable={isConnectable}
34
+ className={styles.handle}
35
+ style={RightHandleStyle}
36
+ id="b"
37
+ ></Handle>
 
38
 
39
+ <NodeHeader
40
+ id={id}
41
+ name={data.name}
42
+ label={data.label}
43
+ className={styles.nodeHeader}
44
+ ></NodeHeader>
45
 
46
+ <div className={styles.nodeText}>
47
+ <LLMLabel value={get(data, 'form.llm_id')}></LLMLabel>
48
+ </div>
49
+ </section>
 
50
  );
51
  }
web/src/pages/flow/canvas/node/logic-node.tsx CHANGED
@@ -4,7 +4,6 @@ import { NodeData } from '../../interface';
4
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
5
  import styles from './index.less';
6
  import NodeHeader from './node-header';
7
- import NodePopover from './popover';
8
 
9
  export function LogicNode({
10
  id,
@@ -13,30 +12,28 @@ export function LogicNode({
13
  selected,
14
  }: NodeProps<NodeData>) {
15
  return (
16
- <NodePopover nodeId={id}>
17
- <section
18
- className={classNames(styles.logicNode, {
19
- [styles.selectedNode]: selected,
20
- })}
21
- >
22
- <Handle
23
- id="c"
24
- type="source"
25
- position={Position.Left}
26
- isConnectable={isConnectable}
27
- className={styles.handle}
28
- style={LeftHandleStyle}
29
- ></Handle>
30
- <Handle
31
- type="source"
32
- position={Position.Right}
33
- isConnectable={isConnectable}
34
- className={styles.handle}
35
- style={RightHandleStyle}
36
- id="b"
37
- ></Handle>
38
- <NodeHeader id={id} name={data.name} label={data.label}></NodeHeader>
39
- </section>
40
- </NodePopover>
41
  );
42
  }
 
4
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
5
  import styles from './index.less';
6
  import NodeHeader from './node-header';
 
7
 
8
  export function LogicNode({
9
  id,
 
12
  selected,
13
  }: NodeProps<NodeData>) {
14
  return (
15
+ <section
16
+ className={classNames(styles.logicNode, {
17
+ [styles.selectedNode]: selected,
18
+ })}
19
+ >
20
+ <Handle
21
+ id="c"
22
+ type="source"
23
+ position={Position.Left}
24
+ isConnectable={isConnectable}
25
+ className={styles.handle}
26
+ style={LeftHandleStyle}
27
+ ></Handle>
28
+ <Handle
29
+ type="source"
30
+ position={Position.Right}
31
+ isConnectable={isConnectable}
32
+ className={styles.handle}
33
+ style={RightHandleStyle}
34
+ id="b"
35
+ ></Handle>
36
+ <NodeHeader id={id} name={data.name} label={data.label}></NodeHeader>
37
+ </section>
 
 
38
  );
39
  }
web/src/pages/flow/canvas/node/message-node.tsx CHANGED
@@ -6,7 +6,6 @@ import { NodeData } from '../../interface';
6
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
7
  import styles from './index.less';
8
  import NodeHeader from './node-header';
9
- import NodePopover from './popover';
10
 
11
  export function MessageNode({
12
  id,
@@ -17,47 +16,45 @@ export function MessageNode({
17
  const messages: string[] = get(data, 'form.messages', []);
18
 
19
  return (
20
- <NodePopover nodeId={id}>
21
- <section
22
- className={classNames(styles.logicNode, {
23
- [styles.selectedNode]: selected,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  })}
25
- >
26
- <Handle
27
- id="c"
28
- type="source"
29
- position={Position.Left}
30
- isConnectable={isConnectable}
31
- className={styles.handle}
32
- style={LeftHandleStyle}
33
- ></Handle>
34
- <Handle
35
- type="source"
36
- position={Position.Right}
37
- isConnectable={isConnectable}
38
- className={styles.handle}
39
- style={RightHandleStyle}
40
- id="b"
41
- ></Handle>
42
- <NodeHeader
43
- id={id}
44
- name={data.name}
45
- label={data.label}
46
- className={classNames({
47
- [styles.nodeHeader]: messages.length > 0,
48
- })}
49
- ></NodeHeader>
50
 
51
- <Flex vertical gap={8} className={styles.messageNodeContainer}>
52
- {messages.map((message, idx) => {
53
- return (
54
- <div className={styles.nodeText} key={idx}>
55
- {message}
56
- </div>
57
- );
58
- })}
59
- </Flex>
60
- </section>
61
- </NodePopover>
62
  );
63
  }
 
6
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
7
  import styles from './index.less';
8
  import NodeHeader from './node-header';
 
9
 
10
  export function MessageNode({
11
  id,
 
16
  const messages: string[] = get(data, 'form.messages', []);
17
 
18
  return (
19
+ <section
20
+ className={classNames(styles.logicNode, {
21
+ [styles.selectedNode]: selected,
22
+ })}
23
+ >
24
+ <Handle
25
+ id="c"
26
+ type="source"
27
+ position={Position.Left}
28
+ isConnectable={isConnectable}
29
+ className={styles.handle}
30
+ style={LeftHandleStyle}
31
+ ></Handle>
32
+ <Handle
33
+ type="source"
34
+ position={Position.Right}
35
+ isConnectable={isConnectable}
36
+ className={styles.handle}
37
+ style={RightHandleStyle}
38
+ id="b"
39
+ ></Handle>
40
+ <NodeHeader
41
+ id={id}
42
+ name={data.name}
43
+ label={data.label}
44
+ className={classNames({
45
+ [styles.nodeHeader]: messages.length > 0,
46
  })}
47
+ ></NodeHeader>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
+ <Flex vertical gap={8} className={styles.messageNodeContainer}>
50
+ {messages.map((message, idx) => {
51
+ return (
52
+ <div className={styles.nodeText} key={idx}>
53
+ {message}
54
+ </div>
55
+ );
56
+ })}
57
+ </Flex>
58
+ </section>
 
59
  );
60
  }
web/src/pages/flow/canvas/node/node-header.tsx CHANGED
@@ -1,34 +1,52 @@
1
  import { Flex } from 'antd';
2
-
3
  import { Operator, operatorMap } from '../../constant';
4
  import OperatorIcon from '../../operator-icon';
5
  import NodeDropdown from './dropdown';
 
 
6
  import styles from './index.less';
 
7
 
8
  interface IProps {
9
  id: string;
10
- label: string;
11
- name: string;
12
  gap?: number;
13
  className?: string;
14
  }
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  const NodeHeader = ({ label, id, name, gap = 4, className }: IProps) => {
17
  return (
18
- <Flex
19
- flex={1}
20
- align="center"
21
- justify={'space-between'}
22
- gap={gap}
23
- className={className}
24
- >
25
- <OperatorIcon
26
- name={label as Operator}
27
- color={operatorMap[label as Operator].color}
28
- ></OperatorIcon>
29
- <span className={styles.nodeTitle}>{name}</span>
30
- <NodeDropdown id={id}></NodeDropdown>
31
- </Flex>
 
 
 
32
  );
33
  };
34
 
 
1
  import { Flex } from 'antd';
 
2
  import { Operator, operatorMap } from '../../constant';
3
  import OperatorIcon from '../../operator-icon';
4
  import NodeDropdown from './dropdown';
5
+
6
+ import { useTranslate } from '@/hooks/common-hooks';
7
  import styles from './index.less';
8
+ 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 ">
22
+ <NextNodePopover nodeId={id} name={name}>
23
+ <span className="text-blue-600 cursor-pointer text-[10px]">
24
+ {t('operationResults')}
25
+ </span>
26
+ </NextNodePopover>
27
+ </section>
28
+ );
29
+ }
30
+
31
  const NodeHeader = ({ label, id, name, gap = 4, className }: IProps) => {
32
  return (
33
+ <section className="haha">
34
+ {label !== Operator.Answer && <RunStatus id={id} name={name}></RunStatus>}
35
+ <Flex
36
+ flex={1}
37
+ align="center"
38
+ justify={'space-between'}
39
+ gap={gap}
40
+ className={className}
41
+ >
42
+ <OperatorIcon
43
+ name={label as Operator}
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
  );
51
  };
52
 
web/src/pages/flow/canvas/node/popover.tsx CHANGED
@@ -1,49 +1,98 @@
1
  import { useFetchFlow } from '@/hooks/flow-hooks';
2
- import { Popover } from 'antd';
3
  import get from 'lodash/get';
4
- import React, { useMemo } from 'react';
5
  import JsonView from 'react18-json-view';
6
  import 'react18-json-view/src/style.css';
7
- import { Operator } from '../../constant';
8
  import { useReplaceIdWithText } from '../../hooks';
9
 
10
- import styles from './index.less';
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  interface IProps extends React.PropsWithChildren {
13
  nodeId: string;
 
14
  }
15
 
16
- const NodePopover = ({ children, nodeId }: IProps) => {
 
 
17
  const { data } = useFetchFlow();
18
  const component = useMemo(() => {
19
  return get(data, ['dsl', 'components', nodeId], {});
20
  }, [nodeId, data]);
21
 
 
 
 
 
 
22
  const output = get(component, ['obj', 'params', 'output'], {});
23
- const componentName = get(component, ['obj', 'component_name'], '');
24
- const replacedOutput = useReplaceIdWithText(output);
25
-
26
- const content =
27
- componentName !== Operator.Answer ? (
28
- <div
29
- onClick={(e) => {
30
- e.preventDefault();
31
- e.stopPropagation();
32
- }}
33
- >
34
- <JsonView
35
- src={replacedOutput}
36
- displaySize={30}
37
- className={styles.jsonView}
38
- />
39
- </div>
40
- ) : undefined;
41
 
42
  return (
43
- <Popover content={content} placement="right" destroyTooltipOnHide>
44
- {children}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  </Popover>
46
  );
47
- };
48
-
49
- export default NodePopover;
 
1
  import { useFetchFlow } from '@/hooks/flow-hooks';
 
2
  import get from 'lodash/get';
3
+ import React, { MouseEventHandler, useCallback, useMemo } from 'react';
4
  import JsonView from 'react18-json-view';
5
  import 'react18-json-view/src/style.css';
 
6
  import { useReplaceIdWithText } from '../../hooks';
7
 
8
+ import {
9
+ Popover,
10
+ PopoverContent,
11
+ PopoverTrigger,
12
+ } from '@/components/ui/popover';
13
+ import {
14
+ Table,
15
+ TableBody,
16
+ TableCell,
17
+ TableHead,
18
+ TableHeader,
19
+ TableRow,
20
+ } from '@/components/ui/table';
21
+ import { useTranslate } from '@/hooks/common-hooks';
22
 
23
  interface IProps extends React.PropsWithChildren {
24
  nodeId: string;
25
+ name?: string;
26
  }
27
 
28
+ export function NextNodePopover({ children, nodeId, name }: IProps) {
29
+ const { t } = useTranslate('flow');
30
+
31
  const { data } = useFetchFlow();
32
  const component = useMemo(() => {
33
  return get(data, ['dsl', 'components', nodeId], {});
34
  }, [nodeId, data]);
35
 
36
+ const inputs: Array<{ component_id: string; content: string }> = get(
37
+ component,
38
+ ['obj', 'params', 'inputs'],
39
+ [],
40
+ );
41
  const output = get(component, ['obj', 'params', 'output'], {});
42
+ const { replacedOutput, getNameById } = useReplaceIdWithText(output);
43
+ const stopPropagation: MouseEventHandler = useCallback((e) => {
44
+ e.stopPropagation();
45
+ }, []);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
  return (
48
+ <Popover>
49
+ <PopoverTrigger onClick={stopPropagation} asChild>
50
+ {children}
51
+ </PopoverTrigger>
52
+ <PopoverContent
53
+ align={'start'}
54
+ side={'right'}
55
+ sideOffset={20}
56
+ onClick={stopPropagation}
57
+ className="w-[400px]"
58
+ >
59
+ <div className="mb-3 font-semibold text-[16px]">
60
+ {name} {t('operationResults')}
61
+ </div>
62
+ <div className="flex w-full gap-4 flex-col">
63
+ <div className="flex flex-col space-y-1.5">
64
+ <span className="font-semibold text-[14px]">{t('input')}</span>
65
+ <div className="bg-gray-100 p-1 rounded">
66
+ <Table>
67
+ <TableHeader>
68
+ <TableRow>
69
+ <TableHead>{t('componentId')}</TableHead>
70
+ <TableHead className="w-[60px]">{t('content')}</TableHead>
71
+ </TableRow>
72
+ </TableHeader>
73
+ <TableBody>
74
+ {inputs.map((x, idx) => (
75
+ <TableRow key={idx}>
76
+ <TableCell>{getNameById(x.component_id)}</TableCell>
77
+ <TableCell className="truncate">{x.content}</TableCell>
78
+ </TableRow>
79
+ ))}
80
+ </TableBody>
81
+ </Table>
82
+ </div>
83
+ </div>
84
+ <div className="flex flex-col space-y-1.5">
85
+ <span className="font-semibold text-[14px]">{t('output')}</span>
86
+ <div className="bg-gray-100 p-1 rounded">
87
+ <JsonView
88
+ src={replacedOutput}
89
+ displaySize={30}
90
+ className="w-full max-h-[300px] break-words overflow-auto"
91
+ />
92
+ </div>
93
+ </div>
94
+ </div>
95
+ </PopoverContent>
96
  </Popover>
97
  );
98
+ }
 
 
web/src/pages/flow/canvas/node/relevant-node.tsx CHANGED
@@ -3,7 +3,6 @@ import classNames from 'classnames';
3
  import { Handle, NodeProps, Position } from 'reactflow';
4
  import { NodeData } from '../../interface';
5
  import { RightHandleStyle } from './handle-icon';
6
- import NodePopover from './popover';
7
 
8
  import { get } from 'lodash';
9
  import styles from './index.less';
@@ -13,53 +12,51 @@ export function RelevantNode({ id, data, selected }: NodeProps<NodeData>) {
13
  const yes = get(data, 'form.yes');
14
  const no = get(data, 'form.no');
15
  return (
16
- <NodePopover nodeId={id}>
17
- <section
18
- className={classNames(styles.logicNode, {
19
- [styles.selectedNode]: selected,
20
- })}
21
- >
22
- <Handle
23
- type="target"
24
- position={Position.Left}
25
- isConnectable
26
- className={styles.handle}
27
- id={'a'}
28
- ></Handle>
29
- <Handle
30
- type="source"
31
- position={Position.Right}
32
- isConnectable
33
- className={styles.handle}
34
- id={'yes'}
35
- style={{ ...RightHandleStyle, top: 59 }}
36
- ></Handle>
37
- <Handle
38
- type="source"
39
- position={Position.Right}
40
- isConnectable
41
- className={styles.handle}
42
- id={'no'}
43
- style={{ ...RightHandleStyle, top: 112 }}
44
- ></Handle>
45
- <NodeHeader
46
- id={id}
47
- name={data.name}
48
- label={data.label}
49
- className={styles.nodeHeader}
50
- ></NodeHeader>
51
 
52
- <Flex vertical gap={10}>
53
- <Flex vertical>
54
- <div className={styles.relevantLabel}>Yes</div>
55
- <div className={styles.nodeText}>{yes}</div>
56
- </Flex>
57
- <Flex vertical>
58
- <div className={styles.relevantLabel}>No</div>
59
- <div className={styles.nodeText}>{no}</div>
60
- </Flex>
61
  </Flex>
62
- </section>
63
- </NodePopover>
 
 
 
 
64
  );
65
  }
 
3
  import { Handle, NodeProps, Position } from 'reactflow';
4
  import { NodeData } from '../../interface';
5
  import { RightHandleStyle } from './handle-icon';
 
6
 
7
  import { get } from 'lodash';
8
  import styles from './index.less';
 
12
  const yes = get(data, 'form.yes');
13
  const no = get(data, 'form.no');
14
  return (
15
+ <section
16
+ className={classNames(styles.logicNode, {
17
+ [styles.selectedNode]: selected,
18
+ })}
19
+ >
20
+ <Handle
21
+ type="target"
22
+ position={Position.Left}
23
+ isConnectable
24
+ className={styles.handle}
25
+ id={'a'}
26
+ ></Handle>
27
+ <Handle
28
+ type="source"
29
+ position={Position.Right}
30
+ isConnectable
31
+ className={styles.handle}
32
+ id={'yes'}
33
+ style={{ ...RightHandleStyle, top: 59 }}
34
+ ></Handle>
35
+ <Handle
36
+ type="source"
37
+ position={Position.Right}
38
+ isConnectable
39
+ className={styles.handle}
40
+ id={'no'}
41
+ style={{ ...RightHandleStyle, top: 112 }}
42
+ ></Handle>
43
+ <NodeHeader
44
+ id={id}
45
+ name={data.name}
46
+ label={data.label}
47
+ className={styles.nodeHeader}
48
+ ></NodeHeader>
 
49
 
50
+ <Flex vertical gap={10}>
51
+ <Flex vertical>
52
+ <div className={styles.relevantLabel}>Yes</div>
53
+ <div className={styles.nodeText}>{yes}</div>
 
 
 
 
 
54
  </Flex>
55
+ <Flex vertical>
56
+ <div className={styles.relevantLabel}>No</div>
57
+ <div className={styles.nodeText}>{no}</div>
58
+ </Flex>
59
+ </Flex>
60
+ </section>
61
  );
62
  }
web/src/pages/flow/canvas/node/retrieval-node.tsx CHANGED
@@ -9,7 +9,6 @@ import { NodeData } from '../../interface';
9
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
10
  import styles from './index.less';
11
  import NodeHeader from './node-header';
12
- import NodePopover from './popover';
13
 
14
  export function RetrievalNode({
15
  id,
@@ -31,55 +30,53 @@ export function RetrievalNode({
31
  }, [knowledgeList, knowledgeBaseIds]);
32
 
33
  return (
34
- <NodePopover nodeId={id}>
35
- <section
36
- className={classNames(styles.logicNode, {
37
- [styles.selectedNode]: selected,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  })}
39
- >
40
- <Handle
41
- id="c"
42
- type="source"
43
- position={Position.Left}
44
- isConnectable={isConnectable}
45
- className={styles.handle}
46
- style={LeftHandleStyle}
47
- ></Handle>
48
- <Handle
49
- type="source"
50
- position={Position.Right}
51
- isConnectable={isConnectable}
52
- className={styles.handle}
53
- style={RightHandleStyle}
54
- id="b"
55
- ></Handle>
56
- <NodeHeader
57
- id={id}
58
- name={data.name}
59
- label={data.label}
60
- className={classNames({
61
- [styles.nodeHeader]: knowledgeBaseIds.length > 0,
62
- })}
63
- ></NodeHeader>
64
- <Flex vertical gap={8}>
65
- {knowledgeBases.map((knowledge) => {
66
- return (
67
- <div className={styles.nodeText} key={knowledge.id}>
68
- <Flex align={'center'} gap={6}>
69
- <Avatar
70
- size={26}
71
- icon={<UserOutlined />}
72
- src={knowledge.avatar}
73
- />
74
- <Flex className={styles.knowledgeNodeName} flex={1}>
75
- {knowledge.name}
76
- </Flex>
77
  </Flex>
78
- </div>
79
- );
80
- })}
81
- </Flex>
82
- </section>
83
- </NodePopover>
84
  );
85
  }
 
9
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
10
  import styles from './index.less';
11
  import NodeHeader from './node-header';
 
12
 
13
  export function RetrievalNode({
14
  id,
 
30
  }, [knowledgeList, knowledgeBaseIds]);
31
 
32
  return (
33
+ <section
34
+ className={classNames(styles.logicNode, {
35
+ [styles.selectedNode]: selected,
36
+ })}
37
+ >
38
+ <Handle
39
+ id="c"
40
+ type="source"
41
+ position={Position.Left}
42
+ isConnectable={isConnectable}
43
+ className={styles.handle}
44
+ style={LeftHandleStyle}
45
+ ></Handle>
46
+ <Handle
47
+ type="source"
48
+ position={Position.Right}
49
+ isConnectable={isConnectable}
50
+ className={styles.handle}
51
+ style={RightHandleStyle}
52
+ id="b"
53
+ ></Handle>
54
+ <NodeHeader
55
+ id={id}
56
+ name={data.name}
57
+ label={data.label}
58
+ className={classNames({
59
+ [styles.nodeHeader]: knowledgeBaseIds.length > 0,
60
  })}
61
+ ></NodeHeader>
62
+ <Flex vertical gap={8}>
63
+ {knowledgeBases.map((knowledge) => {
64
+ return (
65
+ <div className={styles.nodeText} key={knowledge.id}>
66
+ <Flex align={'center'} gap={6}>
67
+ <Avatar
68
+ size={26}
69
+ icon={<UserOutlined />}
70
+ src={knowledge.avatar}
71
+ />
72
+ <Flex className={styles.knowledgeNodeName} flex={1}>
73
+ {knowledge.name}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  </Flex>
75
+ </Flex>
76
+ </div>
77
+ );
78
+ })}
79
+ </Flex>
80
+ </section>
81
  );
82
  }
web/src/pages/flow/canvas/node/rewrite-node.tsx CHANGED
@@ -6,7 +6,6 @@ import { NodeData } from '../../interface';
6
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
7
  import styles from './index.less';
8
  import NodeHeader from './node-header';
9
- import NodePopover from './popover';
10
 
11
  export function RewriteNode({
12
  id,
@@ -15,40 +14,38 @@ export function RewriteNode({
15
  selected,
16
  }: NodeProps<NodeData>) {
17
  return (
18
- <NodePopover nodeId={id}>
19
- <section
20
- className={classNames(styles.logicNode, {
21
- [styles.selectedNode]: selected,
22
- })}
23
- >
24
- <Handle
25
- id="c"
26
- type="source"
27
- position={Position.Left}
28
- isConnectable={isConnectable}
29
- className={styles.handle}
30
- style={LeftHandleStyle}
31
- ></Handle>
32
- <Handle
33
- type="source"
34
- position={Position.Right}
35
- isConnectable={isConnectable}
36
- className={styles.handle}
37
- style={RightHandleStyle}
38
- id="b"
39
- ></Handle>
40
 
41
- <NodeHeader
42
- id={id}
43
- name={data.name}
44
- label={data.label}
45
- className={styles.nodeHeader}
46
- ></NodeHeader>
47
 
48
- <div className={styles.nodeText}>
49
- <LLMLabel value={get(data, 'form.llm_id')}></LLMLabel>
50
- </div>
51
- </section>
52
- </NodePopover>
53
  );
54
  }
 
6
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
7
  import styles from './index.less';
8
  import NodeHeader from './node-header';
 
9
 
10
  export function RewriteNode({
11
  id,
 
14
  selected,
15
  }: NodeProps<NodeData>) {
16
  return (
17
+ <section
18
+ className={classNames(styles.logicNode, {
19
+ [styles.selectedNode]: selected,
20
+ })}
21
+ >
22
+ <Handle
23
+ id="c"
24
+ type="source"
25
+ position={Position.Left}
26
+ isConnectable={isConnectable}
27
+ className={styles.handle}
28
+ style={LeftHandleStyle}
29
+ ></Handle>
30
+ <Handle
31
+ type="source"
32
+ position={Position.Right}
33
+ isConnectable={isConnectable}
34
+ className={styles.handle}
35
+ style={RightHandleStyle}
36
+ id="b"
37
+ ></Handle>
 
38
 
39
+ <NodeHeader
40
+ id={id}
41
+ name={data.name}
42
+ label={data.label}
43
+ className={styles.nodeHeader}
44
+ ></NodeHeader>
45
 
46
+ <div className={styles.nodeText}>
47
+ <LLMLabel value={get(data, 'form.llm_id')}></LLMLabel>
48
+ </div>
49
+ </section>
 
50
  );
51
  }
web/src/pages/flow/canvas/node/switch-node.tsx CHANGED
@@ -7,7 +7,6 @@ import { RightHandleStyle } from './handle-icon';
7
  import { useBuildSwitchHandlePositions } from './hooks';
8
  import styles from './index.less';
9
  import NodeHeader from './node-header';
10
- import NodePopover from './popover';
11
 
12
  const getConditionKey = (idx: number, length: number) => {
13
  if (idx === 0 && length !== 1) {
@@ -58,55 +57,53 @@ export function SwitchNode({ id, data, selected }: NodeProps<NodeData>) {
58
  const { positions } = useBuildSwitchHandlePositions({ data, id });
59
 
60
  return (
61
- <NodePopover nodeId={id}>
62
- <section
63
- className={classNames(styles.logicNode, {
64
- [styles.selectedNode]: selected,
65
- })}
66
- >
67
- <Handle
68
- type="target"
69
- position={Position.Left}
70
- isConnectable
71
- className={styles.handle}
72
- id={'a'}
73
- ></Handle>
74
- <NodeHeader
75
- id={id}
76
- name={data.name}
77
- label={data.label}
78
- className={styles.nodeHeader}
79
- ></NodeHeader>
80
- <Flex vertical gap={10}>
81
- {positions.map((position, idx) => {
82
- return (
83
- <div key={idx}>
84
- <Flex vertical>
85
- <Flex justify={'space-between'}>
86
- <span>{idx < positions.length - 1 && position.text}</span>
87
- <span>{getConditionKey(idx, positions.length)}</span>
88
- </Flex>
89
- {position.condition && (
90
- <ConditionBlock
91
- nodeId={id}
92
- condition={position.condition}
93
- ></ConditionBlock>
94
- )}
95
  </Flex>
96
- <Handle
97
- key={position.text}
98
- id={position.text}
99
- type="source"
100
- position={Position.Right}
101
- isConnectable
102
- className={styles.handle}
103
- style={{ ...RightHandleStyle, top: position.top }}
104
- ></Handle>
105
- </div>
106
- );
107
- })}
108
- </Flex>
109
- </section>
110
- </NodePopover>
 
 
 
 
 
 
111
  );
112
  }
 
7
  import { useBuildSwitchHandlePositions } from './hooks';
8
  import styles from './index.less';
9
  import NodeHeader from './node-header';
 
10
 
11
  const getConditionKey = (idx: number, length: number) => {
12
  if (idx === 0 && length !== 1) {
 
57
  const { positions } = useBuildSwitchHandlePositions({ data, id });
58
 
59
  return (
60
+ <section
61
+ className={classNames(styles.logicNode, {
62
+ [styles.selectedNode]: selected,
63
+ })}
64
+ >
65
+ <Handle
66
+ type="target"
67
+ position={Position.Left}
68
+ isConnectable
69
+ className={styles.handle}
70
+ id={'a'}
71
+ ></Handle>
72
+ <NodeHeader
73
+ id={id}
74
+ name={data.name}
75
+ label={data.label}
76
+ className={styles.nodeHeader}
77
+ ></NodeHeader>
78
+ <Flex vertical gap={10}>
79
+ {positions.map((position, idx) => {
80
+ return (
81
+ <div key={idx}>
82
+ <Flex vertical>
83
+ <Flex justify={'space-between'}>
84
+ <span>{idx < positions.length - 1 && position.text}</span>
85
+ <span>{getConditionKey(idx, positions.length)}</span>
 
 
 
 
 
 
 
 
86
  </Flex>
87
+ {position.condition && (
88
+ <ConditionBlock
89
+ nodeId={id}
90
+ condition={position.condition}
91
+ ></ConditionBlock>
92
+ )}
93
+ </Flex>
94
+ <Handle
95
+ key={position.text}
96
+ id={position.text}
97
+ type="source"
98
+ position={Position.Right}
99
+ isConnectable
100
+ className={styles.handle}
101
+ style={{ ...RightHandleStyle, top: position.top }}
102
+ ></Handle>
103
+ </div>
104
+ );
105
+ })}
106
+ </Flex>
107
+ </section>
108
  );
109
  }
web/src/pages/flow/hooks.ts CHANGED
@@ -524,7 +524,10 @@ export const useReplaceIdWithText = (output: unknown) => {
524
  return getNode(id)?.data.name;
525
  };
526
 
527
- return replaceIdWithText(output, getNameById);
 
 
 
528
  };
529
 
530
  /**
 
524
  return getNode(id)?.data.name;
525
  };
526
 
527
+ return {
528
+ replacedOutput: replaceIdWithText(output, getNameById),
529
+ getNameById,
530
+ };
531
  };
532
 
533
  /**