### What problem does this PR solve? feat: Add InvokeNode #1908 ### Type of change - [ ] Bug Fix (non-breaking change which fixes an issue) - [x] New Feature (non-breaking change which adds functionality)tags/v0.13.0
| if (editable) { | if (editable) { | ||||
| childNode = editing ? ( | childNode = editing ? ( | ||||
| <Form.Item | <Form.Item | ||||
| style={{ margin: 0, width: 100 }} | |||||
| style={{ margin: 0, width: 70 }} | |||||
| name={dataIndex} | name={dataIndex} | ||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| // style={{ paddingRight: 24 }} | // style={{ paddingRight: 24 }} | ||||
| onClick={toggleEdit} | onClick={toggleEdit} | ||||
| > | > | ||||
| <Text ellipsis={{ tooltip: children }} style={{ width: 100 }}> | |||||
| <Text ellipsis={{ tooltip: children }} style={{ width: 70 }}> | |||||
| {children} | {children} | ||||
| </Text> | </Text> | ||||
| </div> | </div> |
| method: 'Method', | method: 'Method', | ||||
| timeout: 'Timeout', | timeout: 'Timeout', | ||||
| headers: 'Headers', | headers: 'Headers', | ||||
| cleanHtml: 'Clean html', | |||||
| }, | }, | ||||
| footer: { | footer: { | ||||
| profile: 'All rights reserved @ React', | profile: 'All rights reserved @ React', |
| method: '方法', | method: '方法', | ||||
| timeout: '超時', | timeout: '超時', | ||||
| headers: '請求頭', | headers: '請求頭', | ||||
| cleanHtml: '清除 html', | |||||
| }, | }, | ||||
| footer: { | footer: { | ||||
| profile: '“保留所有權利 @ react”', | profile: '“保留所有權利 @ react”', |
| method: '方法', | method: '方法', | ||||
| timeout: '超时', | timeout: '超时', | ||||
| headers: '请求头', | headers: '请求头', | ||||
| cleanHtml: '清除 html', | |||||
| }, | }, | ||||
| footer: { | footer: { | ||||
| profile: 'All rights reserved @ React', | profile: 'All rights reserved @ React', |
| import { BeginNode } from './node/begin-node'; | import { BeginNode } from './node/begin-node'; | ||||
| import { CategorizeNode } from './node/categorize-node'; | import { CategorizeNode } from './node/categorize-node'; | ||||
| import { GenerateNode } from './node/generate-node'; | import { GenerateNode } from './node/generate-node'; | ||||
| import { InvokeNode } from './node/invoke-node'; | |||||
| import { KeywordNode } from './node/keyword-node'; | import { KeywordNode } from './node/keyword-node'; | ||||
| import { LogicNode } from './node/logic-node'; | import { LogicNode } from './node/logic-node'; | ||||
| import { MessageNode } from './node/message-node'; | import { MessageNode } from './node/message-node'; | ||||
| messageNode: MessageNode, | messageNode: MessageNode, | ||||
| rewriteNode: RewriteNode, | rewriteNode: RewriteNode, | ||||
| keywordNode: KeywordNode, | keywordNode: KeywordNode, | ||||
| invokeNode: InvokeNode, | |||||
| }; | }; | ||||
| const edgeTypes = { | const edgeTypes = { |
| import { Flex } from 'antd'; | |||||
| import classNames from 'classnames'; | |||||
| import { get } from 'lodash'; | |||||
| import { useTranslation } from 'react-i18next'; | |||||
| import { Handle, NodeProps, Position } from 'reactflow'; | |||||
| import { NodeData } from '../../interface'; | |||||
| import { LeftHandleStyle, RightHandleStyle } from './handle-icon'; | |||||
| import styles from './index.less'; | |||||
| import NodeHeader from './node-header'; | |||||
| import NodePopover from './popover'; | |||||
| export function InvokeNode({ | |||||
| id, | |||||
| data, | |||||
| isConnectable = true, | |||||
| selected, | |||||
| }: NodeProps<NodeData>) { | |||||
| const { t } = useTranslation(); | |||||
| const url = get(data, 'form.url'); | |||||
| return ( | |||||
| <NodePopover nodeId={id}> | |||||
| <section | |||||
| className={classNames(styles.ragNode, { | |||||
| [styles.selectedNode]: selected, | |||||
| })} | |||||
| > | |||||
| <Handle | |||||
| id="c" | |||||
| type="source" | |||||
| position={Position.Left} | |||||
| isConnectable={isConnectable} | |||||
| className={styles.handle} | |||||
| style={LeftHandleStyle} | |||||
| ></Handle> | |||||
| <Handle | |||||
| type="source" | |||||
| position={Position.Right} | |||||
| isConnectable={isConnectable} | |||||
| className={styles.handle} | |||||
| id="b" | |||||
| style={RightHandleStyle} | |||||
| ></Handle> | |||||
| <NodeHeader | |||||
| id={id} | |||||
| name={data.name} | |||||
| label={data.label} | |||||
| className={styles.nodeHeader} | |||||
| ></NodeHeader> | |||||
| <Flex vertical> | |||||
| <div>{t('flow.url')}</div> | |||||
| <div className={styles.nodeText}>{url}</div> | |||||
| </Flex> | |||||
| </section> | |||||
| </NodePopover> | |||||
| ); | |||||
| } |
| "Connection": "keep-alive" | "Connection": "keep-alive" | ||||
| }`, | }`, | ||||
| proxy: 'http://', | proxy: 'http://', | ||||
| clean_html: false, | |||||
| }; | }; | ||||
| export const CategorizeAnchorPointPositions = [ | export const CategorizeAnchorPointPositions = [ | ||||
| [Operator.TuShare]: 'ragNode', | [Operator.TuShare]: 'ragNode', | ||||
| [Operator.Note]: 'noteNode', | [Operator.Note]: 'noteNode', | ||||
| [Operator.Crawler]: 'ragNode', | [Operator.Crawler]: 'ragNode', | ||||
| [Operator.Invoke]: 'ragNode', | |||||
| [Operator.Invoke]: 'invokeNode', | |||||
| }; | }; | ||||
| export const LanguageOptions = [ | export const LanguageOptions = [ |
| [Operator.TuShare]: TuShareForm, | [Operator.TuShare]: TuShareForm, | ||||
| [Operator.Crawler]: CrawlerForm, | [Operator.Crawler]: CrawlerForm, | ||||
| [Operator.Invoke]: InvokeForm, | [Operator.Invoke]: InvokeForm, | ||||
| [Operator.Concentrator]: <></>, | |||||
| [Operator.Note]: <></>, | |||||
| [Operator.Concentrator]: () => <></>, | |||||
| [Operator.Note]: () => <></>, | |||||
| }; | }; | ||||
| const EmptyContent = () => <div></div>; | const EmptyContent = () => <div></div>; | ||||
| open={visible} | open={visible} | ||||
| getContainer={false} | getContainer={false} | ||||
| mask={false} | mask={false} | ||||
| width={470} | |||||
| width={500} | |||||
| closeIcon={null} | closeIcon={null} | ||||
| > | > | ||||
| <section className={styles.formWrapper}> | <section className={styles.formWrapper}> |
| title: t('key'), | title: t('key'), | ||||
| dataIndex: 'key', | dataIndex: 'key', | ||||
| key: 'key', | key: 'key', | ||||
| // width: 40, | |||||
| onCell: (record: IInvokeVariable) => ({ | onCell: (record: IInvokeVariable) => ({ | ||||
| record, | record, | ||||
| editable: true, | editable: true, |
| import Editor from '@monaco-editor/react'; | import Editor from '@monaco-editor/react'; | ||||
| import { Form, Input, InputNumber, Select, Space } from 'antd'; | |||||
| import { Form, Input, InputNumber, Select, Space, Switch } from 'antd'; | |||||
| import { useTranslation } from 'react-i18next'; | import { useTranslation } from 'react-i18next'; | ||||
| import { useSetLlmSetting } from '../../hooks'; | import { useSetLlmSetting } from '../../hooks'; | ||||
| import { IOperatorForm } from '../../interface'; | import { IOperatorForm } from '../../interface'; | ||||
| <Form.Item name={'proxy'} label={t('flow.proxy')}> | <Form.Item name={'proxy'} label={t('flow.proxy')}> | ||||
| <Input /> | <Input /> | ||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item name={'clean_html'} label={t('flow.cleanHtml')}> | |||||
| <Switch /> | |||||
| </Form.Item> | |||||
| <DynamicVariables nodeId={node?.id}></DynamicVariables> | <DynamicVariables nodeId={node?.id}></DynamicVariables> | ||||
| </Form> | </Form> | ||||
| </> | </> |