mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-08-14 04:26:05 +08:00
### What problem does this PR solve? feat: Update Switch form data #1739 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
parent
96438ca821
commit
c9d7a34690
@ -1,6 +1,6 @@
|
|||||||
import { Handle, Position } from 'reactflow';
|
import { Handle, Position } from 'reactflow';
|
||||||
// import { v4 as uuid } from 'uuid';
|
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
const DEFAULT_HANDLE_STYLE = {
|
const DEFAULT_HANDLE_STYLE = {
|
||||||
@ -10,20 +10,19 @@ const DEFAULT_HANDLE_STYLE = {
|
|||||||
fontSize: 8,
|
fontSize: 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
interface IProps {
|
interface IProps extends React.PropsWithChildren {
|
||||||
top: number;
|
top: number;
|
||||||
right: number;
|
right: number;
|
||||||
text: string;
|
id: string;
|
||||||
idx?: number;
|
idx?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CategorizeHandle = ({ top, right, text, idx }: IProps) => {
|
const CategorizeHandle = ({ top, right, id, children }: IProps) => {
|
||||||
return (
|
return (
|
||||||
<Handle
|
<Handle
|
||||||
type="source"
|
type="source"
|
||||||
position={Position.Right}
|
position={Position.Right}
|
||||||
// id={`CategorizeHandle${idx}`}
|
id={id}
|
||||||
id={text}
|
|
||||||
isConnectable
|
isConnectable
|
||||||
style={{
|
style={{
|
||||||
...DEFAULT_HANDLE_STYLE,
|
...DEFAULT_HANDLE_STYLE,
|
||||||
@ -33,7 +32,7 @@ const CategorizeHandle = ({ top, right, text, idx }: IProps) => {
|
|||||||
color: 'black',
|
color: 'black',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className={styles.categorizeAnchorPointText}>{text}</span>
|
<span className={styles.categorizeAnchorPointText}>{children || id}</span>
|
||||||
</Handle>
|
</Handle>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,7 @@ import { Flex } from 'antd';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import lowerFirst from 'lodash/lowerFirst';
|
import lowerFirst from 'lodash/lowerFirst';
|
||||||
import { Handle, NodeProps, Position } from 'reactflow';
|
import { Handle, NodeProps, Position } from 'reactflow';
|
||||||
import { Operator, operatorMap } from '../../constant';
|
import { Operator, SwitchElseTo, operatorMap } from '../../constant';
|
||||||
import { NodeData } from '../../interface';
|
import { NodeData } from '../../interface';
|
||||||
import OperatorIcon from '../../operator-icon';
|
import OperatorIcon from '../../operator-icon';
|
||||||
import CategorizeHandle from './categorize-handle';
|
import CategorizeHandle from './categorize-handle';
|
||||||
@ -16,6 +16,7 @@ export function CategorizeNode({ id, data, selected }: NodeProps<NodeData>) {
|
|||||||
const style = operatorMap[data.label as Operator];
|
const style = operatorMap[data.label as Operator];
|
||||||
const { t } = useTranslate('flow');
|
const { t } = useTranslate('flow');
|
||||||
const { positions } = useBuildCategorizeHandlePositions({ data, id });
|
const { positions } = useBuildCategorizeHandlePositions({ data, id });
|
||||||
|
const operatorName = data.label;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodePopover nodeId={id}>
|
<NodePopover nodeId={id}>
|
||||||
@ -49,13 +50,18 @@ export function CategorizeNode({ id, data, selected }: NodeProps<NodeData>) {
|
|||||||
className={styles.handle}
|
className={styles.handle}
|
||||||
id={'c'}
|
id={'c'}
|
||||||
></Handle>
|
></Handle>
|
||||||
|
{operatorName === Operator.Switch && (
|
||||||
|
<CategorizeHandle top={50} right={-4} id={SwitchElseTo}>
|
||||||
|
To
|
||||||
|
</CategorizeHandle>
|
||||||
|
)}
|
||||||
{positions.map((position, idx) => {
|
{positions.map((position, idx) => {
|
||||||
return (
|
return (
|
||||||
<CategorizeHandle
|
<CategorizeHandle
|
||||||
top={position.top}
|
top={position.top}
|
||||||
right={position.right}
|
right={position.right}
|
||||||
key={idx}
|
key={idx}
|
||||||
text={position.text}
|
id={position.text}
|
||||||
idx={idx}
|
idx={idx}
|
||||||
></CategorizeHandle>
|
></CategorizeHandle>
|
||||||
);
|
);
|
||||||
|
@ -2633,3 +2633,5 @@ export const ExeSQLOptions = ['mysql', 'postgresql', 'mariadb'].map((x) => ({
|
|||||||
label: upperFirst(x),
|
label: upperFirst(x),
|
||||||
value: x,
|
value: x,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
export const SwitchElseTo = 'end_cpn_id';
|
||||||
|
@ -30,6 +30,7 @@ import {
|
|||||||
NodeMap,
|
NodeMap,
|
||||||
Operator,
|
Operator,
|
||||||
RestrictedUpstreamMap,
|
RestrictedUpstreamMap,
|
||||||
|
SwitchElseTo,
|
||||||
initialArXivValues,
|
initialArXivValues,
|
||||||
initialBaiduFanyiValues,
|
initialBaiduFanyiValues,
|
||||||
initialBaiduValues,
|
initialBaiduValues,
|
||||||
@ -519,6 +520,17 @@ export const useWatchNodeFormDataChange = () => {
|
|||||||
return pre;
|
return pre;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// Splice the else condition of the conditional judgment to the edge list
|
||||||
|
const elseTo = form[SwitchElseTo];
|
||||||
|
if (elseTo) {
|
||||||
|
downstreamEdges.push({
|
||||||
|
id: uuid(),
|
||||||
|
source: nodeId,
|
||||||
|
target: elseTo,
|
||||||
|
sourceHandle: SwitchElseTo,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setEdgesByNodeId(nodeId, downstreamEdges);
|
setEdgesByNodeId(nodeId, downstreamEdges);
|
||||||
},
|
},
|
||||||
[setEdgesByNodeId],
|
[setEdgesByNodeId],
|
||||||
|
@ -21,7 +21,7 @@ import {
|
|||||||
import { create } from 'zustand';
|
import { create } from 'zustand';
|
||||||
import { devtools } from 'zustand/middleware';
|
import { devtools } from 'zustand/middleware';
|
||||||
import { immer } from 'zustand/middleware/immer';
|
import { immer } from 'zustand/middleware/immer';
|
||||||
import { Operator } from './constant';
|
import { Operator, SwitchElseTo } from './constant';
|
||||||
import { NodeData } from './interface';
|
import { NodeData } from './interface';
|
||||||
import { getOperatorIndex, isEdgeEqual } from './utils';
|
import { getOperatorIndex, isEdgeEqual } from './utils';
|
||||||
|
|
||||||
@ -37,13 +37,22 @@ export type RFState = {
|
|||||||
setNodes: (nodes: Node[]) => void;
|
setNodes: (nodes: Node[]) => void;
|
||||||
setEdges: (edges: Edge[]) => void;
|
setEdges: (edges: Edge[]) => void;
|
||||||
setEdgesByNodeId: (nodeId: string, edges: Edge[]) => void;
|
setEdgesByNodeId: (nodeId: string, edges: Edge[]) => void;
|
||||||
updateNodeForm: (nodeId: string, values: any, path?: string[]) => void;
|
updateNodeForm: (
|
||||||
|
nodeId: string,
|
||||||
|
values: any,
|
||||||
|
path?: (string | number)[],
|
||||||
|
) => void;
|
||||||
onSelectionChange: OnSelectionChangeFunc;
|
onSelectionChange: OnSelectionChangeFunc;
|
||||||
addNode: (nodes: Node) => void;
|
addNode: (nodes: Node) => void;
|
||||||
getNode: (id?: string | null) => Node<NodeData> | undefined;
|
getNode: (id?: string | null) => Node<NodeData> | undefined;
|
||||||
addEdge: (connection: Connection) => void;
|
addEdge: (connection: Connection) => void;
|
||||||
getEdge: (id: string) => Edge | undefined;
|
getEdge: (id: string) => Edge | undefined;
|
||||||
updateFormDataOnConnect: (connection: Connection) => void;
|
updateFormDataOnConnect: (connection: Connection) => void;
|
||||||
|
updateSwitchFormData: (
|
||||||
|
source: string,
|
||||||
|
sourceHandle?: string | null,
|
||||||
|
target?: string | null,
|
||||||
|
) => void;
|
||||||
deletePreviousEdgeOfClassificationNode: (connection: Connection) => void;
|
deletePreviousEdgeOfClassificationNode: (connection: Connection) => void;
|
||||||
duplicateNode: (id: string) => void;
|
duplicateNode: (id: string) => void;
|
||||||
deleteEdge: () => void;
|
deleteEdge: () => void;
|
||||||
@ -132,8 +141,6 @@ const useGraphStore = create<RFState>()(
|
|||||||
if (isDifferent) {
|
if (isDifferent) {
|
||||||
// other operator's edges
|
// other operator's edges
|
||||||
const irrelevantEdges = edges.filter((x) => x.source !== nodeId);
|
const irrelevantEdges = edges.filter((x) => x.source !== nodeId);
|
||||||
// the abandoned edges
|
|
||||||
const selfAbandonedEdges = [];
|
|
||||||
// the added downstream edges
|
// the added downstream edges
|
||||||
const selfAddedDownstreamEdges = differenceWith(
|
const selfAddedDownstreamEdges = differenceWith(
|
||||||
currentDownstreamEdges,
|
currentDownstreamEdges,
|
||||||
@ -168,7 +175,8 @@ const useGraphStore = create<RFState>()(
|
|||||||
return get().edges.find((x) => x.id === id);
|
return get().edges.find((x) => x.id === id);
|
||||||
},
|
},
|
||||||
updateFormDataOnConnect: (connection: Connection) => {
|
updateFormDataOnConnect: (connection: Connection) => {
|
||||||
const { getOperatorTypeFromId, updateNodeForm } = get();
|
const { getOperatorTypeFromId, updateNodeForm, updateSwitchFormData } =
|
||||||
|
get();
|
||||||
const { source, target, sourceHandle } = connection;
|
const { source, target, sourceHandle } = connection;
|
||||||
const operatorType = getOperatorTypeFromId(source);
|
const operatorType = getOperatorTypeFromId(source);
|
||||||
if (source) {
|
if (source) {
|
||||||
@ -185,16 +193,7 @@ const useGraphStore = create<RFState>()(
|
|||||||
]);
|
]);
|
||||||
break;
|
break;
|
||||||
case Operator.Switch: {
|
case Operator.Switch: {
|
||||||
if (sourceHandle) {
|
updateSwitchFormData(source, sourceHandle, target);
|
||||||
const operatorIndex = getOperatorIndex(sourceHandle);
|
|
||||||
if (operatorIndex) {
|
|
||||||
updateNodeForm(source, target, [
|
|
||||||
'conditions',
|
|
||||||
operatorIndex,
|
|
||||||
'to',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -253,7 +252,12 @@ const useGraphStore = create<RFState>()(
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
deleteEdgeById: (id: string) => {
|
deleteEdgeById: (id: string) => {
|
||||||
const { edges, updateNodeForm, getOperatorTypeFromId } = get();
|
const {
|
||||||
|
edges,
|
||||||
|
updateNodeForm,
|
||||||
|
getOperatorTypeFromId,
|
||||||
|
updateSwitchFormData,
|
||||||
|
} = get();
|
||||||
const currentEdge = edges.find((x) => x.id === id);
|
const currentEdge = edges.find((x) => x.id === id);
|
||||||
|
|
||||||
if (currentEdge) {
|
if (currentEdge) {
|
||||||
@ -275,16 +279,7 @@ const useGraphStore = create<RFState>()(
|
|||||||
]);
|
]);
|
||||||
break;
|
break;
|
||||||
case Operator.Switch: {
|
case Operator.Switch: {
|
||||||
if (sourceHandle) {
|
updateSwitchFormData(source, sourceHandle, undefined);
|
||||||
const operatorIndex = getOperatorIndex(sourceHandle);
|
|
||||||
if (operatorIndex) {
|
|
||||||
updateNodeForm(source, undefined, [
|
|
||||||
'conditions',
|
|
||||||
operatorIndex,
|
|
||||||
'to',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -320,7 +315,11 @@ const useGraphStore = create<RFState>()(
|
|||||||
findNodeByName: (name: Operator) => {
|
findNodeByName: (name: Operator) => {
|
||||||
return get().nodes.find((x) => x.data.label === name);
|
return get().nodes.find((x) => x.data.label === name);
|
||||||
},
|
},
|
||||||
updateNodeForm: (nodeId: string, values: any, path: string[] = []) => {
|
updateNodeForm: (
|
||||||
|
nodeId: string,
|
||||||
|
values: any,
|
||||||
|
path: (string | number)[] = [],
|
||||||
|
) => {
|
||||||
set({
|
set({
|
||||||
nodes: get().nodes.map((node) => {
|
nodes: get().nodes.map((node) => {
|
||||||
if (node.id === nodeId) {
|
if (node.id === nodeId) {
|
||||||
@ -343,6 +342,23 @@ const useGraphStore = create<RFState>()(
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
updateSwitchFormData: (source, sourceHandle, target) => {
|
||||||
|
const { updateNodeForm } = get();
|
||||||
|
if (sourceHandle) {
|
||||||
|
if (sourceHandle === SwitchElseTo) {
|
||||||
|
updateNodeForm(source, target, [SwitchElseTo]);
|
||||||
|
} else {
|
||||||
|
const operatorIndex = getOperatorIndex(sourceHandle);
|
||||||
|
if (operatorIndex) {
|
||||||
|
updateNodeForm(source, target, [
|
||||||
|
'conditions',
|
||||||
|
Number(operatorIndex) - 1, // The index is the conditions form index
|
||||||
|
'to',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
updateMutableNodeFormItem: (id: string, field: string, value: any) => {
|
updateMutableNodeFormItem: (id: string, field: string, value: any) => {
|
||||||
const { nodes } = get();
|
const { nodes } = get();
|
||||||
const idx = nodes.findIndex((x) => x.id === id);
|
const idx = nodes.findIndex((x) => x.id === id);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { CloseOutlined } from '@ant-design/icons';
|
import { CloseOutlined } from '@ant-design/icons';
|
||||||
import { Button, Card, Form, Input, Select, Typography } from 'antd';
|
import { Button, Card, Form, Input, Select, Typography } from 'antd';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Operator } from '../constant';
|
import { Operator, SwitchElseTo } from '../constant';
|
||||||
import { useBuildFormSelectOptions } from '../form-hooks';
|
import { useBuildFormSelectOptions } from '../form-hooks';
|
||||||
import { IOperatorForm, ISwitchForm } from '../interface';
|
import { IOperatorForm, ISwitchForm } from '../interface';
|
||||||
import { getOtherFieldValues } from '../utils';
|
import { getOtherFieldValues } from '../utils';
|
||||||
@ -38,15 +38,12 @@ const SwitchForm = ({ onValuesChange, node, form }: IOperatorForm) => {
|
|||||||
initialValues={{ conditions: [{}] }}
|
initialValues={{ conditions: [{}] }}
|
||||||
onValuesChange={onValuesChange}
|
onValuesChange={onValuesChange}
|
||||||
>
|
>
|
||||||
<Form.Item label={t('flow.to')} name={['end_cpn_id']}>
|
<Form.Item label={t('flow.to')} name={[SwitchElseTo]}>
|
||||||
<Select
|
<Select
|
||||||
allowClear
|
allowClear
|
||||||
options={buildCategorizeToOptions(getSelectedConditionTos())}
|
options={buildCategorizeToOptions(getSelectedConditionTos())}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t('flow.no')} name={['no']}>
|
|
||||||
<Input />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.List name="conditions">
|
<Form.List name="conditions">
|
||||||
{(fields, { add, remove }) => (
|
{(fields, { add, remove }) => (
|
||||||
<div style={{ display: 'flex', rowGap: 16, flexDirection: 'column' }}>
|
<div style={{ display: 'flex', rowGap: 16, flexDirection: 'column' }}>
|
||||||
@ -74,7 +71,7 @@ const SwitchForm = ({ onValuesChange, node, form }: IOperatorForm) => {
|
|||||||
<Select
|
<Select
|
||||||
allowClear
|
allowClear
|
||||||
options={buildCategorizeToOptions([
|
options={buildCategorizeToOptions([
|
||||||
form?.getFieldValue('end_cpn_id'),
|
form?.getFieldValue(SwitchElseTo),
|
||||||
...getOtherFieldValues(form!, 'conditions', field, 'to'),
|
...getOtherFieldValues(form!, 'conditions', field, 'to'),
|
||||||
])}
|
])}
|
||||||
/>
|
/>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user