feat: loop start add index (#3101)
* feat: loop start add index * update doc
This commit is contained in:
@@ -256,9 +256,9 @@ export enum NodeOutputKeyEnum {
|
|||||||
|
|
||||||
// loop
|
// loop
|
||||||
loopArray = 'loopArray',
|
loopArray = 'loopArray',
|
||||||
|
|
||||||
// loop start
|
// loop start
|
||||||
loopStartInput = 'loopStartInput',
|
loopStartInput = 'loopStartInput',
|
||||||
|
loopArrayIndex = 'loopArrayIndex',
|
||||||
|
|
||||||
// form input
|
// form input
|
||||||
formInputResult = 'formInputResult'
|
formInputResult = 'formInputResult'
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
import { FlowNodeInputTypeEnum, FlowNodeTypeEnum } from '../../../node/constant';
|
import {
|
||||||
|
FlowNodeInputTypeEnum,
|
||||||
|
FlowNodeOutputTypeEnum,
|
||||||
|
FlowNodeTypeEnum
|
||||||
|
} from '../../../node/constant';
|
||||||
import { FlowNodeTemplateType } from '../../../type/node.d';
|
import { FlowNodeTemplateType } from '../../../type/node.d';
|
||||||
import {
|
import {
|
||||||
FlowNodeTemplateTypeEnum,
|
FlowNodeTemplateTypeEnum,
|
||||||
NodeInputKeyEnum,
|
NodeInputKeyEnum,
|
||||||
|
NodeOutputKeyEnum,
|
||||||
WorkflowIOValueTypeEnum
|
WorkflowIOValueTypeEnum
|
||||||
} from '../../../constants';
|
} from '../../../constants';
|
||||||
import { getHandleConfig } from '../../utils';
|
import { getHandleConfig } from '../../utils';
|
||||||
@@ -30,5 +35,13 @@ export const LoopStartNode: FlowNodeTemplateType = {
|
|||||||
value: ''
|
value: ''
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
outputs: []
|
outputs: [
|
||||||
|
{
|
||||||
|
id: NodeOutputKeyEnum.loopArrayIndex,
|
||||||
|
key: NodeOutputKeyEnum.loopArrayIndex,
|
||||||
|
label: i18nT('workflow:Array_element_index'),
|
||||||
|
type: FlowNodeOutputTypeEnum.static,
|
||||||
|
valueType: WorkflowIOValueTypeEnum.number
|
||||||
|
}
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ export const dispatchLoop = async (props: Props): Promise<Response> => {
|
|||||||
let totalPoints = 0;
|
let totalPoints = 0;
|
||||||
let newVariables: Record<string, any> = props.variables;
|
let newVariables: Record<string, any> = props.variables;
|
||||||
|
|
||||||
|
let index = 0;
|
||||||
for await (const item of loopInputArray.filter(Boolean)) {
|
for await (const item of loopInputArray.filter(Boolean)) {
|
||||||
runtimeNodes.forEach((node) => {
|
runtimeNodes.forEach((node) => {
|
||||||
if (
|
if (
|
||||||
@@ -50,14 +51,21 @@ export const dispatchLoop = async (props: Props): Promise<Response> => {
|
|||||||
node.flowNodeType === FlowNodeTypeEnum.loopStart
|
node.flowNodeType === FlowNodeTypeEnum.loopStart
|
||||||
) {
|
) {
|
||||||
node.isEntry = true;
|
node.isEntry = true;
|
||||||
node.inputs = node.inputs.map((input) =>
|
node.inputs = node.inputs.map((input) => {
|
||||||
input.key === NodeInputKeyEnum.loopStartInput
|
if (input.key === NodeInputKeyEnum.loopStartInput) {
|
||||||
? {
|
return {
|
||||||
...input,
|
...input,
|
||||||
value: item
|
value: item
|
||||||
}
|
};
|
||||||
: input
|
} else if (input.key === NodeInputKeyEnum.loopStartInput) {
|
||||||
);
|
return {
|
||||||
|
...input,
|
||||||
|
value: index++
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const response = await dispatchWorkFlow({
|
const response = await dispatchWorkFlow({
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"Array_element": "Array element",
|
"Array_element": "Array element",
|
||||||
|
"Array_element_index": "Index",
|
||||||
"Code": "Code",
|
"Code": "Code",
|
||||||
"Confirm_sync_node": "It will be updated to the latest node configuration and fields that do not exist in the template will be deleted (including all custom fields).\n\nIf the fields are complex, it is recommended that you copy a node first and then update the original node to facilitate parameter copying.",
|
"Confirm_sync_node": "It will be updated to the latest node configuration and fields that do not exist in the template will be deleted (including all custom fields).\n\nIf the fields are complex, it is recommended that you copy a node first and then update the original node to facilitate parameter copying.",
|
||||||
"Node.Open_Node_Course": "Open node course",
|
"Node.Open_Node_Course": "Open node course",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"Array_element": "数组元素",
|
"Array_element": "数组元素",
|
||||||
|
"Array_element_index": "下标",
|
||||||
"Code": "代码",
|
"Code": "代码",
|
||||||
"Confirm_sync_node": "将会更新至最新的节点配置,不存在模板中的字段将会被删除(包括所有自定义字段)。\n如果字段较为复杂,建议您先复制一份节点,再更新原来的节点,便于参数复制。",
|
"Confirm_sync_node": "将会更新至最新的节点配置,不存在模板中的字段将会被删除(包括所有自定义字段)。\n如果字段较为复杂,建议您先复制一份节点,再更新原来的节点,便于参数复制。",
|
||||||
"Node.Open_Node_Course": "查看节点教程",
|
"Node.Open_Node_Course": "查看节点教程",
|
||||||
|
|||||||
@@ -43,15 +43,11 @@ const NodeLoop = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
|||||||
|
|
||||||
const { resetParentNodeSizeAndPosition } = useWorkflow();
|
const { resetParentNodeSizeAndPosition } = useWorkflow();
|
||||||
|
|
||||||
const loopInputArray = useMemo(
|
const { nodeWidth, nodeHeight, loopInputArray } = useMemo(() => {
|
||||||
() => inputs.find((input) => input.key === NodeInputKeyEnum.loopInputArray),
|
|
||||||
[inputs]
|
|
||||||
);
|
|
||||||
|
|
||||||
const { nodeWidth, nodeHeight } = useMemo(() => {
|
|
||||||
return {
|
return {
|
||||||
nodeWidth: inputs.find((input) => input.key === NodeInputKeyEnum.nodeWidth)?.value,
|
nodeWidth: inputs.find((input) => input.key === NodeInputKeyEnum.nodeWidth)?.value,
|
||||||
nodeHeight: inputs.find((input) => input.key === NodeInputKeyEnum.nodeHeight)?.value
|
nodeHeight: inputs.find((input) => input.key === NodeInputKeyEnum.nodeHeight)?.value,
|
||||||
|
loopInputArray: inputs.find((input) => input.key === NodeInputKeyEnum.loopInputArray)
|
||||||
};
|
};
|
||||||
}, [inputs]);
|
}, [inputs]);
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,15 @@ import { WorkflowContext } from '../../../context';
|
|||||||
import {
|
import {
|
||||||
NodeInputKeyEnum,
|
NodeInputKeyEnum,
|
||||||
NodeOutputKeyEnum,
|
NodeOutputKeyEnum,
|
||||||
|
toolValueTypeList,
|
||||||
WorkflowIOValueTypeEnum
|
WorkflowIOValueTypeEnum
|
||||||
} from '@fastgpt/global/core/workflow/constants';
|
} from '@fastgpt/global/core/workflow/constants';
|
||||||
import { Box, Flex, Table, TableContainer, Tbody, Td, Th, Thead, Tr } from '@chakra-ui/react';
|
import { Box, Flex, Table, TableContainer, Tbody, Td, Th, Thead, Tr } from '@chakra-ui/react';
|
||||||
import React, { useEffect, useMemo } from 'react';
|
import React, { useEffect, useMemo } from 'react';
|
||||||
import { FlowNodeOutputTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
import {
|
||||||
|
FlowNodeOutputTypeEnum,
|
||||||
|
FlowValueTypeMap
|
||||||
|
} from '@fastgpt/global/core/workflow/node/constant';
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
|
|
||||||
const typeMap = {
|
const typeMap = {
|
||||||
@@ -24,7 +28,7 @@ const typeMap = {
|
|||||||
|
|
||||||
const NodeLoopStart = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
const NodeLoopStart = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { nodeId } = data;
|
const { nodeId, outputs } = data;
|
||||||
const { nodeList, onChangeNode } = useContextSelector(WorkflowContext, (v) => v);
|
const { nodeList, onChangeNode } = useContextSelector(WorkflowContext, (v) => v);
|
||||||
|
|
||||||
const loopStartNode = useMemo(
|
const loopStartNode = useMemo(
|
||||||
@@ -94,23 +98,21 @@ const NodeLoopStart = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
|||||||
debug: true
|
debug: true
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box px={4} pt={2} w={'420px'} h={'116px'}>
|
<Box px={4} pt={2} w={'420px'}>
|
||||||
{!loopItemInputType ? (
|
<Box bg={'white'} borderRadius={'md'} overflow={'hidden'} border={'base'}>
|
||||||
<EmptyTip text={t('workflow:loop_start_tip')} py={0} mt={4} iconSize={'32px'} />
|
<TableContainer>
|
||||||
) : (
|
<Table bg={'white'}>
|
||||||
<Box bg={'white'} borderRadius={'md'} overflow={'hidden'} border={'base'}>
|
<Thead>
|
||||||
<TableContainer>
|
<Tr>
|
||||||
<Table bg={'white'}>
|
<Th borderBottomLeftRadius={'none !important'}>
|
||||||
<Thead>
|
{t('workflow:Variable_name')}
|
||||||
<Tr>
|
</Th>
|
||||||
<Th borderBottomLeftRadius={'none !important'}>
|
<Th>{t('common:core.workflow.Value type')}</Th>
|
||||||
{t('workflow:Variable_name')}
|
</Tr>
|
||||||
</Th>
|
</Thead>
|
||||||
<Th>{t('common:core.workflow.Value type')}</Th>
|
<Tbody>
|
||||||
</Tr>
|
{outputs.map((output) => (
|
||||||
</Thead>
|
<Tr key={output.id}>
|
||||||
<Tbody>
|
|
||||||
<Tr>
|
|
||||||
<Td>
|
<Td>
|
||||||
<Flex alignItems={'center'}>
|
<Flex alignItems={'center'}>
|
||||||
<MyIcon
|
<MyIcon
|
||||||
@@ -119,20 +121,20 @@ const NodeLoopStart = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
|||||||
mr={1}
|
mr={1}
|
||||||
color={'primary.600'}
|
color={'primary.600'}
|
||||||
/>
|
/>
|
||||||
{t('workflow:Array_element')}
|
{t(output.label)}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Td>
|
</Td>
|
||||||
<Td>{loopItemInputType}</Td>
|
{output.valueType && <Td>{FlowValueTypeMap[output.valueType]?.label}</Td>}
|
||||||
</Tr>
|
</Tr>
|
||||||
</Tbody>
|
))}
|
||||||
</Table>
|
</Tbody>
|
||||||
</TableContainer>
|
</Table>
|
||||||
</Box>
|
</TableContainer>
|
||||||
)}
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</NodeCard>
|
</NodeCard>
|
||||||
);
|
);
|
||||||
}, [data, loopItemInputType, selected, t]);
|
}, [data, outputs, selected, t]);
|
||||||
|
|
||||||
return Render;
|
return Render;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user