mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-27 08:25:07 +00:00
feat: add elseif to ifelse node (#1378)
This commit is contained in:
@@ -141,8 +141,7 @@ export enum NodeOutputKeyEnum {
|
|||||||
// plugin
|
// plugin
|
||||||
pluginStart = 'pluginStart',
|
pluginStart = 'pluginStart',
|
||||||
|
|
||||||
if = 'IF',
|
ifElseResult = 'ifElseResult'
|
||||||
else = 'ELSE'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum VariableInputEnum {
|
export enum VariableInputEnum {
|
||||||
|
@@ -75,7 +75,7 @@ export type DispatchNodeResponseType = {
|
|||||||
pluginDetail?: ChatHistoryItemResType[];
|
pluginDetail?: ChatHistoryItemResType[];
|
||||||
|
|
||||||
// if-else
|
// if-else
|
||||||
ifElseResult?: 'IF' | 'ELSE';
|
ifElseResult?: string;
|
||||||
|
|
||||||
// tool
|
// tool
|
||||||
toolCallTokens?: number;
|
toolCallTokens?: number;
|
||||||
|
@@ -23,14 +23,6 @@ export const IfElseNode: FlowNodeTemplateType = {
|
|||||||
intro: '根据一定的条件,执行不同的分支。',
|
intro: '根据一定的条件,执行不同的分支。',
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
|
||||||
key: NodeInputKeyEnum.condition,
|
|
||||||
valueType: WorkflowIOValueTypeEnum.string,
|
|
||||||
label: '',
|
|
||||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
|
||||||
required: false,
|
|
||||||
value: 'AND' // AND, OR
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: NodeInputKeyEnum.ifElseList,
|
key: NodeInputKeyEnum.ifElseList,
|
||||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||||
@@ -38,27 +30,25 @@ export const IfElseNode: FlowNodeTemplateType = {
|
|||||||
label: '',
|
label: '',
|
||||||
value: [
|
value: [
|
||||||
{
|
{
|
||||||
variable: undefined,
|
condition: 'AND', // AND, OR
|
||||||
condition: undefined,
|
list: [
|
||||||
value: undefined
|
{
|
||||||
|
variable: undefined,
|
||||||
|
condition: undefined,
|
||||||
|
value: undefined
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
outputs: [
|
outputs: [
|
||||||
{
|
{
|
||||||
id: NodeOutputKeyEnum.if,
|
id: NodeOutputKeyEnum.ifElseResult,
|
||||||
key: NodeOutputKeyEnum.if,
|
key: NodeOutputKeyEnum.ifElseResult,
|
||||||
label: 'IF',
|
label: 'IF ELSE',
|
||||||
valueType: WorkflowIOValueTypeEnum.any,
|
valueType: WorkflowIOValueTypeEnum.string,
|
||||||
type: FlowNodeOutputTypeEnum.source
|
type: FlowNodeOutputTypeEnum.static
|
||||||
},
|
|
||||||
{
|
|
||||||
id: NodeOutputKeyEnum.else,
|
|
||||||
key: NodeOutputKeyEnum.else,
|
|
||||||
label: 'ELSE',
|
|
||||||
valueType: WorkflowIOValueTypeEnum.any,
|
|
||||||
type: FlowNodeOutputTypeEnum.source
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
@@ -2,8 +2,12 @@ import { ReferenceValueProps } from 'core/workflow/type/io';
|
|||||||
import { VariableConditionEnum } from './constant';
|
import { VariableConditionEnum } from './constant';
|
||||||
|
|
||||||
export type IfElseConditionType = 'AND' | 'OR';
|
export type IfElseConditionType = 'AND' | 'OR';
|
||||||
export type IfElseListItemType = {
|
export type ConditionListItemType = {
|
||||||
variable?: ReferenceValueProps;
|
variable?: ReferenceValueProps;
|
||||||
condition?: VariableConditionEnum;
|
condition?: VariableConditionEnum;
|
||||||
value?: string;
|
value?: string;
|
||||||
};
|
};
|
||||||
|
export type IfElseListItemType = {
|
||||||
|
condition: IfElseConditionType;
|
||||||
|
list: ConditionListItemType[];
|
||||||
|
};
|
||||||
|
@@ -3,6 +3,7 @@ import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runti
|
|||||||
import { DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type';
|
import { DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type';
|
||||||
import { VariableConditionEnum } from '@fastgpt/global/core/workflow/template/system/ifElse/constant';
|
import { VariableConditionEnum } from '@fastgpt/global/core/workflow/template/system/ifElse/constant';
|
||||||
import {
|
import {
|
||||||
|
ConditionListItemType,
|
||||||
IfElseConditionType,
|
IfElseConditionType,
|
||||||
IfElseListItemType
|
IfElseListItemType
|
||||||
} from '@fastgpt/global/core/workflow/template/system/ifElse/type';
|
} from '@fastgpt/global/core/workflow/template/system/ifElse/type';
|
||||||
@@ -41,15 +42,13 @@ function checkCondition(condition: VariableConditionEnum, variableValue: any, va
|
|||||||
return (operations[condition] || (() => false))();
|
return (operations[condition] || (() => false))();
|
||||||
}
|
}
|
||||||
|
|
||||||
export const dispatchIfElse = async (props: Props): Promise<DispatchNodeResultType<{}>> => {
|
function getResult(
|
||||||
const {
|
condition: IfElseConditionType,
|
||||||
params,
|
list: ConditionListItemType[],
|
||||||
runtimeNodes,
|
variables: any,
|
||||||
variables,
|
runtimeNodes: any[]
|
||||||
node: { nodeId }
|
) {
|
||||||
} = props;
|
const listResult = list.map((item) => {
|
||||||
const { condition, ifElseList } = params;
|
|
||||||
const listResult = ifElseList.map((item) => {
|
|
||||||
const { variable, condition: variableCondition, value } = item;
|
const { variable, condition: variableCondition, value } = item;
|
||||||
|
|
||||||
const variableValue = getReferenceVariableValue({
|
const variableValue = getReferenceVariableValue({
|
||||||
@@ -61,15 +60,40 @@ export const dispatchIfElse = async (props: Props): Promise<DispatchNodeResultTy
|
|||||||
return checkCondition(variableCondition as VariableConditionEnum, variableValue, value || '');
|
return checkCondition(variableCondition as VariableConditionEnum, variableValue, value || '');
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = condition === 'AND' ? listResult.every(Boolean) : listResult.some(Boolean);
|
return condition === 'AND' ? listResult.every(Boolean) : listResult.some(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const dispatchIfElse = async (props: Props): Promise<DispatchNodeResultType<{}>> => {
|
||||||
|
const {
|
||||||
|
params,
|
||||||
|
runtimeNodes,
|
||||||
|
variables,
|
||||||
|
node: { nodeId }
|
||||||
|
} = props;
|
||||||
|
const { ifElseList } = params;
|
||||||
|
|
||||||
|
let res = 'ELSE';
|
||||||
|
for (let i = 0; i < ifElseList.length; i++) {
|
||||||
|
const item = ifElseList[i];
|
||||||
|
const result = getResult(item.condition, item.list, variables, runtimeNodes);
|
||||||
|
if (result) {
|
||||||
|
res = `IF${i}`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const resArray = Array.from({ length: ifElseList.length + 1 }, (_, index) => {
|
||||||
|
const label = index < ifElseList.length ? `IF${index}` : 'ELSE';
|
||||||
|
return getHandleId(nodeId, 'source', label);
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[DispatchNodeResponseKeyEnum.nodeResponse]: {
|
[DispatchNodeResponseKeyEnum.nodeResponse]: {
|
||||||
totalPoints: 0,
|
totalPoints: 0,
|
||||||
ifElseResult: result ? 'IF' : 'ELSE'
|
ifElseResult: res
|
||||||
},
|
},
|
||||||
[DispatchNodeResponseKeyEnum.skipHandleId]: result
|
[DispatchNodeResponseKeyEnum.skipHandleId]: resArray.filter(
|
||||||
? [getHandleId(nodeId, 'source', 'ELSE')]
|
(item) => item !== getHandleId(nodeId, 'source', res)
|
||||||
: [getHandleId(nodeId, 'source', 'IF')]
|
)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
122
pnpm-lock.yaml
generated
122
pnpm-lock.yaml
generated
@@ -1,4 +1,4 @@
|
|||||||
lockfileVersion: '6.1'
|
lockfileVersion: '6.0'
|
||||||
|
|
||||||
settings:
|
settings:
|
||||||
autoInstallPeers: true
|
autoInstallPeers: true
|
||||||
@@ -431,6 +431,9 @@ importers:
|
|||||||
react:
|
react:
|
||||||
specifier: 18.2.0
|
specifier: 18.2.0
|
||||||
version: 18.2.0
|
version: 18.2.0
|
||||||
|
react-beautiful-dnd:
|
||||||
|
specifier: ^13.1.1
|
||||||
|
version: 13.1.1(react-dom@18.2.0)(react@18.2.0)
|
||||||
react-day-picker:
|
react-day-picker:
|
||||||
specifier: ^8.7.1
|
specifier: ^8.7.1
|
||||||
version: 8.7.1(date-fns@2.30.0)(react@18.2.0)
|
version: 8.7.1(date-fns@2.30.0)(react@18.2.0)
|
||||||
@@ -501,6 +504,9 @@ importers:
|
|||||||
'@types/react':
|
'@types/react':
|
||||||
specifier: 18.2.0
|
specifier: 18.2.0
|
||||||
version: 18.2.0
|
version: 18.2.0
|
||||||
|
'@types/react-beautiful-dnd':
|
||||||
|
specifier: ^13.1.8
|
||||||
|
version: 13.1.8
|
||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
specifier: 18.2.0
|
specifier: 18.2.0
|
||||||
version: 18.2.0
|
version: 18.2.0
|
||||||
@@ -3065,6 +3071,7 @@ packages:
|
|||||||
|
|
||||||
/@emotion/memoize@0.7.4:
|
/@emotion/memoize@0.7.4:
|
||||||
resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==}
|
resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==}
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -3682,6 +3689,7 @@ packages:
|
|||||||
/@mapbox/node-pre-gyp@1.0.11(encoding@0.1.13):
|
/@mapbox/node-pre-gyp@1.0.11(encoding@0.1.13):
|
||||||
resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==}
|
resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
detect-libc: 2.0.3
|
detect-libc: 2.0.3
|
||||||
https-proxy-agent: 5.0.1
|
https-proxy-agent: 5.0.1
|
||||||
@@ -4741,12 +4749,27 @@ packages:
|
|||||||
resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==}
|
resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/react-beautiful-dnd@13.1.8:
|
||||||
|
resolution: {integrity: sha512-E3TyFsro9pQuK4r8S/OL6G99eq7p8v29sX0PM7oT8Z+PJfZvSQTx4zTQbUJ+QZXioAF0e7TGBEcA1XhYhCweyQ==}
|
||||||
|
dependencies:
|
||||||
|
'@types/react': 18.2.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/react-dom@18.2.0:
|
/@types/react-dom@18.2.0:
|
||||||
resolution: {integrity: sha512-8yQrvS6sMpSwIovhPOwfyNf2Wz6v/B62LFSVYQ85+Rq3tLsBIG7rP5geMxaijTUxSkrO6RzN/IRuIAADYQsleA==}
|
resolution: {integrity: sha512-8yQrvS6sMpSwIovhPOwfyNf2Wz6v/B62LFSVYQ85+Rq3tLsBIG7rP5geMxaijTUxSkrO6RzN/IRuIAADYQsleA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/react': 18.2.0
|
'@types/react': 18.2.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/react-redux@7.1.33:
|
||||||
|
resolution: {integrity: sha512-NF8m5AjWCkert+fosDsN3hAlHzpjSiXlVy9EgQEmLoBhaNXbmyeGs/aj5dQzKuF+/q+S7JQagorGDW8pJ28Hmg==}
|
||||||
|
dependencies:
|
||||||
|
'@types/hoist-non-react-statics': 3.3.5
|
||||||
|
'@types/react': 18.2.0
|
||||||
|
hoist-non-react-statics: 3.3.2
|
||||||
|
redux: 4.2.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@types/react-syntax-highlighter@15.5.6:
|
/@types/react-syntax-highlighter@15.5.6:
|
||||||
resolution: {integrity: sha512-i7wFuLbIAFlabTeD2I1cLjEOrG/xdMa/rpx2zwzAoGHuXJDhSqp9BSfDlMHSh9JSuNfxHk9eEmMX6D55GiyjGg==}
|
resolution: {integrity: sha512-i7wFuLbIAFlabTeD2I1cLjEOrG/xdMa/rpx2zwzAoGHuXJDhSqp9BSfDlMHSh9JSuNfxHk9eEmMX6D55GiyjGg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -5005,6 +5028,7 @@ packages:
|
|||||||
|
|
||||||
/abbrev@1.1.1:
|
/abbrev@1.1.1:
|
||||||
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
|
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -5047,6 +5071,7 @@ packages:
|
|||||||
/agent-base@6.0.2:
|
/agent-base@6.0.2:
|
||||||
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
|
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
|
||||||
engines: {node: '>= 6.0.0'}
|
engines: {node: '>= 6.0.0'}
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@@ -5170,12 +5195,14 @@ packages:
|
|||||||
|
|
||||||
/aproba@2.0.0:
|
/aproba@2.0.0:
|
||||||
resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==}
|
resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==}
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/are-we-there-yet@2.0.0:
|
/are-we-there-yet@2.0.0:
|
||||||
resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==}
|
resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
delegates: 1.0.0
|
delegates: 1.0.0
|
||||||
readable-stream: 3.6.2
|
readable-stream: 3.6.2
|
||||||
@@ -5791,6 +5818,7 @@ packages:
|
|||||||
/chownr@2.0.0:
|
/chownr@2.0.0:
|
||||||
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
|
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -5903,6 +5931,7 @@ packages:
|
|||||||
/color-support@1.1.3:
|
/color-support@1.1.3:
|
||||||
resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==}
|
resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -5975,6 +6004,7 @@ packages:
|
|||||||
|
|
||||||
/console-control-strings@1.1.0:
|
/console-control-strings@1.1.0:
|
||||||
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
|
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -6540,6 +6570,7 @@ packages:
|
|||||||
/decompress-response@4.2.1:
|
/decompress-response@4.2.1:
|
||||||
resolution: {integrity: sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==}
|
resolution: {integrity: sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
mimic-response: 2.1.0
|
mimic-response: 2.1.0
|
||||||
dev: false
|
dev: false
|
||||||
@@ -6644,6 +6675,7 @@ packages:
|
|||||||
|
|
||||||
/delegates@1.0.0:
|
/delegates@1.0.0:
|
||||||
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
|
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -6671,6 +6703,7 @@ packages:
|
|||||||
/detect-libc@2.0.3:
|
/detect-libc@2.0.3:
|
||||||
resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
|
resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -7877,6 +7910,7 @@ packages:
|
|||||||
/fs-minipass@2.1.0:
|
/fs-minipass@2.1.0:
|
||||||
resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
|
resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
minipass: 3.3.6
|
minipass: 3.3.6
|
||||||
dev: false
|
dev: false
|
||||||
@@ -7912,6 +7946,7 @@ packages:
|
|||||||
/gauge@3.0.2:
|
/gauge@3.0.2:
|
||||||
resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==}
|
resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
aproba: 2.0.0
|
aproba: 2.0.0
|
||||||
color-support: 1.1.3
|
color-support: 1.1.3
|
||||||
@@ -8089,6 +8124,7 @@ packages:
|
|||||||
|
|
||||||
/has-unicode@2.0.1:
|
/has-unicode@2.0.1:
|
||||||
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
|
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -8246,6 +8282,7 @@ packages:
|
|||||||
/https-proxy-agent@5.0.1:
|
/https-proxy-agent@5.0.1:
|
||||||
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
|
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
agent-base: 6.0.2
|
agent-base: 6.0.2
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
@@ -9088,6 +9125,7 @@ packages:
|
|||||||
/make-dir@3.1.0:
|
/make-dir@3.1.0:
|
||||||
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
|
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
semver: 6.3.1
|
semver: 6.3.1
|
||||||
dev: false
|
dev: false
|
||||||
@@ -9289,8 +9327,13 @@ packages:
|
|||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/memoize-one@5.2.1:
|
||||||
|
resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/memory-pager@1.5.0:
|
/memory-pager@1.5.0:
|
||||||
resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==}
|
resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==}
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -9647,6 +9690,7 @@ packages:
|
|||||||
/mimic-response@2.1.0:
|
/mimic-response@2.1.0:
|
||||||
resolution: {integrity: sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==}
|
resolution: {integrity: sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -9669,6 +9713,7 @@ packages:
|
|||||||
/minipass@3.3.6:
|
/minipass@3.3.6:
|
||||||
resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
|
resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
yallist: 4.0.0
|
yallist: 4.0.0
|
||||||
dev: false
|
dev: false
|
||||||
@@ -9677,12 +9722,14 @@ packages:
|
|||||||
/minipass@5.0.0:
|
/minipass@5.0.0:
|
||||||
resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==}
|
resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/minizlib@2.1.2:
|
/minizlib@2.1.2:
|
||||||
resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
|
resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
minipass: 3.3.6
|
minipass: 3.3.6
|
||||||
yallist: 4.0.0
|
yallist: 4.0.0
|
||||||
@@ -9700,6 +9747,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
|
resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -9981,6 +10029,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==}
|
resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
abbrev: 1.1.1
|
abbrev: 1.1.1
|
||||||
dev: false
|
dev: false
|
||||||
@@ -9999,6 +10048,7 @@ packages:
|
|||||||
|
|
||||||
/npmlog@5.0.1:
|
/npmlog@5.0.1:
|
||||||
resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==}
|
resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==}
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
are-we-there-yet: 2.0.0
|
are-we-there-yet: 2.0.0
|
||||||
console-control-strings: 1.1.0
|
console-control-strings: 1.1.0
|
||||||
@@ -10309,6 +10359,7 @@ packages:
|
|||||||
/path2d@0.1.1:
|
/path2d@0.1.1:
|
||||||
resolution: {integrity: sha512-/+S03c8AGsDYKKBtRDqieTJv2GlkMb0bWjnqOgtF6MkjdUQ9a8ARAtxWf9NgKLGm2+WQr6+/tqJdU8HNGsIDoA==}
|
resolution: {integrity: sha512-/+S03c8AGsDYKKBtRDqieTJv2GlkMb0bWjnqOgtF6MkjdUQ9a8ARAtxWf9NgKLGm2+WQr6+/tqJdU8HNGsIDoA==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -10587,6 +10638,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/raf-schd@4.0.3:
|
||||||
|
resolution: {integrity: sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/randombytes@2.1.0:
|
/randombytes@2.1.0:
|
||||||
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
|
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -10614,6 +10669,25 @@ packages:
|
|||||||
unpipe: 1.0.0
|
unpipe: 1.0.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/react-beautiful-dnd@13.1.1(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8.5 || ^17.0.0 || ^18.0.0
|
||||||
|
react-dom: ^16.8.5 || ^17.0.0 || ^18.0.0
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.24.1
|
||||||
|
css-box-model: 1.2.1
|
||||||
|
memoize-one: 5.2.1
|
||||||
|
raf-schd: 4.0.3
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
react-redux: 7.2.9(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
redux: 4.2.1
|
||||||
|
use-memo-one: 1.1.3(react@18.2.0)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- react-native
|
||||||
|
dev: false
|
||||||
|
|
||||||
/react-clientside-effect@1.2.6(react@18.2.0):
|
/react-clientside-effect@1.2.6(react@18.2.0):
|
||||||
resolution: {integrity: sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==}
|
resolution: {integrity: sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -10706,6 +10780,10 @@ packages:
|
|||||||
/react-is@16.13.1:
|
/react-is@16.13.1:
|
||||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||||
|
|
||||||
|
/react-is@17.0.2:
|
||||||
|
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/react-is@18.2.0:
|
/react-is@18.2.0:
|
||||||
resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
|
resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
|
||||||
dev: false
|
dev: false
|
||||||
@@ -10737,6 +10815,28 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/react-redux@7.2.9(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8.3 || ^17 || ^18
|
||||||
|
react-dom: '*'
|
||||||
|
react-native: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
react-dom:
|
||||||
|
optional: true
|
||||||
|
react-native:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.24.1
|
||||||
|
'@types/react-redux': 7.1.33
|
||||||
|
hoist-non-react-statics: 3.3.2
|
||||||
|
loose-envify: 1.4.0
|
||||||
|
prop-types: 15.8.1
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
react-is: 17.0.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/react-remove-scroll-bar@2.3.6(@types/react@18.2.0)(react@18.2.0):
|
/react-remove-scroll-bar@2.3.6(@types/react@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==}
|
resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -10858,6 +10958,12 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
picomatch: 2.3.1
|
picomatch: 2.3.1
|
||||||
|
|
||||||
|
/redux@4.2.1:
|
||||||
|
resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==}
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.24.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/reflect.getprototypeof@1.0.6:
|
/reflect.getprototypeof@1.0.6:
|
||||||
resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==}
|
resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -11262,6 +11368,7 @@ packages:
|
|||||||
|
|
||||||
/set-blocking@2.0.0:
|
/set-blocking@2.0.0:
|
||||||
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
|
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -11331,11 +11438,13 @@ packages:
|
|||||||
|
|
||||||
/simple-concat@1.0.1:
|
/simple-concat@1.0.1:
|
||||||
resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==}
|
resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==}
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/simple-get@3.1.1:
|
/simple-get@3.1.1:
|
||||||
resolution: {integrity: sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==}
|
resolution: {integrity: sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==}
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
decompress-response: 4.2.1
|
decompress-response: 4.2.1
|
||||||
once: 1.4.0
|
once: 1.4.0
|
||||||
@@ -11417,6 +11526,7 @@ packages:
|
|||||||
|
|
||||||
/sparse-bitfield@3.0.3:
|
/sparse-bitfield@3.0.3:
|
||||||
resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==}
|
resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==}
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
memory-pager: 1.5.0
|
memory-pager: 1.5.0
|
||||||
dev: false
|
dev: false
|
||||||
@@ -11685,6 +11795,7 @@ packages:
|
|||||||
/tar@6.2.1:
|
/tar@6.2.1:
|
||||||
resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
|
resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
chownr: 2.0.0
|
chownr: 2.0.0
|
||||||
fs-minipass: 2.1.0
|
fs-minipass: 2.1.0
|
||||||
@@ -12182,6 +12293,14 @@ packages:
|
|||||||
scheduler: 0.23.0
|
scheduler: 0.23.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/use-memo-one@1.1.3(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||||
|
dependencies:
|
||||||
|
react: 18.2.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/use-sidecar@1.1.2(@types/react@18.2.0)(react@18.2.0):
|
/use-sidecar@1.1.2(@types/react@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==}
|
resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -12539,6 +12658,7 @@ packages:
|
|||||||
|
|
||||||
/wide-align@1.1.5:
|
/wide-align@1.1.5:
|
||||||
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
|
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
string-width: 4.2.3
|
string-width: 4.2.3
|
||||||
dev: false
|
dev: false
|
||||||
|
@@ -935,6 +935,7 @@
|
|||||||
},
|
},
|
||||||
"input": {
|
"input": {
|
||||||
"Add Input": "Add Input",
|
"Add Input": "Add Input",
|
||||||
|
"Add Branch": "Add Branch",
|
||||||
"Input Number": "Input: {{length}}",
|
"Input Number": "Input: {{length}}",
|
||||||
"add": "",
|
"add": "",
|
||||||
"description": {
|
"description": {
|
||||||
|
@@ -937,6 +937,7 @@
|
|||||||
"Add Input": "添加入参",
|
"Add Input": "添加入参",
|
||||||
"Input Number": "入参: {{length}}",
|
"Input Number": "入参: {{length}}",
|
||||||
"add": "添加条件",
|
"add": "添加条件",
|
||||||
|
"Add Branch": "添加分支",
|
||||||
"description": {
|
"description": {
|
||||||
"Background": "你可以添加一些特定内容的介绍,从而更好的识别用户的问题类型。这个内容通常是给模型介绍一个它不知道的内容。",
|
"Background": "你可以添加一些特定内容的介绍,从而更好的识别用户的问题类型。这个内容通常是给模型介绍一个它不知道的内容。",
|
||||||
"HTTP Dynamic Input": "接收前方节点的输出值作为变量,这些变量可以被HTTP请求参数使用。",
|
"HTTP Dynamic Input": "接收前方节点的输出值作为变量,这些变量可以被HTTP请求参数使用。",
|
||||||
|
@@ -47,6 +47,7 @@
|
|||||||
"nextjs-node-loader": "^1.1.5",
|
"nextjs-node-loader": "^1.1.5",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
|
"react-beautiful-dnd": "^13.1.1",
|
||||||
"react-day-picker": "^8.7.1",
|
"react-day-picker": "^8.7.1",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-hook-form": "7.43.1",
|
"react-hook-form": "7.43.1",
|
||||||
@@ -72,6 +73,7 @@
|
|||||||
"@types/lodash": "^4.14.191",
|
"@types/lodash": "^4.14.191",
|
||||||
"@types/node": "^20.8.5",
|
"@types/node": "^20.8.5",
|
||||||
"@types/react": "18.2.0",
|
"@types/react": "18.2.0",
|
||||||
|
"@types/react-beautiful-dnd": "^13.1.8",
|
||||||
"@types/react-dom": "18.2.0",
|
"@types/react-dom": "18.2.0",
|
||||||
"@types/react-syntax-highlighter": "^15.5.6",
|
"@types/react-syntax-highlighter": "^15.5.6",
|
||||||
"@types/request-ip": "^0.0.37",
|
"@types/request-ip": "^0.0.37",
|
||||||
|
@@ -1,381 +0,0 @@
|
|||||||
import React, { useCallback, useMemo } from 'react';
|
|
||||||
import NodeCard from './render/NodeCard';
|
|
||||||
import { useTranslation } from 'next-i18next';
|
|
||||||
import { Box, Button, Flex, background } from '@chakra-ui/react';
|
|
||||||
import { SmallAddIcon } from '@chakra-ui/icons';
|
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
|
||||||
import RenderOutput from './render/RenderOutput';
|
|
||||||
import { NodeInputKeyEnum, WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants';
|
|
||||||
import { NodeProps } from 'reactflow';
|
|
||||||
import { FlowNodeItemType } from '@fastgpt/global/core/workflow/type';
|
|
||||||
import {
|
|
||||||
IfElseConditionType,
|
|
||||||
IfElseListItemType
|
|
||||||
} from '@fastgpt/global/core/workflow/template/system/ifElse/type';
|
|
||||||
import { ReferenceValueProps } from '@fastgpt/global/core/workflow/type/io';
|
|
||||||
import { ReferSelector, useReference } from './render/RenderInput/templates/Reference';
|
|
||||||
import {
|
|
||||||
VariableConditionEnum,
|
|
||||||
allConditionList,
|
|
||||||
arrayConditionList,
|
|
||||||
booleanConditionList,
|
|
||||||
numberConditionList
|
|
||||||
} from '@fastgpt/global/core/workflow/template/system/ifElse/constant';
|
|
||||||
import { stringConditionList } from '@fastgpt/global/core/workflow/template/system/ifElse/constant';
|
|
||||||
import MySelect from '@fastgpt/web/components/common/MySelect';
|
|
||||||
import MyInput from '@/components/MyInput';
|
|
||||||
import { useContextSelector } from 'use-context-selector';
|
|
||||||
import { WorkflowContext } from '../../context';
|
|
||||||
|
|
||||||
const NodeIfElse = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const { nodeId, inputs = [], outputs } = data;
|
|
||||||
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
|
|
||||||
|
|
||||||
const condition = useMemo(
|
|
||||||
() =>
|
|
||||||
(inputs.find((input) => input.key === NodeInputKeyEnum.condition)
|
|
||||||
?.value as IfElseConditionType) || 'OR',
|
|
||||||
[inputs]
|
|
||||||
);
|
|
||||||
const ifElseList = useMemo(
|
|
||||||
() =>
|
|
||||||
(inputs.find((input) => input.key === NodeInputKeyEnum.ifElseList)
|
|
||||||
?.value as IfElseListItemType[]) || [],
|
|
||||||
[inputs]
|
|
||||||
);
|
|
||||||
|
|
||||||
const onUpdateIfElseList = useCallback(
|
|
||||||
(value: IfElseListItemType[]) => {
|
|
||||||
const ifElseListInput = inputs.find((input) => input.key === NodeInputKeyEnum.ifElseList);
|
|
||||||
if (!ifElseListInput) return;
|
|
||||||
|
|
||||||
onChangeNode({
|
|
||||||
nodeId,
|
|
||||||
type: 'updateInput',
|
|
||||||
key: NodeInputKeyEnum.ifElseList,
|
|
||||||
value: {
|
|
||||||
...ifElseListInput,
|
|
||||||
value
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[inputs, nodeId, onChangeNode]
|
|
||||||
);
|
|
||||||
|
|
||||||
const RenderAddCondition = useMemo(() => {
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
onUpdateIfElseList([
|
|
||||||
...ifElseList,
|
|
||||||
{
|
|
||||||
variable: undefined,
|
|
||||||
condition: undefined,
|
|
||||||
value: undefined
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
}}
|
|
||||||
variant={'whiteBase'}
|
|
||||||
leftIcon={<SmallAddIcon />}
|
|
||||||
my={3}
|
|
||||||
w={'full'}
|
|
||||||
>
|
|
||||||
{t('core.module.input.add')}
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
}, [ifElseList, onUpdateIfElseList, t]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<NodeCard selected={selected} maxW={'1000px'} {...data}>
|
|
||||||
<Box px={6}>
|
|
||||||
<RenderOutput nodeId={nodeId} flowOutputList={[outputs[0]]} />
|
|
||||||
</Box>
|
|
||||||
<Box py={3} px={4}>
|
|
||||||
<Box className="nowheel">
|
|
||||||
{ifElseList.map((item, i) => {
|
|
||||||
return (
|
|
||||||
<Box key={i}>
|
|
||||||
{/* border */}
|
|
||||||
{i !== 0 && (
|
|
||||||
<Flex alignItems={'center'} w={'full'} py={'5px'}>
|
|
||||||
<Box
|
|
||||||
w={'auto'}
|
|
||||||
flex={1}
|
|
||||||
height={'1px'}
|
|
||||||
style={{
|
|
||||||
background:
|
|
||||||
'linear-gradient(90deg, rgba(232, 235, 240, 0.00) 0%, #E8EBF0 100%)'
|
|
||||||
}}
|
|
||||||
></Box>
|
|
||||||
<Flex
|
|
||||||
px={'2.5'}
|
|
||||||
color={'primary.600'}
|
|
||||||
fontWeight={'medium'}
|
|
||||||
alignItems={'center'}
|
|
||||||
cursor={'pointer'}
|
|
||||||
rounded={'md'}
|
|
||||||
onClick={() => {
|
|
||||||
const conditionInput = inputs.find(
|
|
||||||
(input) => input.key === NodeInputKeyEnum.condition
|
|
||||||
);
|
|
||||||
if (!conditionInput) return;
|
|
||||||
|
|
||||||
onChangeNode({
|
|
||||||
nodeId,
|
|
||||||
type: 'updateInput',
|
|
||||||
key: NodeInputKeyEnum.condition,
|
|
||||||
value: {
|
|
||||||
...conditionInput,
|
|
||||||
value: conditionInput.value === 'OR' ? 'AND' : 'OR'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{condition}
|
|
||||||
<MyIcon ml={1} boxSize={5} name="change" />
|
|
||||||
</Flex>
|
|
||||||
<Box
|
|
||||||
w={'auto'}
|
|
||||||
flex={1}
|
|
||||||
height={'1px'}
|
|
||||||
style={{
|
|
||||||
background:
|
|
||||||
'linear-gradient(90deg, #E8EBF0 0%, rgba(232, 235, 240, 0.00) 100%)'
|
|
||||||
}}
|
|
||||||
></Box>
|
|
||||||
</Flex>
|
|
||||||
)}
|
|
||||||
{/* condition list */}
|
|
||||||
<Flex gap={2} alignItems={'center'}>
|
|
||||||
{/* variable reference */}
|
|
||||||
<Box minW={'250px'}>
|
|
||||||
<Reference
|
|
||||||
nodeId={nodeId}
|
|
||||||
variable={item.variable}
|
|
||||||
onSelect={(e) => {
|
|
||||||
onUpdateIfElseList(
|
|
||||||
ifElseList.map((ifElse, index) => {
|
|
||||||
if (index === i) {
|
|
||||||
return {
|
|
||||||
...ifElse,
|
|
||||||
variable: e
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return ifElse;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
{/* condition select */}
|
|
||||||
<Box w={'130px'} flex={1}>
|
|
||||||
<ConditionSelect
|
|
||||||
condition={item.condition}
|
|
||||||
variable={item.variable}
|
|
||||||
onSelect={(e) => {
|
|
||||||
onUpdateIfElseList(
|
|
||||||
ifElseList.map((ifElse, index) => {
|
|
||||||
if (index === i) {
|
|
||||||
return {
|
|
||||||
...ifElse,
|
|
||||||
condition: e
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return ifElse;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
{/* value */}
|
|
||||||
<Box w={'200px'}>
|
|
||||||
<ConditionValueInput
|
|
||||||
value={item.value}
|
|
||||||
condition={item.condition}
|
|
||||||
variable={item.variable}
|
|
||||||
onChange={(e) => {
|
|
||||||
onUpdateIfElseList(
|
|
||||||
ifElseList.map((ifElse, index) => {
|
|
||||||
if (index === i) {
|
|
||||||
return {
|
|
||||||
...ifElse,
|
|
||||||
value: e
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return ifElse;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
{/* delete */}
|
|
||||||
{ifElseList.length > 1 && (
|
|
||||||
<MyIcon
|
|
||||||
ml={2}
|
|
||||||
boxSize={5}
|
|
||||||
name="delete"
|
|
||||||
cursor={'pointer'}
|
|
||||||
_hover={{ color: 'red.600' }}
|
|
||||||
color={'myGray.400'}
|
|
||||||
onClick={() => {
|
|
||||||
onUpdateIfElseList(ifElseList.filter((_, index) => index !== i));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Flex>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Box>
|
|
||||||
{RenderAddCondition}
|
|
||||||
</Box>
|
|
||||||
<Box px={6} mb={4}>
|
|
||||||
<RenderOutput nodeId={nodeId} flowOutputList={[outputs[1]]} />
|
|
||||||
</Box>
|
|
||||||
</NodeCard>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
export default React.memo(NodeIfElse);
|
|
||||||
|
|
||||||
const Reference = ({
|
|
||||||
nodeId,
|
|
||||||
variable,
|
|
||||||
onSelect
|
|
||||||
}: {
|
|
||||||
nodeId: string;
|
|
||||||
variable?: ReferenceValueProps;
|
|
||||||
onSelect: (e: ReferenceValueProps) => void;
|
|
||||||
}) => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const { referenceList, formatValue } = useReference({
|
|
||||||
nodeId,
|
|
||||||
valueType: WorkflowIOValueTypeEnum.any,
|
|
||||||
value: variable
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ReferSelector
|
|
||||||
placeholder={t('选择引用变量')}
|
|
||||||
list={referenceList}
|
|
||||||
value={formatValue}
|
|
||||||
onSelect={onSelect}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Different data types have different options */
|
|
||||||
const ConditionSelect = ({
|
|
||||||
condition,
|
|
||||||
variable,
|
|
||||||
onSelect
|
|
||||||
}: {
|
|
||||||
condition?: VariableConditionEnum;
|
|
||||||
variable?: ReferenceValueProps;
|
|
||||||
onSelect: (e: VariableConditionEnum) => void;
|
|
||||||
}) => {
|
|
||||||
const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList);
|
|
||||||
|
|
||||||
// get condition type
|
|
||||||
const valueType = useMemo(() => {
|
|
||||||
if (!variable) return;
|
|
||||||
const node = nodeList.find((node) => node.nodeId === variable[0]);
|
|
||||||
|
|
||||||
if (!node) return WorkflowIOValueTypeEnum.any;
|
|
||||||
const output = node.outputs.find((item) => item.id === variable[1]);
|
|
||||||
|
|
||||||
if (!output) return WorkflowIOValueTypeEnum.any;
|
|
||||||
return output.valueType;
|
|
||||||
}, [nodeList, variable]);
|
|
||||||
|
|
||||||
const conditionList = useMemo(() => {
|
|
||||||
if (valueType === WorkflowIOValueTypeEnum.string) return stringConditionList;
|
|
||||||
if (valueType === WorkflowIOValueTypeEnum.number) return numberConditionList;
|
|
||||||
if (valueType === WorkflowIOValueTypeEnum.boolean) return booleanConditionList;
|
|
||||||
if (
|
|
||||||
valueType === WorkflowIOValueTypeEnum.chatHistory ||
|
|
||||||
valueType === WorkflowIOValueTypeEnum.datasetQuote ||
|
|
||||||
valueType === WorkflowIOValueTypeEnum.dynamic ||
|
|
||||||
valueType === WorkflowIOValueTypeEnum.selectApp ||
|
|
||||||
valueType === WorkflowIOValueTypeEnum.arrayBoolean ||
|
|
||||||
valueType === WorkflowIOValueTypeEnum.arrayNumber ||
|
|
||||||
valueType === WorkflowIOValueTypeEnum.arrayObject ||
|
|
||||||
valueType === WorkflowIOValueTypeEnum.arrayString ||
|
|
||||||
valueType === WorkflowIOValueTypeEnum.object
|
|
||||||
)
|
|
||||||
return arrayConditionList;
|
|
||||||
|
|
||||||
if (valueType === WorkflowIOValueTypeEnum.any) return allConditionList;
|
|
||||||
|
|
||||||
return [];
|
|
||||||
}, [valueType]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<MySelect
|
|
||||||
w={'100%'}
|
|
||||||
list={conditionList}
|
|
||||||
value={condition}
|
|
||||||
onchange={onSelect}
|
|
||||||
placeholder="选择条件"
|
|
||||||
></MySelect>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Different condition can be entered differently
|
|
||||||
empty, notEmpty: forbid input
|
|
||||||
boolean type: select true/false
|
|
||||||
*/
|
|
||||||
const ConditionValueInput = ({
|
|
||||||
value = '',
|
|
||||||
variable,
|
|
||||||
condition,
|
|
||||||
onChange
|
|
||||||
}: {
|
|
||||||
value?: string;
|
|
||||||
variable?: ReferenceValueProps;
|
|
||||||
condition?: VariableConditionEnum;
|
|
||||||
onChange: (e: string) => void;
|
|
||||||
}) => {
|
|
||||||
const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList);
|
|
||||||
|
|
||||||
// get value type
|
|
||||||
const valueType = useMemo(() => {
|
|
||||||
if (!variable) return;
|
|
||||||
const node = nodeList.find((node) => node.nodeId === variable[0]);
|
|
||||||
|
|
||||||
if (!node) return WorkflowIOValueTypeEnum.any;
|
|
||||||
const output = node.outputs.find((item) => item.id === variable[1]);
|
|
||||||
|
|
||||||
if (!output) return WorkflowIOValueTypeEnum.any;
|
|
||||||
return output.valueType;
|
|
||||||
}, [nodeList, variable]);
|
|
||||||
|
|
||||||
if (valueType === WorkflowIOValueTypeEnum.boolean) {
|
|
||||||
return (
|
|
||||||
<MySelect
|
|
||||||
list={[
|
|
||||||
{ label: 'True', value: 'true' },
|
|
||||||
{ label: 'False', value: 'false' }
|
|
||||||
]}
|
|
||||||
onchange={onChange}
|
|
||||||
value={value}
|
|
||||||
placeholder={'选择值'}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<MyInput
|
|
||||||
value={value}
|
|
||||||
placeholder={'输入值'}
|
|
||||||
w={'100%'}
|
|
||||||
isDisabled={
|
|
||||||
condition === VariableConditionEnum.isEmpty ||
|
|
||||||
condition === VariableConditionEnum.isNotEmpty
|
|
||||||
}
|
|
||||||
onChange={(e) => onChange(e.target.value)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
@@ -0,0 +1,412 @@
|
|||||||
|
import { Box, Button, Flex } from '@chakra-ui/react';
|
||||||
|
import { DraggableProvided, DraggableStateSnapshot } from 'react-beautiful-dnd';
|
||||||
|
import Container from '../../components/Container';
|
||||||
|
import { DragHandleIcon, MinusIcon, SmallAddIcon } from '@chakra-ui/icons';
|
||||||
|
import { IfElseListItemType } from '@fastgpt/global/core/workflow/template/system/ifElse/type';
|
||||||
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
|
import { ReferenceValueProps } from '@fastgpt/global/core/workflow/type/io';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { ReferSelector, useReference } from '../render/RenderInput/templates/Reference';
|
||||||
|
import { WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants';
|
||||||
|
import {
|
||||||
|
VariableConditionEnum,
|
||||||
|
allConditionList,
|
||||||
|
arrayConditionList,
|
||||||
|
booleanConditionList,
|
||||||
|
numberConditionList,
|
||||||
|
stringConditionList
|
||||||
|
} from '@fastgpt/global/core/workflow/template/system/ifElse/constant';
|
||||||
|
import { useContextSelector } from 'use-context-selector';
|
||||||
|
import React, { useMemo } from 'react';
|
||||||
|
import { WorkflowContext } from '../../../context';
|
||||||
|
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||||
|
import MyInput from '@/components/MyInput';
|
||||||
|
import { getHandleId } from '@fastgpt/global/core/workflow/utils';
|
||||||
|
import { SourceHandle } from '../render/Handle';
|
||||||
|
import { Position, useReactFlow } from 'reactflow';
|
||||||
|
|
||||||
|
const ListItem = ({
|
||||||
|
provided,
|
||||||
|
snapshot,
|
||||||
|
conditionIndex,
|
||||||
|
conditionItem,
|
||||||
|
ifElseList,
|
||||||
|
onUpdateIfElseList,
|
||||||
|
nodeId
|
||||||
|
}: {
|
||||||
|
provided: DraggableProvided;
|
||||||
|
snapshot: DraggableStateSnapshot;
|
||||||
|
conditionIndex: number;
|
||||||
|
conditionItem: IfElseListItemType;
|
||||||
|
ifElseList: IfElseListItemType[];
|
||||||
|
onUpdateIfElseList: (value: IfElseListItemType[]) => void;
|
||||||
|
nodeId: string;
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { getZoom } = useReactFlow();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
ref={provided.innerRef}
|
||||||
|
{...provided.draggableProps}
|
||||||
|
style={{
|
||||||
|
...provided.draggableProps.style,
|
||||||
|
opacity: snapshot.isDragging ? 0.8 : 1
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Flex
|
||||||
|
alignItems={'center'}
|
||||||
|
position={'relative'}
|
||||||
|
transform={snapshot.isDragging ? `scale(${getZoom()})` : ''}
|
||||||
|
transformOrigin={'top left'}
|
||||||
|
>
|
||||||
|
<Container w={snapshot.isDragging ? '' : 'full'} className="nodrag">
|
||||||
|
<Flex mb={4} alignItems={'center'}>
|
||||||
|
<Box {...provided.dragHandleProps}>
|
||||||
|
<DragHandleIcon color={'blackAlpha.600'} />
|
||||||
|
</Box>
|
||||||
|
<Box color={'black'} fontSize={'lg'} ml={2}>
|
||||||
|
{conditionIndex === 0 ? 'IF' : 'ELSE IF'}
|
||||||
|
</Box>
|
||||||
|
<Flex
|
||||||
|
px={'2.5'}
|
||||||
|
color={'primary.600'}
|
||||||
|
fontWeight={'medium'}
|
||||||
|
alignItems={'center'}
|
||||||
|
cursor={'pointer'}
|
||||||
|
rounded={'md'}
|
||||||
|
onClick={() => {
|
||||||
|
onUpdateIfElseList(
|
||||||
|
ifElseList.map((ifElse, index) => {
|
||||||
|
if (index === conditionIndex) {
|
||||||
|
return {
|
||||||
|
...ifElse,
|
||||||
|
condition: ifElse.condition === 'AND' ? 'OR' : 'AND'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return ifElse;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{conditionItem.condition}
|
||||||
|
<MyIcon ml={1} boxSize={5} name="change" />
|
||||||
|
</Flex>
|
||||||
|
<Box flex={1}></Box>
|
||||||
|
{ifElseList.length > 1 && (
|
||||||
|
<MyIcon
|
||||||
|
ml={2}
|
||||||
|
boxSize={5}
|
||||||
|
name="delete"
|
||||||
|
cursor={'pointer'}
|
||||||
|
_hover={{ color: 'red.600' }}
|
||||||
|
color={'myGray.400'}
|
||||||
|
onClick={() => {
|
||||||
|
onUpdateIfElseList(ifElseList.filter((_, index) => index !== conditionIndex));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
<Box>
|
||||||
|
{conditionItem.list?.map((item, i) => {
|
||||||
|
return (
|
||||||
|
<Box key={i}>
|
||||||
|
{/* condition list */}
|
||||||
|
<Flex gap={2} mb={2} alignItems={'center'}>
|
||||||
|
{/* variable reference */}
|
||||||
|
<Box minW={'250px'}>
|
||||||
|
<Reference
|
||||||
|
nodeId={nodeId}
|
||||||
|
variable={item.variable}
|
||||||
|
onSelect={(e) => {
|
||||||
|
onUpdateIfElseList(
|
||||||
|
ifElseList.map((ifElse, index) => {
|
||||||
|
if (index === conditionIndex) {
|
||||||
|
return {
|
||||||
|
...ifElse,
|
||||||
|
list: ifElse.list.map((item, index) => {
|
||||||
|
if (index === i) {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
variable: e
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return ifElse;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
{/* condition select */}
|
||||||
|
<Box w={'130px'} flex={1}>
|
||||||
|
<ConditionSelect
|
||||||
|
condition={item.condition}
|
||||||
|
variable={item.variable}
|
||||||
|
onSelect={(e) => {
|
||||||
|
onUpdateIfElseList(
|
||||||
|
ifElseList.map((ifElse, index) => {
|
||||||
|
if (index === conditionIndex) {
|
||||||
|
return {
|
||||||
|
...ifElse,
|
||||||
|
list: ifElse.list.map((item, index) => {
|
||||||
|
if (index === i) {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
condition: e
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return ifElse;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
{/* value */}
|
||||||
|
<Box w={'200px'}>
|
||||||
|
<ConditionValueInput
|
||||||
|
value={item.value}
|
||||||
|
condition={item.condition}
|
||||||
|
variable={item.variable}
|
||||||
|
onChange={(e) => {
|
||||||
|
onUpdateIfElseList(
|
||||||
|
ifElseList.map((ifElse, index) => {
|
||||||
|
if (index === conditionIndex) {
|
||||||
|
return {
|
||||||
|
...ifElse,
|
||||||
|
list: ifElse.list.map((item, index) => {
|
||||||
|
if (index === i) {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
value: e
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return ifElse;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
{/* delete */}
|
||||||
|
{conditionItem.list.length > 1 && (
|
||||||
|
<MinusIcon
|
||||||
|
ml={2}
|
||||||
|
boxSize={3}
|
||||||
|
name="delete"
|
||||||
|
cursor={'pointer'}
|
||||||
|
_hover={{ color: 'red.600' }}
|
||||||
|
color={'myGray.400'}
|
||||||
|
onClick={() => {
|
||||||
|
onUpdateIfElseList(
|
||||||
|
ifElseList.map((ifElse, index) => {
|
||||||
|
if (index === conditionIndex) {
|
||||||
|
return {
|
||||||
|
...ifElse,
|
||||||
|
list: ifElse.list.filter((_, index) => index !== i)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return ifElse;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Box>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
onUpdateIfElseList(
|
||||||
|
ifElseList.map((ifElse, index) => {
|
||||||
|
if (index === conditionIndex) {
|
||||||
|
return {
|
||||||
|
...ifElse,
|
||||||
|
list: ifElse.list.concat({
|
||||||
|
variable: undefined,
|
||||||
|
condition: undefined,
|
||||||
|
value: undefined
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return ifElse;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
variant={'link'}
|
||||||
|
leftIcon={<SmallAddIcon />}
|
||||||
|
my={3}
|
||||||
|
color={'primary.600'}
|
||||||
|
>
|
||||||
|
{t('core.module.input.add')}
|
||||||
|
</Button>
|
||||||
|
</Container>
|
||||||
|
{!snapshot.isDragging && (
|
||||||
|
<SourceHandle
|
||||||
|
nodeId={nodeId}
|
||||||
|
handleId={getHandleId(nodeId, 'source', 'IF' + conditionIndex.toString())}
|
||||||
|
position={Position.Right}
|
||||||
|
translate={[18, 0]}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default React.memo(ListItem);
|
||||||
|
|
||||||
|
const Reference = ({
|
||||||
|
nodeId,
|
||||||
|
variable,
|
||||||
|
onSelect
|
||||||
|
}: {
|
||||||
|
nodeId: string;
|
||||||
|
variable?: ReferenceValueProps;
|
||||||
|
onSelect: (e: ReferenceValueProps) => void;
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const { referenceList, formatValue } = useReference({
|
||||||
|
nodeId,
|
||||||
|
valueType: WorkflowIOValueTypeEnum.any,
|
||||||
|
value: variable
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ReferSelector
|
||||||
|
placeholder={t('选择引用变量')}
|
||||||
|
list={referenceList}
|
||||||
|
value={formatValue}
|
||||||
|
onSelect={onSelect}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Different data types have different options */
|
||||||
|
const ConditionSelect = ({
|
||||||
|
condition,
|
||||||
|
variable,
|
||||||
|
onSelect
|
||||||
|
}: {
|
||||||
|
condition?: VariableConditionEnum;
|
||||||
|
variable?: ReferenceValueProps;
|
||||||
|
onSelect: (e: VariableConditionEnum) => void;
|
||||||
|
}) => {
|
||||||
|
const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList);
|
||||||
|
|
||||||
|
// get condition type
|
||||||
|
const valueType = useMemo(() => {
|
||||||
|
if (!variable) return;
|
||||||
|
const node = nodeList.find((node) => node.nodeId === variable[0]);
|
||||||
|
|
||||||
|
if (!node) return WorkflowIOValueTypeEnum.any;
|
||||||
|
const output = node.outputs.find((item) => item.id === variable[1]);
|
||||||
|
|
||||||
|
if (!output) return WorkflowIOValueTypeEnum.any;
|
||||||
|
return output.valueType;
|
||||||
|
}, [nodeList, variable]);
|
||||||
|
|
||||||
|
const conditionList = useMemo(() => {
|
||||||
|
if (valueType === WorkflowIOValueTypeEnum.string) return stringConditionList;
|
||||||
|
if (valueType === WorkflowIOValueTypeEnum.number) return numberConditionList;
|
||||||
|
if (valueType === WorkflowIOValueTypeEnum.boolean) return booleanConditionList;
|
||||||
|
if (
|
||||||
|
valueType === WorkflowIOValueTypeEnum.chatHistory ||
|
||||||
|
valueType === WorkflowIOValueTypeEnum.datasetQuote ||
|
||||||
|
valueType === WorkflowIOValueTypeEnum.dynamic ||
|
||||||
|
valueType === WorkflowIOValueTypeEnum.selectApp ||
|
||||||
|
valueType === WorkflowIOValueTypeEnum.arrayBoolean ||
|
||||||
|
valueType === WorkflowIOValueTypeEnum.arrayNumber ||
|
||||||
|
valueType === WorkflowIOValueTypeEnum.arrayObject ||
|
||||||
|
valueType === WorkflowIOValueTypeEnum.arrayString ||
|
||||||
|
valueType === WorkflowIOValueTypeEnum.object
|
||||||
|
)
|
||||||
|
return arrayConditionList;
|
||||||
|
|
||||||
|
if (valueType === WorkflowIOValueTypeEnum.any) return allConditionList;
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}, [valueType]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MySelect
|
||||||
|
w={'100%'}
|
||||||
|
list={conditionList}
|
||||||
|
value={condition}
|
||||||
|
onchange={onSelect}
|
||||||
|
placeholder="选择条件"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Different condition can be entered differently
|
||||||
|
empty, notEmpty: forbid input
|
||||||
|
boolean type: select true/false
|
||||||
|
*/
|
||||||
|
const ConditionValueInput = ({
|
||||||
|
value = '',
|
||||||
|
variable,
|
||||||
|
condition,
|
||||||
|
onChange
|
||||||
|
}: {
|
||||||
|
value?: string;
|
||||||
|
variable?: ReferenceValueProps;
|
||||||
|
condition?: VariableConditionEnum;
|
||||||
|
onChange: (e: string) => void;
|
||||||
|
}) => {
|
||||||
|
const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList);
|
||||||
|
|
||||||
|
// get value type
|
||||||
|
const valueType = useMemo(() => {
|
||||||
|
if (!variable) return;
|
||||||
|
const node = nodeList.find((node) => node.nodeId === variable[0]);
|
||||||
|
|
||||||
|
if (!node) return WorkflowIOValueTypeEnum.any;
|
||||||
|
const output = node.outputs.find((item) => item.id === variable[1]);
|
||||||
|
|
||||||
|
if (!output) return WorkflowIOValueTypeEnum.any;
|
||||||
|
return output.valueType;
|
||||||
|
}, [nodeList, variable]);
|
||||||
|
|
||||||
|
if (valueType === WorkflowIOValueTypeEnum.boolean) {
|
||||||
|
return (
|
||||||
|
<MySelect
|
||||||
|
list={[
|
||||||
|
{ label: 'True', value: 'true' },
|
||||||
|
{ label: 'False', value: 'false' }
|
||||||
|
]}
|
||||||
|
onchange={onChange}
|
||||||
|
value={value}
|
||||||
|
placeholder={'选择值'}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<MyInput
|
||||||
|
value={value}
|
||||||
|
placeholder={'输入值'}
|
||||||
|
w={'100%'}
|
||||||
|
bg={'white'}
|
||||||
|
isDisabled={
|
||||||
|
condition === VariableConditionEnum.isEmpty ||
|
||||||
|
condition === VariableConditionEnum.isNotEmpty
|
||||||
|
}
|
||||||
|
onChange={(e) => onChange(e.target.value)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
@@ -0,0 +1,161 @@
|
|||||||
|
import React, { useCallback, useMemo, useState } from 'react';
|
||||||
|
import NodeCard from '../render/NodeCard';
|
||||||
|
import { useTranslation } from 'next-i18next';
|
||||||
|
import { Box, Button, Flex } from '@chakra-ui/react';
|
||||||
|
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||||
|
import { NodeProps, Position } from 'reactflow';
|
||||||
|
import { FlowNodeItemType } from '@fastgpt/global/core/workflow/type';
|
||||||
|
import { IfElseListItemType } from '@fastgpt/global/core/workflow/template/system/ifElse/type';
|
||||||
|
import { useContextSelector } from 'use-context-selector';
|
||||||
|
import { WorkflowContext } from '../../../context';
|
||||||
|
import Container from '../../components/Container';
|
||||||
|
import { DragDropContext, DragStart, Draggable, DropResult, Droppable } from 'react-beautiful-dnd';
|
||||||
|
import { SourceHandle } from '../render/Handle';
|
||||||
|
import { getHandleId } from '@fastgpt/global/core/workflow/utils';
|
||||||
|
import ListItem from './ListItem';
|
||||||
|
|
||||||
|
const NodeIfElse = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { nodeId, inputs = [] } = data;
|
||||||
|
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
|
||||||
|
|
||||||
|
const [draggingItemHeight, setDraggingItemHeight] = useState(0);
|
||||||
|
|
||||||
|
const ifElseList = useMemo(
|
||||||
|
() =>
|
||||||
|
(inputs.find((input) => input.key === NodeInputKeyEnum.ifElseList)
|
||||||
|
?.value as IfElseListItemType[]) || [],
|
||||||
|
[inputs]
|
||||||
|
);
|
||||||
|
|
||||||
|
const onUpdateIfElseList = useCallback(
|
||||||
|
(value: IfElseListItemType[]) => {
|
||||||
|
const ifElseListInput = inputs.find((input) => input.key === NodeInputKeyEnum.ifElseList);
|
||||||
|
if (!ifElseListInput) return;
|
||||||
|
|
||||||
|
onChangeNode({
|
||||||
|
nodeId,
|
||||||
|
type: 'updateInput',
|
||||||
|
key: NodeInputKeyEnum.ifElseList,
|
||||||
|
value: {
|
||||||
|
...ifElseListInput,
|
||||||
|
value
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[inputs, nodeId, onChangeNode]
|
||||||
|
);
|
||||||
|
|
||||||
|
const reorder = (list: IfElseListItemType[], startIndex: number, endIndex: number) => {
|
||||||
|
const result = Array.from(list);
|
||||||
|
const [removed] = result.splice(startIndex, 1);
|
||||||
|
result.splice(endIndex, 0, removed);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDragStart = (start: DragStart) => {
|
||||||
|
const draggingNode = document.querySelector(`[data-rbd-draggable-id="${start.draggableId}"]`);
|
||||||
|
setDraggingItemHeight(draggingNode?.getBoundingClientRect().height || 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDragEnd = (result: DropResult) => {
|
||||||
|
if (!result.destination) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const newList = reorder(ifElseList, result.source.index, result.destination.index);
|
||||||
|
|
||||||
|
onUpdateIfElseList(newList);
|
||||||
|
setDraggingItemHeight(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NodeCard selected={selected} maxW={'1000px'} {...data}>
|
||||||
|
<Box px={4}>
|
||||||
|
<DragDropContext onDragStart={onDragStart} onDragEnd={onDragEnd}>
|
||||||
|
<Droppable
|
||||||
|
droppableId="droppable"
|
||||||
|
renderClone={(provided, snapshot, rubric) => (
|
||||||
|
<ListItem
|
||||||
|
provided={provided}
|
||||||
|
snapshot={snapshot}
|
||||||
|
conditionItem={ifElseList[rubric.source.index]}
|
||||||
|
conditionIndex={rubric.source.index}
|
||||||
|
ifElseList={ifElseList}
|
||||||
|
onUpdateIfElseList={onUpdateIfElseList}
|
||||||
|
nodeId={nodeId}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{(provided, snapshot) => (
|
||||||
|
<Box {...provided.droppableProps} ref={provided.innerRef}>
|
||||||
|
{ifElseList.map((conditionItem, conditionIndex) => (
|
||||||
|
<Draggable
|
||||||
|
key={conditionIndex}
|
||||||
|
draggableId={conditionIndex.toString()}
|
||||||
|
index={conditionIndex}
|
||||||
|
>
|
||||||
|
{(provided, snapshot) => (
|
||||||
|
<ListItem
|
||||||
|
provided={provided}
|
||||||
|
snapshot={snapshot}
|
||||||
|
conditionItem={conditionItem}
|
||||||
|
conditionIndex={conditionIndex}
|
||||||
|
ifElseList={ifElseList}
|
||||||
|
onUpdateIfElseList={onUpdateIfElseList}
|
||||||
|
nodeId={nodeId}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Draggable>
|
||||||
|
))}
|
||||||
|
<Box height={draggingItemHeight} />
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Droppable>
|
||||||
|
</DragDropContext>
|
||||||
|
<Container position={'relative'}>
|
||||||
|
<Flex alignItems={'center'}>
|
||||||
|
<Box color={'black'} fontSize={'lg'} ml={2}>
|
||||||
|
ELSE
|
||||||
|
</Box>
|
||||||
|
<SourceHandle
|
||||||
|
nodeId={nodeId}
|
||||||
|
handleId={getHandleId(nodeId, 'source', 'ELSE')}
|
||||||
|
position={Position.Right}
|
||||||
|
translate={[26, 0]}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
<Box py={3} px={6}>
|
||||||
|
<Button
|
||||||
|
variant={'whiteBase'}
|
||||||
|
w={'full'}
|
||||||
|
onClick={() => {
|
||||||
|
const ifElseListInput = inputs.find(
|
||||||
|
(input) => input.key === NodeInputKeyEnum.ifElseList
|
||||||
|
);
|
||||||
|
if (!ifElseListInput) return;
|
||||||
|
|
||||||
|
onUpdateIfElseList([
|
||||||
|
...ifElseList,
|
||||||
|
{
|
||||||
|
condition: 'AND',
|
||||||
|
list: [
|
||||||
|
{
|
||||||
|
variable: undefined,
|
||||||
|
condition: undefined,
|
||||||
|
value: undefined
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('core.module.input.Add Branch')}
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</NodeCard>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default React.memo(NodeIfElse);
|
Reference in New Issue
Block a user