feat: Update Switch form data #1739 (#2029)

### 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:
balibabu 2024-08-21 12:47:24 +08:00 committed by GitHub
parent 96438ca821
commit c9d7a34690
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 74 additions and 42 deletions

View File

@ -1,6 +1,6 @@
import { Handle, Position } from 'reactflow';
// import { v4 as uuid } from 'uuid';
import React from 'react';
import styles from './index.less';
const DEFAULT_HANDLE_STYLE = {
@ -10,20 +10,19 @@ const DEFAULT_HANDLE_STYLE = {
fontSize: 8,
};
interface IProps {
interface IProps extends React.PropsWithChildren {
top: number;
right: number;
text: string;
id: string;
idx?: number;
}
const CategorizeHandle = ({ top, right, text, idx }: IProps) => {
const CategorizeHandle = ({ top, right, id, children }: IProps) => {
return (
<Handle
type="source"
position={Position.Right}
// id={`CategorizeHandle${idx}`}
id={text}
id={id}
isConnectable
style={{
...DEFAULT_HANDLE_STYLE,
@ -33,7 +32,7 @@ const CategorizeHandle = ({ top, right, text, idx }: IProps) => {
color: 'black',
}}
>
<span className={styles.categorizeAnchorPointText}>{text}</span>
<span className={styles.categorizeAnchorPointText}>{children || id}</span>
</Handle>
);
};

View File

@ -3,7 +3,7 @@ import { Flex } from 'antd';
import classNames from 'classnames';
import lowerFirst from 'lodash/lowerFirst';
import { Handle, NodeProps, Position } from 'reactflow';
import { Operator, operatorMap } from '../../constant';
import { Operator, SwitchElseTo, operatorMap } from '../../constant';
import { NodeData } from '../../interface';
import OperatorIcon from '../../operator-icon';
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 { t } = useTranslate('flow');
const { positions } = useBuildCategorizeHandlePositions({ data, id });
const operatorName = data.label;
return (
<NodePopover nodeId={id}>
@ -49,13 +50,18 @@ export function CategorizeNode({ id, data, selected }: NodeProps<NodeData>) {
className={styles.handle}
id={'c'}
></Handle>
{operatorName === Operator.Switch && (
<CategorizeHandle top={50} right={-4} id={SwitchElseTo}>
To
</CategorizeHandle>
)}
{positions.map((position, idx) => {
return (
<CategorizeHandle
top={position.top}
right={position.right}
key={idx}
text={position.text}
id={position.text}
idx={idx}
></CategorizeHandle>
);

View File

@ -2633,3 +2633,5 @@ export const ExeSQLOptions = ['mysql', 'postgresql', 'mariadb'].map((x) => ({
label: upperFirst(x),
value: x,
}));
export const SwitchElseTo = 'end_cpn_id';

View File

@ -30,6 +30,7 @@ import {
NodeMap,
Operator,
RestrictedUpstreamMap,
SwitchElseTo,
initialArXivValues,
initialBaiduFanyiValues,
initialBaiduValues,
@ -519,6 +520,17 @@ export const useWatchNodeFormDataChange = () => {
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],

View File

@ -21,7 +21,7 @@ import {
import { create } from 'zustand';
import { devtools } from 'zustand/middleware';
import { immer } from 'zustand/middleware/immer';
import { Operator } from './constant';
import { Operator, SwitchElseTo } from './constant';
import { NodeData } from './interface';
import { getOperatorIndex, isEdgeEqual } from './utils';
@ -37,13 +37,22 @@ export type RFState = {
setNodes: (nodes: Node[]) => void;
setEdges: (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;
addNode: (nodes: Node) => void;
getNode: (id?: string | null) => Node<NodeData> | undefined;
addEdge: (connection: Connection) => void;
getEdge: (id: string) => Edge | undefined;
updateFormDataOnConnect: (connection: Connection) => void;
updateSwitchFormData: (
source: string,
sourceHandle?: string | null,
target?: string | null,
) => void;
deletePreviousEdgeOfClassificationNode: (connection: Connection) => void;
duplicateNode: (id: string) => void;
deleteEdge: () => void;
@ -132,8 +141,6 @@ const useGraphStore = create<RFState>()(
if (isDifferent) {
// other operator's edges
const irrelevantEdges = edges.filter((x) => x.source !== nodeId);
// the abandoned edges
const selfAbandonedEdges = [];
// the added downstream edges
const selfAddedDownstreamEdges = differenceWith(
currentDownstreamEdges,
@ -168,7 +175,8 @@ const useGraphStore = create<RFState>()(
return get().edges.find((x) => x.id === id);
},
updateFormDataOnConnect: (connection: Connection) => {
const { getOperatorTypeFromId, updateNodeForm } = get();
const { getOperatorTypeFromId, updateNodeForm, updateSwitchFormData } =
get();
const { source, target, sourceHandle } = connection;
const operatorType = getOperatorTypeFromId(source);
if (source) {
@ -185,16 +193,7 @@ const useGraphStore = create<RFState>()(
]);
break;
case Operator.Switch: {
if (sourceHandle) {
const operatorIndex = getOperatorIndex(sourceHandle);
if (operatorIndex) {
updateNodeForm(source, target, [
'conditions',
operatorIndex,
'to',
]);
}
}
updateSwitchFormData(source, sourceHandle, target);
break;
}
default:
@ -253,7 +252,12 @@ const useGraphStore = create<RFState>()(
});
},
deleteEdgeById: (id: string) => {
const { edges, updateNodeForm, getOperatorTypeFromId } = get();
const {
edges,
updateNodeForm,
getOperatorTypeFromId,
updateSwitchFormData,
} = get();
const currentEdge = edges.find((x) => x.id === id);
if (currentEdge) {
@ -275,16 +279,7 @@ const useGraphStore = create<RFState>()(
]);
break;
case Operator.Switch: {
if (sourceHandle) {
const operatorIndex = getOperatorIndex(sourceHandle);
if (operatorIndex) {
updateNodeForm(source, undefined, [
'conditions',
operatorIndex,
'to',
]);
}
}
updateSwitchFormData(source, sourceHandle, undefined);
break;
}
default:
@ -320,7 +315,11 @@ const useGraphStore = create<RFState>()(
findNodeByName: (name: Operator) => {
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({
nodes: get().nodes.map((node) => {
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) => {
const { nodes } = get();
const idx = nodes.findIndex((x) => x.id === id);

View File

@ -1,7 +1,7 @@
import { CloseOutlined } from '@ant-design/icons';
import { Button, Card, Form, Input, Select, Typography } from 'antd';
import { useTranslation } from 'react-i18next';
import { Operator } from '../constant';
import { Operator, SwitchElseTo } from '../constant';
import { useBuildFormSelectOptions } from '../form-hooks';
import { IOperatorForm, ISwitchForm } from '../interface';
import { getOtherFieldValues } from '../utils';
@ -38,15 +38,12 @@ const SwitchForm = ({ onValuesChange, node, form }: IOperatorForm) => {
initialValues={{ conditions: [{}] }}
onValuesChange={onValuesChange}
>
<Form.Item label={t('flow.to')} name={['end_cpn_id']}>
<Form.Item label={t('flow.to')} name={[SwitchElseTo]}>
<Select
allowClear
options={buildCategorizeToOptions(getSelectedConditionTos())}
/>
</Form.Item>
<Form.Item label={t('flow.no')} name={['no']}>
<Input />
</Form.Item>
<Form.List name="conditions">
{(fields, { add, remove }) => (
<div style={{ display: 'flex', rowGap: 16, flexDirection: 'column' }}>
@ -74,7 +71,7 @@ const SwitchForm = ({ onValuesChange, node, form }: IOperatorForm) => {
<Select
allowClear
options={buildCategorizeToOptions([
form?.getFieldValue('end_cpn_id'),
form?.getFieldValue(SwitchElseTo),
...getOtherFieldValues(form!, 'conditions', field, 'to'),
])}
/>