mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
### What problem does this PR solve? Feat: Reference the output variable of the upstream operator #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -117,13 +117,9 @@ export default function VariablePickerMenuPlugin({
|
|||||||
|
|
||||||
const [queryString, setQueryString] = React.useState<string | null>('');
|
const [queryString, setQueryString] = React.useState<string | null>('');
|
||||||
|
|
||||||
const buildGroupedOptions = useBuildComponentIdSelectOptions(
|
const options = useBuildComponentIdSelectOptions(node?.id, node?.parentId);
|
||||||
node?.id,
|
|
||||||
node?.parentId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const buildNextOptions = useCallback(() => {
|
const buildNextOptions = useCallback(() => {
|
||||||
const options = buildGroupedOptions();
|
|
||||||
let filteredOptions = options;
|
let filteredOptions = options;
|
||||||
|
|
||||||
if (queryString) {
|
if (queryString) {
|
||||||
@ -150,11 +146,10 @@ export default function VariablePickerMenuPlugin({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return nextOptions;
|
return nextOptions;
|
||||||
}, [buildGroupedOptions, queryString]);
|
}, [options, queryString]);
|
||||||
|
|
||||||
const findLabelByValue = useCallback(
|
const findLabelByValue = useCallback(
|
||||||
(value: string) => {
|
(value: string) => {
|
||||||
const options = buildGroupedOptions();
|
|
||||||
const children = options.reduce<Array<{ label: string; value: string }>>(
|
const children = options.reduce<Array<{ label: string; value: string }>>(
|
||||||
(pre, cur) => {
|
(pre, cur) => {
|
||||||
return pre.concat(cur.options);
|
return pre.concat(cur.options);
|
||||||
@ -164,7 +159,7 @@ export default function VariablePickerMenuPlugin({
|
|||||||
|
|
||||||
return children.find((x) => x.value === value)?.label;
|
return children.find((x) => x.value === value)?.label;
|
||||||
},
|
},
|
||||||
[buildGroupedOptions],
|
[options],
|
||||||
);
|
);
|
||||||
|
|
||||||
const onSelectOption = useCallback(
|
const onSelectOption = useCallback(
|
||||||
|
|||||||
@ -4,9 +4,10 @@ import { DeleteOutlined } from '@ant-design/icons';
|
|||||||
import { Button, Collapse, Flex, Input, Select, Table, TableProps } from 'antd';
|
import { Button, Collapse, Flex, Input, Select, Table, TableProps } from 'antd';
|
||||||
import { trim } from 'lodash';
|
import { trim } from 'lodash';
|
||||||
import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query';
|
import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query';
|
||||||
import { IInvokeVariable, RAGFlowNodeType } from '../../interface';
|
import { IInvokeVariable } from '../../interface';
|
||||||
import { useHandleOperateParameters } from './hooks';
|
import { useHandleOperateParameters } from './hooks';
|
||||||
|
|
||||||
|
import { RAGFlowNodeType } from '@/interfaces/database/flow';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import { RAGFlowNodeType } from '@/interfaces/database/flow';
|
import { RAGFlowNodeType } from '@/interfaces/database/flow';
|
||||||
|
import { Edge } from '@xyflow/react';
|
||||||
import { DefaultOptionType } from 'antd/es/select';
|
import { DefaultOptionType } from 'antd/es/select';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { BeginId, Operator } from '../constant';
|
import { BeginId, Operator } from '../constant';
|
||||||
@ -34,6 +36,61 @@ export const useGetBeginNodeDataQueryIsSafe = () => {
|
|||||||
return isBeginNodeDataQuerySafe;
|
return isBeginNodeDataQuerySafe;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function filterAllUpstreamNodeIds(edges: Edge[], nodeIds: string[]) {
|
||||||
|
return nodeIds.reduce<string[]>((pre, nodeId) => {
|
||||||
|
const currentEdges = edges.filter((x) => x.target === nodeId);
|
||||||
|
|
||||||
|
const upstreamNodeIds: string[] = currentEdges.map((x) => x.source);
|
||||||
|
|
||||||
|
const ids = upstreamNodeIds.concat(
|
||||||
|
filterAllUpstreamNodeIds(edges, upstreamNodeIds),
|
||||||
|
);
|
||||||
|
|
||||||
|
ids.forEach((x) => {
|
||||||
|
if (pre.every((y) => y !== x)) {
|
||||||
|
pre.push(x);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return pre;
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildOutputOptions(outputs: Record<string, any> = {}) {
|
||||||
|
return Object.keys(outputs).map((x) => ({
|
||||||
|
label: x,
|
||||||
|
value: x,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useBuildNodeOutputOptions(nodeId?: string) {
|
||||||
|
const nodes = useGraphStore((state) => state.nodes);
|
||||||
|
const edges = useGraphStore((state) => state.edges);
|
||||||
|
|
||||||
|
const nodeOutputOptions = useMemo(() => {
|
||||||
|
if (!nodeId) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const upstreamIds = filterAllUpstreamNodeIds(edges, [nodeId]);
|
||||||
|
|
||||||
|
const nodeWithOutputList = nodes.filter(
|
||||||
|
(x) =>
|
||||||
|
upstreamIds.some((y) => y === x.id) && !isEmpty(x.data?.form?.outputs),
|
||||||
|
);
|
||||||
|
|
||||||
|
return nodeWithOutputList
|
||||||
|
.filter((x) => x.id !== nodeId)
|
||||||
|
.map((x) => ({
|
||||||
|
label: x.data.name,
|
||||||
|
value: x.id,
|
||||||
|
title: x.data.name,
|
||||||
|
options: buildOutputOptions(x.data.form.outputs),
|
||||||
|
}));
|
||||||
|
}, [edges, nodeId, nodes]);
|
||||||
|
|
||||||
|
return nodeOutputOptions;
|
||||||
|
}
|
||||||
|
|
||||||
// exclude nodes with branches
|
// exclude nodes with branches
|
||||||
const ExcludedNodes = [
|
const ExcludedNodes = [
|
||||||
Operator.Categorize,
|
Operator.Categorize,
|
||||||
@ -49,6 +106,8 @@ export const useBuildComponentIdSelectOptions = (
|
|||||||
const nodes = useGraphStore((state) => state.nodes);
|
const nodes = useGraphStore((state) => state.nodes);
|
||||||
const getBeginNodeDataQuery = useGetBeginNodeDataQuery();
|
const getBeginNodeDataQuery = useGetBeginNodeDataQuery();
|
||||||
|
|
||||||
|
const nodeOutputOptions = useBuildNodeOutputOptions(nodeId);
|
||||||
|
|
||||||
// Limit the nodes inside iteration to only reference peer nodes with the same parentId and other external nodes other than their parent nodes
|
// Limit the nodes inside iteration to only reference peer nodes with the same parentId and other external nodes other than their parent nodes
|
||||||
const filterChildNodesToSameParentOrExternal = useCallback(
|
const filterChildNodesToSameParentOrExternal = useCallback(
|
||||||
(node: RAGFlowNodeType) => {
|
(node: RAGFlowNodeType) => {
|
||||||
@ -76,7 +135,7 @@ export const useBuildComponentIdSelectOptions = (
|
|||||||
.map((x) => ({ label: x.data.name, value: x.id }));
|
.map((x) => ({ label: x.data.name, value: x.id }));
|
||||||
}, [nodes, nodeId, filterChildNodesToSameParentOrExternal]);
|
}, [nodes, nodeId, filterChildNodesToSameParentOrExternal]);
|
||||||
|
|
||||||
const buildGroupedOptions = useCallback(() => {
|
const options = useMemo(() => {
|
||||||
const query: BeginQuery[] = getBeginNodeDataQuery();
|
const query: BeginQuery[] = getBeginNodeDataQuery();
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -92,21 +151,21 @@ export const useBuildComponentIdSelectOptions = (
|
|||||||
value: `begin@${x.key}`,
|
value: `begin@${x.key}`,
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
|
...nodeOutputOptions,
|
||||||
];
|
];
|
||||||
}, [componentIdOptions, getBeginNodeDataQuery]);
|
}, [componentIdOptions, getBeginNodeDataQuery, nodeOutputOptions]);
|
||||||
|
|
||||||
return buildGroupedOptions;
|
return options;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetComponentLabelByValue = (nodeId: string) => {
|
export const useGetComponentLabelByValue = (nodeId: string) => {
|
||||||
const buildGroupedOptions = useBuildComponentIdSelectOptions(nodeId);
|
const options = useBuildComponentIdSelectOptions(nodeId);
|
||||||
|
|
||||||
const flattenOptions = useMemo(() => {
|
const flattenOptions = useMemo(() => {
|
||||||
const options = buildGroupedOptions();
|
|
||||||
return options.reduce<DefaultOptionType[]>((pre, cur) => {
|
return options.reduce<DefaultOptionType[]>((pre, cur) => {
|
||||||
return [...pre, ...cur.options];
|
return [...pre, ...cur.options];
|
||||||
}, []);
|
}, []);
|
||||||
}, [buildGroupedOptions]);
|
}, [options]);
|
||||||
|
|
||||||
const getLabel = useCallback(
|
const getLabel = useCallback(
|
||||||
(val?: string) => {
|
(val?: string) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user