fix: plugin input default value & validate (#2171)

* fix: plugin input default value & validate

* delete console
This commit is contained in:
heheer
2024-07-26 12:41:18 +08:00
committed by GitHub
parent 71d0093768
commit 2d1e53c3b5
3 changed files with 76 additions and 62 deletions

View File

@@ -1,10 +1,11 @@
import React from 'react'; import React, { useEffect } from 'react';
import { Controller } from 'react-hook-form'; import { Controller } from 'react-hook-form';
import RenderPluginInput from './renderPluginInput'; import RenderPluginInput from './renderPluginInput';
import { Button, Flex } from '@chakra-ui/react'; import { Button, Flex } from '@chakra-ui/react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useContextSelector } from 'use-context-selector'; import { useContextSelector } from 'use-context-selector';
import { PluginRunContext } from '../context'; import { PluginRunContext } from '../context';
import { WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants';
const RenderInput = () => { const RenderInput = () => {
const { pluginInputs, variablesForm, histories, onStartChat, onNewChat, onSubmit, isChatting } = const { pluginInputs, variablesForm, histories, onStartChat, onNewChat, onSubmit, isChatting } =
@@ -14,8 +15,21 @@ const RenderInput = () => {
const { const {
control, control,
handleSubmit, handleSubmit,
reset,
formState: { errors } formState: { errors }
} = variablesForm; } = variablesForm;
useEffect(() => {
reset(
pluginInputs.reduce(
(acc, input) => {
acc[input.key] = input.defaultValue;
return acc;
},
{} as Record<string, any>
)
);
}, [pluginInputs, histories]);
const isDisabledInput = histories.length > 0; const isDisabledInput = histories.length > 0;
return ( return (
@@ -26,7 +40,14 @@ const RenderInput = () => {
key={input.key} key={input.key}
control={control} control={control}
name={input.key} name={input.key}
rules={{ required: input.required }} rules={{
validate: (value) => {
if (input.valueType === WorkflowIOValueTypeEnum.boolean) {
return value !== undefined;
}
return !!value;
}
}}
render={({ field: { onChange, value } }) => { render={({ field: { onChange, value } }) => {
return ( return (
<RenderPluginInput <RenderPluginInput

View File

@@ -18,6 +18,7 @@ const JsonEditor = dynamic(() => import('@fastgpt/web/components/common/Textarea
const RenderPluginInput = ({ const RenderPluginInput = ({
value, value,
defaultValue,
onChange, onChange,
label, label,
description, description,
@@ -30,6 +31,7 @@ const RenderPluginInput = ({
isInvalid isInvalid
}: { }: {
value: any; value: any;
defaultValue?: any;
onChange: () => void; onChange: () => void;
label: string; label: string;
description?: string; description?: string;
@@ -48,6 +50,7 @@ const RenderPluginInput = ({
return ( return (
<Textarea <Textarea
value={value} value={value}
defaultValue={defaultValue}
onChange={onChange} onChange={onChange}
isDisabled={isDisabled} isDisabled={isDisabled}
placeholder={t(placeholder as any)} placeholder={t(placeholder as any)}
@@ -66,7 +69,7 @@ const RenderPluginInput = ({
isDisabled={isDisabled} isDisabled={isDisabled}
isInvalid={isInvalid} isInvalid={isInvalid}
> >
<NumberInputField value={value} onChange={onChange} /> <NumberInputField value={value} onChange={onChange} defaultValue={defaultValue} />
<NumberInputStepper> <NumberInputStepper>
<NumberIncrementStepper /> <NumberIncrementStepper />
<NumberDecrementStepper /> <NumberDecrementStepper />
@@ -81,6 +84,7 @@ const RenderPluginInput = ({
onChange={onChange} onChange={onChange}
isDisabled={isDisabled} isDisabled={isDisabled}
isInvalid={isInvalid} isInvalid={isInvalid}
defaultChecked={defaultValue}
/> />
); );
} }
@@ -93,6 +97,7 @@ const RenderPluginInput = ({
value={value} value={value}
onChange={onChange} onChange={onChange}
isInvalid={isInvalid} isInvalid={isInvalid}
defaultValue={defaultValue}
/> />
); );
})(); })();

View File

@@ -36,10 +36,7 @@ import {
getSystemPluginPaths getSystemPluginPaths
} from '@/web/core/app/api/plugin'; } from '@/web/core/app/api/plugin';
import MyBox from '@fastgpt/web/components/common/MyBox'; import MyBox from '@fastgpt/web/components/common/MyBox';
import { WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants'; import { Controller, useForm } from 'react-hook-form';
import { useForm } from 'react-hook-form';
import JsonEditor from '@fastgpt/web/components/common/Textarea/JsonEditor';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import { getTeamPlugTemplates } from '@/web/core/app/api/plugin'; import { getTeamPlugTemplates } from '@/web/core/app/api/plugin';
import { ParentIdType } from '@fastgpt/global/common/parentFolder/type'; import { ParentIdType } from '@fastgpt/global/common/parentFolder/type';
import { AppTypeEnum } from '@fastgpt/global/core/app/constants'; import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
@@ -48,6 +45,8 @@ import FolderPath from '@/components/common/folder/Path';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import CostTooltip from '@/components/core/app/plugin/CostTooltip'; import CostTooltip from '@/components/core/app/plugin/CostTooltip';
import { useSystemStore } from '@/web/common/system/useSystemStore'; import { useSystemStore } from '@/web/common/system/useSystemStore';
import RenderPluginInput from '@/components/core/chat/ChatContainer/PluginRunBox/components/renderPluginInput';
import { WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants';
type Props = { type Props = {
selectedTools: FlowNodeTemplateType[]; selectedTools: FlowNodeTemplateType[];
@@ -189,7 +188,25 @@ const RenderList = React.memo(function RenderList({
const [configTool, setConfigTool] = useState<FlowNodeTemplateType>(); const [configTool, setConfigTool] = useState<FlowNodeTemplateType>();
const onCloseConfigTool = useCallback(() => setConfigTool(undefined), []); const onCloseConfigTool = useCallback(() => setConfigTool(undefined), []);
const { register, getValues, setValue, handleSubmit, reset } = useForm<Record<string, any>>({}); const {
handleSubmit,
reset,
control,
formState: { errors }
} = useForm();
useEffect(() => {
if (configTool) {
const defaultValues = configTool.inputs.reduce(
(acc, input) => {
acc[input.key] = input.defaultValue;
return acc;
},
{} as Record<string, any>
);
reset(defaultValues);
}
}, [configTool, reset]);
const { mutate: onClickAdd, isLoading } = useRequest({ const { mutate: onClickAdd, isLoading } = useRequest({
mutationFn: async (template: FlowNodeTemplateType) => { mutationFn: async (template: FlowNodeTemplateType) => {
@@ -314,66 +331,37 @@ const RenderList = React.memo(function RenderList({
{configTool.inputs {configTool.inputs
.filter((item) => !item.toolDescription) .filter((item) => !item.toolDescription)
.map((input) => { .map((input) => {
const required = input.required || false;
return ( return (
<Box key={input.key} _notLast={{ mb: 4 }} px={1}> <Controller
<Flex position={'relative'} mb={1} alignItems={'center'}> key={input.key}
{t(input.debugLabel || (input.label as any))} control={control}
{input.description && <QuestionTip label={input.description} ml={1} />} name={input.key}
</Flex> rules={{
{(() => { validate: (value) => {
if (input.valueType === WorkflowIOValueTypeEnum.string) { if (input.valueType === WorkflowIOValueTypeEnum.boolean) {
return ( return value !== undefined;
<Textarea
{...register(input.key, {
required
})}
placeholder={t(input.placeholder || ('' as any))}
bg={'myGray.50'}
/>
);
} }
if (input.valueType === WorkflowIOValueTypeEnum.number) { return !!value;
}
}}
render={({ field: { onChange, value } }) => {
return ( return (
<NumberInput <RenderPluginInput
step={input.step} value={value}
onChange={onChange}
label={input.label}
description={input.description}
valueType={input.valueType}
placeholder={input.placeholder}
required={input.required}
min={input.min} min={input.min}
max={input.max} max={input.max}
bg={'myGray.50'} isInvalid={errors && Object.keys(errors).includes(input.key)}
>
<NumberInputField
{...register(input.key, {
required: input.required,
min: input.min,
max: input.max,
valueAsNumber: true
})}
/> />
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
); );
}
if (input.valueType === WorkflowIOValueTypeEnum.boolean) {
return <Switch {...register(input.key, { required })} />;
}
return (
<JsonEditor
bg={'myGray.50'}
placeholder={t(input.placeholder || ('' as any))}
resize
value={getValues(input.key)}
onChange={(e) => {
setValue(input.key, e);
}} }}
/> />
); );
})()}
</Box>
);
})} })}
</ModalBody> </ModalBody>
<ModalFooter gap={6}> <ModalFooter gap={6}>