mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-05-30 18:15:52 +08:00
### What problem does this PR solve? feat: Build the positions of the Switch handle #1739 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
parent
6f438e0a49
commit
02985fc905
@ -1,11 +1,10 @@
|
|||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import intersectionWith from 'lodash/intersectionWith';
|
|
||||||
import isEqual from 'lodash/isEqual';
|
|
||||||
import pick from 'lodash/pick';
|
import pick from 'lodash/pick';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { useUpdateNodeInternals } from 'reactflow';
|
import { useUpdateNodeInternals } from 'reactflow';
|
||||||
|
import { Operator } from '../../constant';
|
||||||
import { IPosition, NodeData } from '../../interface';
|
import { IPosition, NodeData } from '../../interface';
|
||||||
import { buildNewPositionMap } from '../../utils';
|
import { buildNewPositionMap, isKeysEqual } from '../../utils';
|
||||||
|
|
||||||
export const useBuildCategorizeHandlePositions = ({
|
export const useBuildCategorizeHandlePositions = ({
|
||||||
data,
|
data,
|
||||||
@ -14,40 +13,41 @@ export const useBuildCategorizeHandlePositions = ({
|
|||||||
id: string;
|
id: string;
|
||||||
data: NodeData;
|
data: NodeData;
|
||||||
}) => {
|
}) => {
|
||||||
|
const operatorName = data.label as Operator;
|
||||||
const updateNodeInternals = useUpdateNodeInternals();
|
const updateNodeInternals = useUpdateNodeInternals();
|
||||||
const [positionMap, setPositionMap] = useState<Record<string, IPosition>>({});
|
const [positionMap, setPositionMap] = useState<Record<string, IPosition>>({});
|
||||||
const categoryData = useMemo(
|
|
||||||
() => get(data, 'form.category_description') ?? {},
|
const categoryData = useMemo(() => {
|
||||||
[data],
|
if (operatorName === Operator.Categorize) {
|
||||||
);
|
return get(data, `form.category_description`, {});
|
||||||
|
} else if (operatorName === Operator.Switch) {
|
||||||
|
return get(data, 'form.conditions', []);
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}, [data, operatorName]);
|
||||||
|
|
||||||
const positions = useMemo(() => {
|
const positions = useMemo(() => {
|
||||||
return Object.keys(categoryData)
|
return Object.keys(categoryData)
|
||||||
.map((x) => {
|
.map((x, idx) => {
|
||||||
const position = positionMap[x];
|
const position = positionMap[x];
|
||||||
return { text: x, ...position };
|
let text = x;
|
||||||
|
if (operatorName === Operator.Switch) {
|
||||||
|
text = `Item ${idx + 1}`;
|
||||||
|
}
|
||||||
|
return { text, ...position };
|
||||||
})
|
})
|
||||||
.filter((x) => typeof x?.right === 'number');
|
.filter((x) => typeof x?.right === 'number');
|
||||||
}, [categoryData, positionMap]);
|
}, [categoryData, positionMap, operatorName]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Cache used coordinates
|
// Cache used coordinates
|
||||||
setPositionMap((state) => {
|
setPositionMap((state) => {
|
||||||
// index in use
|
|
||||||
const indexesInUse = Object.values(state).map((x) => x.idx);
|
|
||||||
const categoryDataKeys = Object.keys(categoryData);
|
const categoryDataKeys = Object.keys(categoryData);
|
||||||
const stateKeys = Object.keys(state);
|
const stateKeys = Object.keys(state);
|
||||||
if (!isEqual(categoryDataKeys.sort(), stateKeys.sort())) {
|
if (!isKeysEqual(categoryDataKeys, stateKeys)) {
|
||||||
const intersectionKeys = intersectionWith(
|
const { newPositionMap, intersectionKeys } = buildNewPositionMap(
|
||||||
stateKeys,
|
|
||||||
categoryDataKeys,
|
categoryDataKeys,
|
||||||
(categoryDataKey, postionMapKey) => categoryDataKey === postionMapKey,
|
state,
|
||||||
);
|
|
||||||
const newPositionMap = buildNewPositionMap(
|
|
||||||
categoryDataKeys.filter(
|
|
||||||
(x) => !intersectionKeys.some((y) => y === x),
|
|
||||||
),
|
|
||||||
indexesInUse,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const nextPositionMap = {
|
const nextPositionMap = {
|
||||||
@ -68,10 +68,30 @@ export const useBuildCategorizeHandlePositions = ({
|
|||||||
return { positions };
|
return { positions };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useBuildSwitchHandlePositions = ({
|
// export const useBuildSwitchHandlePositions = ({
|
||||||
data,
|
// data,
|
||||||
id,
|
// id,
|
||||||
}: {
|
// }: {
|
||||||
id: string;
|
// id: string;
|
||||||
data: NodeData;
|
// data: NodeData;
|
||||||
}) => {};
|
// }) => {
|
||||||
|
// const [positionMap, setPositionMap] = useState<Record<string, IPosition>>({});
|
||||||
|
// const conditions = useMemo(() => get(data, 'form.conditions', []), [data]);
|
||||||
|
// const updateNodeInternals = useUpdateNodeInternals();
|
||||||
|
|
||||||
|
// const positions = useMemo(() => {
|
||||||
|
// return conditions
|
||||||
|
// .map((x, idx) => {
|
||||||
|
// const text = `Item ${idx}`;
|
||||||
|
// const position = positionMap[text];
|
||||||
|
// return { text: text, ...position };
|
||||||
|
// })
|
||||||
|
// .filter((x) => typeof x?.right === 'number');
|
||||||
|
// }, [conditions, positionMap]);
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// updateNodeInternals(id);
|
||||||
|
// }, [id, updateNodeInternals, positionMap]);
|
||||||
|
|
||||||
|
// return { positions };
|
||||||
|
// };
|
||||||
|
@ -87,7 +87,19 @@ export const operatorIconMap = {
|
|||||||
[Operator.Switch]: SwitchIcon,
|
[Operator.Switch]: SwitchIcon,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const operatorMap = {
|
export const operatorMap: Record<
|
||||||
|
Operator,
|
||||||
|
{
|
||||||
|
backgroundColor?: string;
|
||||||
|
color?: string;
|
||||||
|
width?: number;
|
||||||
|
height?: number;
|
||||||
|
fontSize?: number;
|
||||||
|
iconFontSize?: number;
|
||||||
|
iconWidth?: number;
|
||||||
|
moreIconColor?: number;
|
||||||
|
}
|
||||||
|
> = {
|
||||||
[Operator.Retrieval]: {
|
[Operator.Retrieval]: {
|
||||||
backgroundColor: '#cad6e0',
|
backgroundColor: '#cad6e0',
|
||||||
color: '#385974',
|
color: '#385974',
|
||||||
@ -388,7 +400,7 @@ export const initialExeSqlValues = {
|
|||||||
top_n: 30,
|
top_n: 30,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const initialSwitchValues = { conditions: [{}] };
|
export const initialSwitchValues = { conditions: [] };
|
||||||
|
|
||||||
export const CategorizeAnchorPointPositions = [
|
export const CategorizeAnchorPointPositions = [
|
||||||
{ top: 1, right: 34 },
|
{ top: 1, right: 34 },
|
||||||
|
@ -64,11 +64,34 @@ export interface IRelevantForm extends IGenerateForm {
|
|||||||
no: string;
|
no: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Condition {
|
||||||
|
items: Item[];
|
||||||
|
logical_operator: string;
|
||||||
|
to: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Item {
|
||||||
|
cpn_id: string;
|
||||||
|
operator: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ISwitchForm {
|
||||||
|
conditions: Condition[];
|
||||||
|
end_cpn_id: string;
|
||||||
|
no: string;
|
||||||
|
}
|
||||||
|
|
||||||
export type NodeData = {
|
export type NodeData = {
|
||||||
label: string; // operator type
|
label: string; // operator type
|
||||||
name: string; // operator name
|
name: string; // operator name
|
||||||
color: string;
|
color: string;
|
||||||
form: IBeginForm | IRetrievalForm | IGenerateForm | ICategorizeForm;
|
form:
|
||||||
|
| IBeginForm
|
||||||
|
| IRetrievalForm
|
||||||
|
| IGenerateForm
|
||||||
|
| ICategorizeForm
|
||||||
|
| ISwitchForm;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IPosition = { top: number; right: number; idx: number };
|
export type IPosition = { top: number; right: number; idx: number };
|
||||||
|
@ -184,6 +184,14 @@ const useGraphStore = create<RFState>()(
|
|||||||
'to',
|
'to',
|
||||||
]);
|
]);
|
||||||
break;
|
break;
|
||||||
|
// case Operator.Switch:
|
||||||
|
// if (sourceHandle)
|
||||||
|
// updateNodeForm(source, target, [
|
||||||
|
// 'conditions',
|
||||||
|
// sourceHandle,
|
||||||
|
// 'to',
|
||||||
|
// ]);
|
||||||
|
// break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { DSLComponents } from '@/interfaces/database/flow';
|
import { DSLComponents } from '@/interfaces/database/flow';
|
||||||
import { removeUselessFieldsFromValues } from '@/utils/form';
|
import { removeUselessFieldsFromValues } from '@/utils/form';
|
||||||
import { humanId } from 'human-id';
|
import { humanId } from 'human-id';
|
||||||
import { curry, sample } from 'lodash';
|
import { curry, intersectionWith, isEqual, sample } from 'lodash';
|
||||||
import pipe from 'lodash/fp/pipe';
|
import pipe from 'lodash/fp/pipe';
|
||||||
import isObject from 'lodash/isObject';
|
import isObject from 'lodash/isObject';
|
||||||
import { Edge, Node, Position } from 'reactflow';
|
import { Edge, Node, Position } from 'reactflow';
|
||||||
@ -172,10 +172,24 @@ export const isEdgeEqual = (previous: Edge, current: Edge) =>
|
|||||||
previous.sourceHandle === current.sourceHandle;
|
previous.sourceHandle === current.sourceHandle;
|
||||||
|
|
||||||
export const buildNewPositionMap = (
|
export const buildNewPositionMap = (
|
||||||
categoryDataKeys: string[],
|
currentKeys: string[],
|
||||||
indexesInUse: number[],
|
previousPositionMap: Record<string, IPosition>,
|
||||||
) => {
|
) => {
|
||||||
return categoryDataKeys.reduce<Record<string, IPosition>>((pre, cur) => {
|
// index in use
|
||||||
|
const indexesInUse = Object.values(previousPositionMap).map((x) => x.idx);
|
||||||
|
const previousKeys = Object.keys(previousPositionMap);
|
||||||
|
const intersectionKeys = intersectionWith(
|
||||||
|
previousKeys,
|
||||||
|
currentKeys,
|
||||||
|
(categoryDataKey, positionMapKey) => categoryDataKey === positionMapKey,
|
||||||
|
);
|
||||||
|
// difference set
|
||||||
|
const currentDifferenceKeys = currentKeys.filter(
|
||||||
|
(x) => !intersectionKeys.some((y) => y === x),
|
||||||
|
);
|
||||||
|
const newPositionMap = currentDifferenceKeys.reduce<
|
||||||
|
Record<string, IPosition>
|
||||||
|
>((pre, cur) => {
|
||||||
// take a coordinate
|
// take a coordinate
|
||||||
const effectiveIdxes = CategorizeAnchorPointPositions.map(
|
const effectiveIdxes = CategorizeAnchorPointPositions.map(
|
||||||
(x, idx) => idx,
|
(x, idx) => idx,
|
||||||
@ -188,4 +202,10 @@ export const buildNewPositionMap = (
|
|||||||
|
|
||||||
return pre;
|
return pre;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
|
return { intersectionKeys, newPositionMap };
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isKeysEqual = (currentKeys: string[], previousKeys: string[]) => {
|
||||||
|
return isEqual(currentKeys.sort(), previousKeys.sort());
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user