feat: plugin input type add select and custom var (#2571)

* feat: plugin input type add select and custom var

* fix

* fix ui

* fix

* fix
This commit is contained in:
heheer
2024-08-30 18:03:04 +08:00
committed by GitHub
parent 903f39fe17
commit 9d5fd24085
29 changed files with 591 additions and 367 deletions

View File

@@ -108,15 +108,9 @@ const RenderInput = () => {
<RenderPluginInput
value={value}
onChange={onChange}
label={input.label}
description={input.description}
isDisabled={isDisabledInput}
valueType={input.valueType}
placeholder={input.placeholder}
required={input.required}
min={input.min}
max={input.max}
isInvalid={errors && Object.keys(errors).includes(input.key)}
input={input}
/>
);
}}

View File

@@ -6,10 +6,14 @@ import {
NumberInput,
NumberInputField,
NumberInputStepper,
Select,
Switch,
Textarea
} from '@chakra-ui/react';
import { WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants';
import { FlowNodeInputTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { FlowNodeInputItemType } from '@fastgpt/global/core/workflow/type/io';
import MySelect from '@fastgpt/web/components/common/MySelect';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import { useTranslation } from 'next-i18next';
import dynamic from 'next/dynamic';
@@ -18,58 +22,53 @@ const JsonEditor = dynamic(() => import('@fastgpt/web/components/common/Textarea
const RenderPluginInput = ({
value,
defaultValue,
onChange,
label,
description,
isDisabled,
valueType,
placeholder,
required,
min,
max,
isInvalid
isInvalid,
input
}: {
value: any;
defaultValue?: any;
onChange: () => void;
label: string;
description?: string;
isDisabled?: boolean;
valueType: WorkflowIOValueTypeEnum | undefined;
placeholder?: string;
required?: boolean;
min?: number;
max?: number;
isInvalid: boolean;
input: FlowNodeInputItemType;
}) => {
const { t } = useTranslation();
const inputType = input.renderTypeList[0];
const render = (() => {
if (valueType === WorkflowIOValueTypeEnum.string) {
if (inputType === FlowNodeInputTypeEnum.customVariable) {
return null;
}
if (inputType === FlowNodeInputTypeEnum.select && input.list) {
return (
<MySelect list={input.list} value={value} onchange={onChange} isDisabled={isDisabled} />
);
}
if (input.valueType === WorkflowIOValueTypeEnum.string) {
return (
<Textarea
value={value}
defaultValue={defaultValue}
defaultValue={input.defaultValue}
onChange={onChange}
isDisabled={isDisabled}
placeholder={t(placeholder as any)}
placeholder={t(input.placeholder as any)}
bg={'myGray.50'}
isInvalid={isInvalid}
/>
);
}
if (valueType === WorkflowIOValueTypeEnum.number) {
if (input.valueType === WorkflowIOValueTypeEnum.number) {
return (
<NumberInput
step={1}
min={min}
max={max}
min={input.min}
max={input.max}
bg={'myGray.50'}
isDisabled={isDisabled}
isInvalid={isInvalid}
>
<NumberInputField value={value} onChange={onChange} defaultValue={defaultValue} />
<NumberInputField value={value} onChange={onChange} defaultValue={input.defaultValue} />
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
@@ -77,14 +76,14 @@ const RenderPluginInput = ({
</NumberInput>
);
}
if (valueType === WorkflowIOValueTypeEnum.boolean) {
if (input.valueType === WorkflowIOValueTypeEnum.boolean) {
return (
<Switch
isChecked={value}
onChange={onChange}
isDisabled={isDisabled}
isInvalid={isInvalid}
defaultChecked={defaultValue}
defaultChecked={!!input.defaultValue}
/>
);
}
@@ -92,12 +91,12 @@ const RenderPluginInput = ({
return (
<JsonEditor
bg={'myGray.50'}
placeholder={t(placeholder || ('' as any))}
placeholder={t(input.placeholder as any)}
resize
value={value}
onChange={onChange}
isInvalid={isInvalid}
defaultValue={defaultValue}
defaultValue={input.defaultValue}
/>
);
})();
@@ -106,14 +105,14 @@ const RenderPluginInput = ({
<Box _notLast={{ mb: 4 }} px={1}>
<Flex alignItems={'center'} mb={1}>
<Box position={'relative'}>
{required && (
{input.required && (
<Box position={'absolute'} left={-2} top={'-1px'} color={'red.600'}>
*
</Box>
)}
{label}
{input.label}
</Box>
{description && <QuestionTip ml={2} label={description} />}
{input.description && <QuestionTip ml={2} label={input.description} />}
</Flex>
{render}
</Box>

View File

@@ -378,15 +378,9 @@ const RenderList = React.memo(function RenderList({
return (
<RenderPluginInput
value={value}
onChange={onChange}
label={input.label}
description={input.description}
valueType={input.valueType}
placeholder={input.placeholder}
required={input.required}
min={input.min}
max={input.max}
isInvalid={errors && Object.keys(errors).includes(input.key)}
onChange={onChange}
input={input}
/>
);
}}

View File

@@ -38,7 +38,7 @@ const NodeCode = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
return (
<Box>
<Flex mb={1} alignItems={'flex-end'}>
<Box flex={'1'}>Javascript{workflowT('Code')}</Box>
<Box flex={'1'}>{'Javascript ' + workflowT('Code')}</Box>
<Box
cursor={'pointer'}
color={'primary.500'}

View File

@@ -2,16 +2,15 @@ import React, { useCallback, useMemo } from 'react';
import {
Box,
Button,
ModalFooter,
ModalBody,
Flex,
Switch,
Input,
Textarea,
Stack,
HStack
HStack,
FormControl
} from '@chakra-ui/react';
import { useForm } from 'react-hook-form';
import { useFieldArray, useForm } from 'react-hook-form';
import MyModal from '@fastgpt/web/components/common/MyModal';
import { useTranslation } from 'next-i18next';
import { FlowValueTypeMap } from '@fastgpt/global/core/workflow/node/constant';
@@ -19,9 +18,9 @@ import { FlowNodeInputTypeEnum } from '@fastgpt/global/core/workflow/node/consta
import { useToast } from '@fastgpt/web/hooks/useToast';
import MySelect from '@fastgpt/web/components/common/MySelect';
import { WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants';
import MyIcon from '@fastgpt/web/components/common/Icon';
import dynamic from 'next/dynamic';
import { useI18n } from '@/web/context/I18n';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
import { FlowNodeInputItemType } from '@fastgpt/global/core/workflow/type/io';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
@@ -39,7 +38,9 @@ export const defaultInput: FlowNodeInputItemType = {
valueType: WorkflowIOValueTypeEnum.string,
canEdit: true,
key: '',
label: ''
label: '',
description: '',
defaultValue: ''
};
const FieldEditModal = ({
@@ -56,72 +57,118 @@ const FieldEditModal = ({
onSubmit: (e: { data: FlowNodeInputItemType; isChangeKey: boolean }) => void;
}) => {
const { t } = useTranslation();
const { workflowT } = useI18n();
const { toast } = useToast();
const inputTypeList = useMemo(
() => [
{
label: t('common:core.workflow.inputType.Reference'),
value: FlowNodeInputTypeEnum.reference,
defaultValueType: WorkflowIOValueTypeEnum.string
},
{
label: t('common:core.workflow.inputType.input'),
value: FlowNodeInputTypeEnum.input,
defaultValueType: WorkflowIOValueTypeEnum.string
},
{
label: t('common:core.workflow.inputType.textarea'),
value: FlowNodeInputTypeEnum.textarea,
defaultValueType: WorkflowIOValueTypeEnum.string
},
{
label: t('common:core.workflow.inputType.JSON Editor'),
value: FlowNodeInputTypeEnum.JSONEditor,
defaultValueType: WorkflowIOValueTypeEnum.string
},
{
label: t('common:core.workflow.inputType.number input'),
value: FlowNodeInputTypeEnum.numberInput,
defaultValueType: WorkflowIOValueTypeEnum.number
},
{
label: t('common:core.workflow.inputType.switch'),
value: FlowNodeInputTypeEnum.switch,
defaultValueType: WorkflowIOValueTypeEnum.boolean
},
{
label: t('common:core.workflow.inputType.selectApp'),
value: FlowNodeInputTypeEnum.selectApp,
defaultValueType: WorkflowIOValueTypeEnum.selectApp
},
{
label: t('common:core.workflow.inputType.selectLLMModel'),
value: FlowNodeInputTypeEnum.selectLLMModel,
defaultValueType: WorkflowIOValueTypeEnum.string
},
{
label: t('common:core.workflow.inputType.selectDataset'),
value: FlowNodeInputTypeEnum.selectDataset,
defaultValueType: WorkflowIOValueTypeEnum.selectDataset
},
...(hasDynamicInput
? []
: [
{
label: t('common:core.workflow.inputType.dynamicTargetInput'),
value: FlowNodeInputTypeEnum.addInputParam,
defaultValueType: WorkflowIOValueTypeEnum.dynamic
}
])
],
() =>
[
[
{
icon: 'core/workflow/inputType/reference',
label: t('common:core.workflow.inputType.Reference'),
value: FlowNodeInputTypeEnum.reference,
defaultValueType: WorkflowIOValueTypeEnum.string
},
{
icon: 'core/workflow/inputType/input',
label: t('common:core.workflow.inputType.input'),
value: FlowNodeInputTypeEnum.input,
defaultValueType: WorkflowIOValueTypeEnum.string
},
{
icon: 'core/workflow/inputType/textarea',
label: t('common:core.workflow.inputType.textarea'),
value: FlowNodeInputTypeEnum.textarea,
defaultValueType: WorkflowIOValueTypeEnum.string
},
{
icon: 'core/workflow/inputType/jsonEditor',
label: t('common:core.workflow.inputType.JSON Editor'),
value: FlowNodeInputTypeEnum.JSONEditor,
defaultValueType: WorkflowIOValueTypeEnum.string
},
{
icon: 'core/workflow/inputType/numberInput',
label: t('common:core.workflow.inputType.number input'),
value: FlowNodeInputTypeEnum.numberInput,
defaultValueType: WorkflowIOValueTypeEnum.number
},
{
icon: 'core/workflow/inputType/option',
label: t('common:core.workflow.inputType.select'),
value: FlowNodeInputTypeEnum.select,
defaultValueType: WorkflowIOValueTypeEnum.string
},
{
icon: 'core/workflow/inputType/switch',
label: t('common:core.workflow.inputType.switch'),
value: FlowNodeInputTypeEnum.switch,
defaultValueType: WorkflowIOValueTypeEnum.boolean
}
],
[
{
icon: 'core/workflow/inputType/selectApp',
label: t('common:core.workflow.inputType.selectApp'),
value: FlowNodeInputTypeEnum.selectApp,
defaultValueType: WorkflowIOValueTypeEnum.selectApp
},
{
icon: 'core/workflow/inputType/selectLLM',
label: t('common:core.workflow.inputType.selectLLMModel'),
value: FlowNodeInputTypeEnum.selectLLMModel,
defaultValueType: WorkflowIOValueTypeEnum.string
},
{
icon: 'core/workflow/inputType/selectDataset',
label: t('common:core.workflow.inputType.selectDataset'),
value: FlowNodeInputTypeEnum.selectDataset,
defaultValueType: WorkflowIOValueTypeEnum.selectDataset
},
...(hasDynamicInput
? []
: [
{
icon: 'core/workflow/inputType/dynamic',
label: t('common:core.workflow.inputType.dynamicTargetInput'),
value: FlowNodeInputTypeEnum.addInputParam,
defaultValueType: WorkflowIOValueTypeEnum.dynamic
}
])
],
[
{
icon: 'core/workflow/inputType/customVariable',
label: t('common:core.workflow.inputType.custom'),
value: FlowNodeInputTypeEnum.customVariable,
defaultValueType: WorkflowIOValueTypeEnum.string,
description: t('app:variable.select type_desc')
}
]
] as {
icon: string;
label: string;
value: FlowNodeInputTypeEnum;
defaultValueType: WorkflowIOValueTypeEnum;
description?: string;
}[][],
[hasDynamicInput, t]
);
const isEdit = !!defaultValue.key;
const { register, getValues, setValue, handleSubmit, watch } = useForm({
defaultValues: defaultValue
const { register, getValues, setValue, handleSubmit, watch, control, reset } = useForm({
defaultValues: {
...defaultValue,
list: defaultValue.list?.length ? defaultValue.list : [{ label: '', value: '' }]
}
});
const {
fields: selectEnums,
append: appendEnums,
remove: removeEnums
} = useFieldArray({
control,
name: 'list'
});
const inputType = watch('renderTypeList.0') || FlowNodeInputTypeEnum.reference;
@@ -134,11 +181,13 @@ const FieldEditModal = ({
const min = watch('min');
const selectValueTypeList = watch('customInputConfig.selectValueTypeList');
const showValueTypeSelect = inputType === FlowNodeInputTypeEnum.reference;
const showValueTypeSelect =
inputType === FlowNodeInputTypeEnum.reference ||
inputType === FlowNodeInputTypeEnum.customVariable;
// input type config
const showRequired = useMemo(() => {
const list = [FlowNodeInputTypeEnum.addInputParam];
const list = [FlowNodeInputTypeEnum.addInputParam, FlowNodeInputTypeEnum.customVariable];
return !list.includes(inputType);
}, [inputType]);
const showDefaultValue = useMemo(() => {
@@ -167,11 +216,11 @@ const FieldEditModal = ({
value: item.value
}));
const defaultValueType =
inputTypeList.find((item) => item.value === inputType)?.defaultValueType ||
inputTypeList.flat().find((item) => item.value === inputType)?.defaultValueType ||
WorkflowIOValueTypeEnum.string;
const onSubmitSuccess = useCallback(
(data: FlowNodeInputItemType) => {
(data: FlowNodeInputItemType, action: 'confirm' | 'continue') => {
data.key = data?.key?.trim();
if (!data.key) {
@@ -181,17 +230,27 @@ const FieldEditModal = ({
});
}
if (data.renderTypeList[0] !== FlowNodeInputTypeEnum.reference) {
if (
data.renderTypeList[0] !== FlowNodeInputTypeEnum.reference &&
data.renderTypeList[0] !== FlowNodeInputTypeEnum.customVariable
) {
data.valueType = defaultValueType;
}
if (
data.renderTypeList[0] === FlowNodeInputTypeEnum.addInputParam ||
data.renderTypeList[0] === FlowNodeInputTypeEnum.customVariable
) {
data.required = false;
}
const isChangeKey = defaultValue.key !== data.key;
// create check key
if (keys.includes(data.key)) {
if (!isEdit || isChangeKey) {
toast({
status: 'warning',
title: workflowT('field_name_already_exists')
title: t('workflow:field_name_already_exists')
});
return;
}
@@ -205,11 +264,23 @@ const FieldEditModal = ({
data.label = data.key;
onSubmit({
data,
isChangeKey
});
onClose();
if (action === 'confirm') {
onSubmit({
data,
isChangeKey
});
onClose();
} else if (action === 'continue') {
onSubmit({
data,
isChangeKey
});
toast({
status: 'success',
title: t('common:common.Add Success')
});
reset(defaultInput);
}
},
[
defaultValue.key,
@@ -217,11 +288,11 @@ const FieldEditModal = ({
isEdit,
isToolInput,
keys,
onClose,
onSubmit,
t,
toast,
workflowT
onClose,
reset
]
);
const onSubmitError = useCallback(
@@ -242,206 +313,342 @@ const FieldEditModal = ({
return (
<MyModal
isOpen={true}
onClose={onClose}
iconSrc="/imgs/workflow/extract.png"
title={isEdit ? workflowT('edit_input') : workflowT('add_new_input')}
maxW={['90vw', '800px']}
title={isEdit ? t('workflow:edit_input') : t('workflow:add_new_input')}
maxW={['90vw', '1028px']}
w={'100%'}
>
<ModalBody display={'flex'} gap={8} flexDirection={['column', 'row']}>
<Stack flex={1} gap={5}>
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 70px'}>{t('common:core.module.Input Type')}</FormLabel>
<Box flex={1}>
<MySelect<FlowNodeInputTypeEnum>
list={inputTypeList}
value={inputType}
onchange={(e) => {
setValue('renderTypeList.0', e);
}}
/>
</Box>
</Flex>
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 70px'}>{t('common:core.module.Field Name')}</FormLabel>
<Input
bg={'myGray.50'}
placeholder="appointment/sql"
{...register('key', {
required: true
})}
/>
</Flex>
<Box alignItems={'flex-start'}>
<FormLabel flex={'0 0 70px'} mb={'1px'}>
{workflowT('field_description')}
<Flex h={'560px'}>
<Stack gap={4} p={8}>
<Box alignItems={'center'}>
<FormLabel color={'myGray.600'} fontWeight={'medium'}>
{t('common:core.module.Input Type')}
</FormLabel>
<Textarea
bg={'myGray.50'}
placeholder={workflowT('field_description_placeholder')}
rows={4}
{...register('description', { required: isToolInput ? true : false })}
/>
<Flex flexDirection={'column'} gap={4}>
{inputTypeList.map((list, index) => {
return (
<Box
key={index}
display={'grid'}
gridTemplateColumns={'repeat(3, 1fr)'}
gap={4}
mt={5}
>
{list.map((item) => {
const isSelected = inputType === item.value;
return (
<Box
display={'flex'}
key={item.label}
border={isSelected ? '1px solid #3370FF' : '1px solid #DFE2EA'}
p={3}
rounded={'6px'}
fontWeight={'medium'}
fontSize={'14px'}
alignItems={'center'}
cursor={'pointer'}
boxShadow={
isSelected ? '0px 0px 0px 2.4px rgba(51, 112, 255, 0.15)' : 'none'
}
_hover={{
'& > svg': {
color: 'primary.600'
},
'& > span': {
color: 'myGray.900'
},
border: '1px solid #3370FF',
boxShadow: '0px 0px 0px 2.4px rgba(51, 112, 255, 0.15)'
}}
onClick={() => {
setValue('renderTypeList.0', item.value);
}}
>
<MyIcon
name={item.icon as any}
w={'20px'}
mr={1.5}
color={isSelected ? 'primary.600' : 'myGray.400'}
/>
<Box as="span" color={isSelected ? 'myGray.900' : 'inherit'}>
{item.label}
</Box>
{item.description && <QuestionTip label={item.description} ml={1} />}
</Box>
);
})}
</Box>
);
})}
</Flex>
</Box>
</Stack>
{/* input type config */}
<Stack flex={1} gap={5}>
{/* value type */}
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 70px'}>{t('common:core.module.Data Type')}</FormLabel>
{showValueTypeSelect ? (
<Box flex={1}>
<MySelect<WorkflowIOValueTypeEnum>
list={valueTypeSelectList}
value={valueType}
onchange={(e) => {
setValue('valueType', e);
<Stack flex={1} borderLeft={'1px solid #F0F1F6'} justifyContent={'space-between'}>
<Flex flexDirection={'column'} p={8} gap={4} flex={'1 0 0'} overflow={'auto'}>
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 100px'} fontWeight={'medium'}>
{t('common:core.module.Field Name')}
</FormLabel>
<Input
bg={'myGray.50'}
placeholder="appointment/sql"
{...register('key', {
required: true
})}
/>
</Flex>
<Flex alignItems={'flex-start'}>
<FormLabel flex={'0 0 100px'} fontWeight={'medium'}>
{t('workflow:field_description')}
</FormLabel>
<Textarea
bg={'myGray.50'}
placeholder={t('workflow:field_description_placeholder')}
rows={4}
{...register('description', { required: isToolInput ? true : false })}
/>
</Flex>
{/* value type */}
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 100px'} fontWeight={'medium'}>
{t('common:core.module.Data Type')}
</FormLabel>
{showValueTypeSelect ? (
<Box flex={1}>
<MySelect<WorkflowIOValueTypeEnum>
list={valueTypeSelectList}
value={valueType}
onchange={(e) => {
setValue('valueType', e);
}}
/>
</Box>
) : (
<Box fontSize={'14px'}>{defaultValueType}</Box>
)}
</Flex>
{showRequired && (
<Flex alignItems={'center'} minH={'40px'}>
<FormLabel flex={'1'} fontWeight={'medium'}>
{t('workflow:field_required')}
</FormLabel>
<Switch {...register('required')} />
</Flex>
)}
{/* reference */}
{inputType === FlowNodeInputTypeEnum.reference && (
<>
<Flex alignItems={'center'} minH={'40px'}>
<FormLabel flex={'1'} fontWeight={'medium'}>
{t('workflow:field_used_as_tool_input')}
</FormLabel>
<Switch
isChecked={isToolInput}
onChange={(e) => {
setIsToolInput();
console.log(isToolInput);
}}
/>
</Flex>
</>
)}
{showMaxLenInput && (
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 100px'} fontWeight={'medium'}>
{t('common:core.module.Max Length')}
</FormLabel>
<MyNumberInput
flex={'1 0 0'}
bg={'myGray.50'}
placeholder={t('common:core.module.Max Length placeholder')}
value={maxLength}
onChange={(e) => {
// @ts-ignore
setValue('maxLength', e || '');
}}
/>
</Box>
) : (
defaultValueType
</Flex>
)}
{showMinMaxInput && (
<>
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 100px'} fontWeight={'medium'}>
{t('common:core.module.Max Value')}
</FormLabel>
<MyNumberInput
flex={'1 0 0'}
bg={'myGray.50'}
value={watch('max')}
onChange={(e) => {
// @ts-ignore
setValue('max', e || '');
}}
/>
</Flex>
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 100px'} fontWeight={'medium'}>
{t('common:core.module.Min Value')}
</FormLabel>
<MyNumberInput
flex={'1 0 0'}
bg={'myGray.50'}
value={watch('min')}
onChange={(e) => {
// @ts-ignore
setValue('min', e || '');
}}
/>
</Flex>
</>
)}
{showDefaultValue && (
<Flex alignItems={'center'} minH={'40px'}>
<FormLabel
flex={inputType === FlowNodeInputTypeEnum.switch ? 1 : '0 0 100px'}
fontWeight={'medium'}
>
{t('common:core.module.Default Value')}
</FormLabel>
{inputType === FlowNodeInputTypeEnum.numberInput && (
<Input
bg={'myGray.50'}
max={max}
min={min}
type={'number'}
{...register('defaultValue')}
/>
)}
{inputType === FlowNodeInputTypeEnum.input && (
<Input bg={'myGray.50'} maxLength={maxLength} {...register('defaultValue')} />
)}
{inputType === FlowNodeInputTypeEnum.textarea && (
<Textarea bg={'myGray.50'} maxLength={maxLength} {...register('defaultValue')} />
)}
{inputType === FlowNodeInputTypeEnum.JSONEditor && (
<JsonEditor
bg={'myGray.50'}
resize
w={'full'}
onChange={(e) => {
setValue('defaultValue', e);
}}
defaultValue={String(getValues('defaultValue'))}
/>
)}
{inputType === FlowNodeInputTypeEnum.switch && (
<Switch {...register('defaultValue')} />
)}
</Flex>
)}
{inputType === FlowNodeInputTypeEnum.addInputParam && (
<>
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 100px'} fontWeight={'medium'}>
{t('common:core.module.Input Type')}
</FormLabel>
<Box fontSize={'14px'}>{t('workflow:only_the_reference_type_is_supported')}</Box>
</Flex>
<Box>
<HStack mb={1}>
<FormLabel fontWeight={'medium'}>{t('workflow:optional_value_type')}</FormLabel>
<QuestionTip label={t('workflow:optional_value_type_tip')} />
</HStack>
<MultipleSelect<WorkflowIOValueTypeEnum>
list={valueTypeSelectList}
bg={'myGray.50'}
value={selectValueTypeList || []}
onSelect={(e) => {
setValue('customInputConfig.selectValueTypeList', e);
}}
/>
</Box>
</>
)}
{inputType === FlowNodeInputTypeEnum.select && (
<>
<Flex flexDirection={'column'} gap={4}>
{selectEnums.map((item, i) => (
<Flex key={item.id} alignItems={'center'}>
<FormLabel flex={'0 0 100px'} fontWeight={'medium'}>
{`${t('common:core.module.variable.variable options')} ${i + 1}`}
</FormLabel>
<FormControl>
<Input
fontSize={'12px'}
bg={'myGray.50'}
placeholder={`${t('common:core.module.variable.variable options')} ${i + 1}`}
{...register(`list.${i}.label`, {
required: true,
onChange: (e) => {
setValue(`list.${i}.value`, e.target.value);
}
})}
/>
</FormControl>
{selectEnums.length > 1 && (
<MyIcon
ml={3}
name={'delete'}
w={'16px'}
cursor={'pointer'}
p={2}
borderRadius={'md'}
_hover={{ bg: 'red.100' }}
onClick={() => removeEnums(i)}
/>
)}
</Flex>
))}
</Flex>
<Button
variant={'whiteBase'}
leftIcon={<MyIcon name={'common/addLight'} w={'16px'} />}
onClick={() => appendEnums({ label: '', value: '' })}
fontWeight={'medium'}
fontSize={'12px'}
w={'24'}
py={2}
>
{t('common:core.module.variable add option')}
</Button>
</>
)}
</Flex>
{showRequired && (
<Flex alignItems={'center'} minH={'40px'}>
<FormLabel flex={'1'}>{workflowT('field_required')}</FormLabel>
<Switch {...register('required')} />
</Flex>
)}
{/* reference */}
{inputType === FlowNodeInputTypeEnum.reference && (
<>
<Flex alignItems={'center'} minH={'40px'}>
<FormLabel flex={'1'}>{workflowT('field_used_as_tool_input')}</FormLabel>
<Switch
isChecked={isToolInput}
onChange={(e) => {
setIsToolInput();
}}
/>
</Flex>
</>
)}
{showMaxLenInput && (
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 70px'}>{t('common:core.module.Max Length')}</FormLabel>
<MyNumberInput
flex={'1 0 0'}
bg={'myGray.50'}
placeholder={t('common:core.module.Max Length placeholder')}
value={maxLength}
onChange={(e) => {
// @ts-ignore
setValue('maxLength', e || '');
}}
/>
</Flex>
)}
{showMinMaxInput && (
<>
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 70px'}>{t('common:core.module.Max Value')}</FormLabel>
<MyNumberInput
flex={'1 0 0'}
bg={'myGray.50'}
value={watch('max')}
onChange={(e) => {
// @ts-ignore
setValue('max', e || '');
}}
/>
</Flex>
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 70px'}>{t('common:core.module.Min Value')}</FormLabel>
<MyNumberInput
flex={'1 0 0'}
bg={'myGray.50'}
value={watch('min')}
onChange={(e) => {
// @ts-ignore
setValue('min', e || '');
}}
/>
</Flex>
</>
)}
{showDefaultValue && (
<Flex alignItems={'center'} minH={'40px'}>
<FormLabel flex={inputType === FlowNodeInputTypeEnum.switch ? 1 : '0 0 70px'}>
{t('common:core.module.Default Value')}
</FormLabel>
{inputType === FlowNodeInputTypeEnum.numberInput && (
<Input
bg={'myGray.50'}
max={max}
min={min}
type={'number'}
{...register('defaultValue')}
/>
)}
{inputType === FlowNodeInputTypeEnum.input && (
<Input bg={'myGray.50'} maxLength={maxLength} {...register('defaultValue')} />
)}
{inputType === FlowNodeInputTypeEnum.textarea && (
<Textarea bg={'myGray.50'} maxLength={maxLength} {...register('defaultValue')} />
)}
{inputType === FlowNodeInputTypeEnum.JSONEditor && (
<JsonEditor
bg={'myGray.50'}
resize
w={'full'}
onChange={(e) => {
setValue('defaultValue', e);
}}
defaultValue={String(getValues('defaultValue'))}
/>
)}
{inputType === FlowNodeInputTypeEnum.switch && (
<Switch {...register('defaultValue')} />
)}
</Flex>
)}
{inputType === FlowNodeInputTypeEnum.addInputParam && (
<>
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 70px'}>{t('common:core.module.Input Type')}</FormLabel>
<Box flex={1} fontWeight={'bold'}>
{workflowT('only_the_reference_type_is_supported')}
</Box>
</Flex>
<Box>
<HStack mb={1}>
<FormLabel>{workflowT('optional_value_type')}</FormLabel>
<QuestionTip label={workflowT('optional_value_type_tip')} />
</HStack>
<MultipleSelect<WorkflowIOValueTypeEnum>
list={valueTypeSelectList}
bg={'myGray.50'}
value={selectValueTypeList || []}
onSelect={(e) => {
setValue('customInputConfig.selectValueTypeList', e);
}}
/>
</Box>
</>
)}
<Flex justify={'flex-end'} gap={3} pb={8} pr={8}>
<Button variant={'whiteBase'} fontWeight={'medium'} onClick={onClose} w={20}>
{t('common:common.Close')}
</Button>
<Button
variant={'primaryOutline'}
fontWeight={'medium'}
onClick={handleSubmit((data) => onSubmitSuccess(data, 'confirm'), onSubmitError)}
w={20}
>
{t('common:common.Confirm')}
</Button>
{!isEdit && (
<Button
fontWeight={'medium'}
onClick={handleSubmit((data) => onSubmitSuccess(data, 'continue'), onSubmitError)}
w={20}
>
{t('common:comon.Continue_Adding')}
</Button>
)}
</Flex>
</Stack>
</ModalBody>
<ModalFooter>
<Button variant={'whiteBase'} mr={3} onClick={onClose}>
{t('common:common.Close')}
</Button>
<Button onClick={handleSubmit(onSubmitSuccess, onSubmitError)}>
{t('common:common.Confirm')}
</Button>
</ModalFooter>
</Flex>
</MyModal>
);
};

View File

@@ -36,7 +36,9 @@ const VariableTable = ({
<Tr key={item.key}>
<Td>
<Flex alignItems={'center'}>
{!!item.icon && <MyIcon name={item.icon as any} w={'14px'} mr={1} />}
{!!item.icon && (
<MyIcon name={item.icon as any} w={'14px'} mr={1} color={'primary.600'} />
)}
{item.label || item.key}
</Flex>
</Td>
@@ -48,6 +50,7 @@ const VariableTable = ({
name={'common/settingLight'}
w={'16px'}
cursor={'pointer'}
_hover={{ color: 'primary.600' }}
onClick={() => onEdit(item.key)}
/>
<MyIcon

View File

@@ -174,6 +174,7 @@ const NodeVariableUpdate = ({ data, selected }: NodeProps<FlowNodeItemType>) =>
bg={'white'}
borderRadius={'xs'}
mx={2}
color={'primary.600'}
onClick={() => {
onUpdateList(
updateList.map((update, i) => {