perf: all plugin variables type support referense & replace input and textarea with prompt editor (#2950)

* support reference as plugin variables

* replace input and textarea with prompt editor

* adjust height & optimize textarea and input

* input select
This commit is contained in:
heheer
2024-10-22 11:21:28 +08:00
committed by GitHub
parent 779ff29ed5
commit 3f34c33d4c
17 changed files with 258 additions and 141 deletions

View File

@@ -267,6 +267,7 @@ export enum NodeOutputKeyEnum {
export enum VariableInputEnum {
input = 'input',
textarea = 'textarea',
textInput = 'textInput',
numberInput = 'numberInput',
select = 'select',
custom = 'custom'
@@ -294,6 +295,12 @@ export const variableMap: Record<
defaultValueType: WorkflowIOValueTypeEnum.string,
description: i18nT('app:variable.textarea_type_desc')
},
[VariableInputEnum.textInput]: {
icon: 'core/workflow/inputType/input',
label: i18nT('common:core.workflow.inputType.textInput'),
value: VariableInputEnum.textInput,
defaultValueType: WorkflowIOValueTypeEnum.string
},
[VariableInputEnum.numberInput]: {
icon: 'core/workflow/inputType/numberInput',
label: i18nT('common:core.workflow.inputType.number input'),

View File

@@ -1,14 +1,13 @@
import { WorkflowIOValueTypeEnum } from '../constants';
import { i18nT } from '../../../../web/i18n/utils';
export enum FlowNodeInputTypeEnum { // render ui
textInput = 'textInput',
reference = 'reference', // reference to other node output
input = 'input', // one line input
numberInput = 'numberInput',
switch = 'switch', // true/false
select = 'select',
// editor
textarea = 'textarea',
JSONEditor = 'JSONEditor',
addInputParam = 'addInputParam', // params input
@@ -27,7 +26,11 @@ export enum FlowNodeInputTypeEnum { // render ui
settingDatasetQuotePrompt = 'settingDatasetQuotePrompt',
hidden = 'hidden',
custom = 'custom'
custom = 'custom',
// deprecated
input = 'input', // one line input
textarea = 'textarea'
}
export const FlowNodeInputMap: Record<
FlowNodeInputTypeEnum,
@@ -35,12 +38,12 @@ export const FlowNodeInputMap: Record<
icon: string;
}
> = {
[FlowNodeInputTypeEnum.textInput]: {
icon: 'core/workflow/inputType/input'
},
[FlowNodeInputTypeEnum.reference]: {
icon: 'core/workflow/inputType/reference'
},
[FlowNodeInputTypeEnum.input]: {
icon: 'core/workflow/inputType/input'
},
[FlowNodeInputTypeEnum.numberInput]: {
icon: 'core/workflow/inputType/numberInput'
},
@@ -50,9 +53,6 @@ export const FlowNodeInputMap: Record<
[FlowNodeInputTypeEnum.switch]: {
icon: 'core/workflow/inputType/switch'
},
[FlowNodeInputTypeEnum.textarea]: {
icon: 'core/workflow/inputType/textarea'
},
[FlowNodeInputTypeEnum.JSONEditor]: {
icon: 'core/workflow/inputType/jsonEditor'
},
@@ -85,6 +85,12 @@ export const FlowNodeInputMap: Record<
},
[FlowNodeInputTypeEnum.custom]: {
icon: 'core/workflow/inputType/custom'
},
[FlowNodeInputTypeEnum.input]: {
icon: 'core/workflow/inputType/input'
},
[FlowNodeInputTypeEnum.textarea]: {
icon: 'core/workflow/inputType/textarea'
}
};

View File

@@ -230,6 +230,10 @@ export const appData2FlowNodeIO = ({
FlowNodeInputTypeEnum.textarea,
FlowNodeInputTypeEnum.reference
],
[VariableInputEnum.textInput]: [
FlowNodeInputTypeEnum.textInput,
FlowNodeInputTypeEnum.reference
],
[VariableInputEnum.numberInput]: [FlowNodeInputTypeEnum.numberInput],
[VariableInputEnum.select]: [FlowNodeInputTypeEnum.select],
[VariableInputEnum.custom]: [

View File

@@ -36,6 +36,11 @@ const NodeInputSelect = ({
icon: FlowNodeInputMap[FlowNodeInputTypeEnum.input].icon,
title: t('common:core.workflow.inputType.Manual input')
},
{
type: FlowNodeInputTypeEnum.textInput,
icon: FlowNodeInputMap[FlowNodeInputTypeEnum.input].icon,
title: t('common:core.workflow.inputType.Manual input')
},
{
type: FlowNodeInputTypeEnum.numberInput,
icon: FlowNodeInputMap[FlowNodeInputTypeEnum.numberInput].icon,

View File

@@ -800,6 +800,7 @@
"core.workflow.inputType.selectDataset": "Dataset Select",
"core.workflow.inputType.selectLLMModel": "Chat Model Select",
"core.workflow.inputType.switch": "Switch",
"core.workflow.inputType.textInput": "Text Input box",
"core.workflow.inputType.textarea": "Multi-line Input Box",
"core.workflow.publish.OnRevert version": "Click to Revert to This Version",
"core.workflow.publish.OnRevert version confirm": "Confirm to Revert to This Version? The configuration of the editing version will be saved, and a new release version will be created for the reverted version.",

View File

@@ -2,8 +2,8 @@
"Array_element": "Array element",
"Code": "Code",
"Confirm_sync_node": "It will be updated to the latest node configuration and fields that do not exist in the template will be deleted (including all custom fields).\n\nIf the fields are complex, it is recommended that you copy a node first and then update the original node to facilitate parameter copying.",
"Node_variables": "Node variables",
"Node.Open_Node_Course": "Open node course",
"Node_variables": "Node variables",
"Quote_prompt_setting": "Quote prompt",
"Variable.Variable type": "Variable type",
"Variable_name": "Variable name",
@@ -54,6 +54,7 @@
"field_description_placeholder": "Describe the function of this input field. If it is a tool call parameter, this description will affect the quality of the model generation.",
"field_name_already_exists": "Field name already exists",
"field_required": "Required",
"field_used_as_reference": "Support reference",
"field_used_as_tool_input": "Used as Tool Call Parameter",
"filter_description": "Currently supports filtering by tags and creation time. Fill in the format as follows:\n{\n \"tags\": {\n \"$and\": [\"Tag 1\",\"Tag 2\"],\n \"$or\": [\"When there are $and tags, and is effective, or is not effective\"]\n },\n \"createTime\": {\n \"$gte\": \"YYYY-MM-DD HH:mm format, collection creation time greater than this time\",\n \"$lte\": \"YYYY-MM-DD HH:mm format, collection creation time less than this time, can be used with $gte\"\n }\n}",
"form_input_result": "User complete input result",

View File

@@ -805,6 +805,7 @@
"core.workflow.inputType.selectDataset": "知识库选择",
"core.workflow.inputType.selectLLMModel": "对话模型选择",
"core.workflow.inputType.switch": "开关",
"core.workflow.inputType.textInput": "文本输入框",
"core.workflow.inputType.textarea": "多行输入框",
"core.workflow.publish.OnRevert version": "点击回退到该版本",
"core.workflow.publish.OnRevert version confirm": "确认回退至该版本?会为您保存编辑中版本的配置,并为回退版本创建一个新的发布版本。",

View File

@@ -2,8 +2,8 @@
"Array_element": "数组元素",
"Code": "代码",
"Confirm_sync_node": "将会更新至最新的节点配置,不存在模板中的字段将会被删除(包括所有自定义字段)。\n如果字段较为复杂建议您先复制一份节点再更新原来的节点便于参数复制。",
"Node_variables": "节点变量",
"Node.Open_Node_Course": "查看节点教程",
"Node_variables": "节点变量",
"Quote_prompt_setting": "引用提示词配置",
"Variable.Variable type": "变量类型",
"Variable_name": "变量名",
@@ -55,6 +55,7 @@
"field_description_placeholder": "描述该输入字段的功能,如果为工具调用参数,则该描述会影响模型生成的质量",
"field_name_already_exists": "字段名已经存在",
"field_required": "必填",
"field_used_as_reference": "支持变量引用",
"field_used_as_tool_input": "作为工具调用参数",
"filter_description": "目前支持标签和创建时间过滤,需按照以下格式填写:\n{\n \"tags\": {\n \"$and\": [\"标签 1\",\"标签 2\"],\n \"$or\": [\"有 $and 标签时and 生效or 不生效\"]\n },\n \"createTime\": {\n \"$gte\": \"YYYY-MM-DD HH:mm 格式即可,集合的创建时间大于该时间\",\n \"$lte\": \"YYYY-MM-DD HH:mm 格式即可,集合的创建时间小于该时间,可和 $gte 共同使用\"\n }\n}",
"form_input_result": "用户完整输入结果",

View File

@@ -36,7 +36,7 @@ export const defaultVariable: VariableItemType = {
id: nanoid(),
key: '',
label: '',
type: VariableInputEnum.input,
type: VariableInputEnum.textInput,
description: '',
required: true,
valueType: WorkflowIOValueTypeEnum.string
@@ -72,13 +72,18 @@ const VariableEdit = ({
const inputTypeList = useMemo(
() =>
Object.values(variableMap).map((item) => ({
icon: item.icon,
label: t(item.label as any),
value: item.value,
defaultValueType: item.defaultValueType,
description: item.description ? t(item.description as any) : ''
})),
Object.values(variableMap)
.filter(
(item) =>
item.value !== VariableInputEnum.input && item.value !== VariableInputEnum.textarea
)
.map((item) => ({
icon: item.icon,
label: t(item.label as any),
value: item.value,
defaultValueType: item.defaultValueType,
description: item.description ? t(item.description as any) : ''
})),
[t]
);

View File

@@ -24,6 +24,7 @@ import { ChatBoxContext } from '../Provider';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import { useDeepCompareEffect } from 'ahooks';
import { VariableItemType } from '@fastgpt/global/core/app/type';
import PromptEditor from '@fastgpt/web/components/common/Textarea/PromptEditor';
export const VariableInputItem = ({
item,
@@ -77,6 +78,16 @@ export const VariableInputItem = ({
maxLength={item.maxLength || 4000}
/>
)}
{item.type === VariableInputEnum.textInput && (
<PromptEditor
value={item.defaultValue}
onChange={(e) => setValue(item.key, e)}
bg={'myGray.50'}
minH={50}
maxH={150}
showOpenModal={false}
/>
)}
{item.type === VariableInputEnum.select && (
<Controller
key={item.key}

View File

@@ -38,6 +38,7 @@ import { FlowNodeInputTypeEnum } from '@fastgpt/global/core/workflow/node/consta
import { useTranslation } from 'react-i18next';
import { Controller, useForm } from 'react-hook-form';
import MySelect from '@fastgpt/web/components/common/MySelect';
import PromptEditor from '@fastgpt/web/components/common/Textarea/PromptEditor';
type props = {
value: UserChatItemValueItemType | AIChatItemValueItemType;
@@ -240,6 +241,15 @@ const RenderUserFormInteractive = React.memo(function RenderFormInput({
maxLength={input.maxLength || 4000}
/>
)}
{input.type === FlowNodeInputTypeEnum.textInput && (
<PromptEditor
value={input.value}
onChange={(e) => setValue(input.label, e)}
minH={40}
maxH={100}
showOpenModal={false}
/>
)}
{input.type === FlowNodeInputTypeEnum.numberInput && (
<NumberInput
step={1}

View File

@@ -13,7 +13,6 @@ import {
Box,
Button,
Flex,
Textarea,
NumberDecrementStepper,
NumberIncrementStepper,
NumberInput,
@@ -34,6 +33,7 @@ import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { AppContext } from '../../../context';
import { VariableInputItem } from '@/components/core/chat/ChatContainer/ChatBox/components/VariableInput';
import LightRowTabs from '@fastgpt/web/components/common/Tabs/LightRowTabs';
import PromptEditor from '@fastgpt/web/components/common/Textarea/PromptEditor';
const MyRightDrawer = dynamic(
() => import('@fastgpt/web/components/common/MyDrawer/MyRightDrawer')
@@ -270,10 +270,14 @@ export const useDebug = () => {
const RenderInput = (() => {
if (input.valueType === WorkflowIOValueTypeEnum.string) {
return (
<Textarea
{...register(`nodeVariables.${input.key}`, {
required
})}
<PromptEditor
value={getValues(`nodeVariables.${input.key}`)}
onChange={(e) => {
setValue(`nodeVariables.${input.key}`, e);
}}
minH={50}
maxH={150}
showOpenModal={false}
placeholder={t(input.placeholder || ('' as any))}
bg={'myGray.50'}
/>

View File

@@ -11,7 +11,7 @@ import { useToast } from '@fastgpt/web/hooks/useToast';
import InputTypeConfig from '../NodePluginIO/InputTypeConfig';
export const defaultFormInput: UserInputFormItemType = {
type: FlowNodeInputTypeEnum.input,
type: FlowNodeInputTypeEnum.textInput,
key: '',
label: '',
description: '',
@@ -54,14 +54,8 @@ const InputFormEditModal = ({
const inputTypeList = [
{
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,
label: t('common:core.workflow.inputType.textInput'),
value: FlowNodeInputTypeEnum.textInput,
defaultValueType: WorkflowIOValueTypeEnum.string
},
{

View File

@@ -54,14 +54,8 @@ const FieldEditModal = ({
},
{
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,
label: t('common:core.workflow.inputType.textInput'),
value: FlowNodeInputTypeEnum.textInput,
defaultValueType: WorkflowIOValueTypeEnum.string
},
{
@@ -138,11 +132,24 @@ const FieldEditModal = ({
});
const { getValues, setValue, watch, reset } = form;
const inputType = watch('renderTypeList.0') || FlowNodeInputTypeEnum.reference;
const renderTypeList = watch('renderTypeList');
const inputType = renderTypeList[0] || FlowNodeInputTypeEnum.reference;
const valueType = watch('valueType');
const [isToolInput, { toggle: setIsToolInput }] = useBoolean(!!getValues('toolDescription'));
const isRefrence = renderTypeList.includes(FlowNodeInputTypeEnum.reference);
const setIsRefrence = () => {
if (isRefrence) {
setValue(
'renderTypeList',
renderTypeList.filter((item) => item !== FlowNodeInputTypeEnum.reference)
);
} else {
setValue('renderTypeList', [...getValues('renderTypeList'), FlowNodeInputTypeEnum.reference]);
}
};
const maxLength = watch('maxLength');
const max = watch('max');
const min = watch('min');
@@ -328,6 +335,8 @@ const FieldEditModal = ({
defaultValue={defaultInputValue}
isToolInput={isToolInput}
setIsToolInput={setIsToolInput}
isRefrence={isRefrence}
setIsRefrence={setIsRefrence}
valueType={valueType}
defaultValueType={defaultValueType}
onSubmitSuccess={onSubmitSuccess}

View File

@@ -34,6 +34,7 @@ import { useFieldArray, UseFormReturn } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import MyIcon from '@fastgpt/web/components/common/Icon';
import DndDrag, { Draggable } from '@fastgpt/web/components/common/DndDrag';
import PromptEditor from '@fastgpt/web/components/common/Textarea/PromptEditor';
type ListValueType = { id: string; value: string; label: string }[];
@@ -50,6 +51,8 @@ const InputTypeConfig = ({
defaultValue,
isToolInput,
setIsToolInput,
isRefrence,
setIsRefrence,
valueType,
defaultValueType,
onSubmitSuccess,
@@ -72,6 +75,8 @@ const InputTypeConfig = ({
// Plugin-specific fields
isToolInput?: boolean;
setIsToolInput?: () => void;
isRefrence?: boolean;
setIsRefrence?: () => void;
valueType?: WorkflowIOValueTypeEnum;
defaultValueType?: WorkflowIOValueTypeEnum;
@@ -132,7 +137,7 @@ const InputTypeConfig = ({
}, [inputType]);
const showMaxLenInput = useMemo(() => {
const list = [FlowNodeInputTypeEnum.input, FlowNodeInputTypeEnum.textarea];
const list = [FlowNodeInputTypeEnum.textInput];
return list.includes(inputType as FlowNodeInputTypeEnum);
}, [inputType]);
@@ -143,8 +148,7 @@ const InputTypeConfig = ({
const showDefaultValue = useMemo(() => {
const list = [
FlowNodeInputTypeEnum.input,
FlowNodeInputTypeEnum.textarea,
FlowNodeInputTypeEnum.textInput,
FlowNodeInputTypeEnum.JSONEditor,
FlowNodeInputTypeEnum.numberInput,
FlowNodeInputTypeEnum.switch,
@@ -158,7 +162,7 @@ const InputTypeConfig = ({
<Stack flex={1} borderLeft={'1px solid #F0F1F6'} justifyContent={'space-between'}>
<Flex flexDirection={'column'} p={8} pb={2} gap={4} flex={'1 0 0'} overflow={'auto'}>
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 100px'} fontWeight={'medium'}>
<FormLabel flex={'0 0 132px'} fontWeight={'medium'}>
{typeLabels.name[type] || typeLabels.name.formInput}
</FormLabel>
<Input
@@ -170,7 +174,7 @@ const InputTypeConfig = ({
/>
</Flex>
<Flex alignItems={'flex-start'}>
<FormLabel flex={'0 0 100px'} fontWeight={'medium'}>
<FormLabel flex={'0 0 132px'} fontWeight={'medium'}>
{typeLabels.description[type] || typeLabels.description.plugin}
</FormLabel>
<Textarea
@@ -184,7 +188,7 @@ const InputTypeConfig = ({
{/* value type */}
{type !== 'formInput' && (
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 100px'} fontWeight={'medium'}>
<FormLabel flex={'0 0 132px'} fontWeight={'medium'}>
{t('common:core.module.Data Type')}
</FormLabel>
{showValueTypeSelect ? (
@@ -208,18 +212,33 @@ const InputTypeConfig = ({
)}
{showRequired && (
<Flex alignItems={'center'} minH={'40px'}>
<FormLabel flex={'0 0 100px'} fontWeight={'medium'}>
<FormLabel flex={'0 0 132px'} fontWeight={'medium'}>
{t('workflow:field_required')}
</FormLabel>
<Switch {...register('required')} />
</Flex>
)}
{/* reference */}
{inputType === FlowNodeInputTypeEnum.reference && (
{inputType !== FlowNodeInputTypeEnum.reference && setIsRefrence && (
<>
<Flex alignItems={'center'} minH={'40px'}>
<FormLabel flex={'1'} fontWeight={'medium'}>
<FormLabel flex={'0 0 132px'} fontWeight={'medium'}>
{t('workflow:field_used_as_reference')}
</FormLabel>
<Switch
isChecked={isRefrence}
onChange={(e) => {
setIsRefrence();
}}
/>
</Flex>
</>
)}
{/* reference */}
{(inputType === FlowNodeInputTypeEnum.reference || isRefrence) && (
<>
<Flex alignItems={'center'} minH={'40px'}>
<FormLabel flex={'0 0 132px'} fontWeight={'medium'}>
{t('workflow:field_used_as_tool_input')}
</FormLabel>
<Switch
@@ -234,7 +253,7 @@ const InputTypeConfig = ({
{showMaxLenInput && (
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 100px'} fontWeight={'medium'}>
<FormLabel flex={'0 0 132px'} fontWeight={'medium'}>
{t('common:core.module.Max Length')}
</FormLabel>
<MyNumberInput
@@ -254,7 +273,7 @@ const InputTypeConfig = ({
{showMinMaxInput && (
<>
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 100px'} fontWeight={'medium'}>
<FormLabel flex={'0 0 132px'} fontWeight={'medium'}>
{t('common:core.module.Max Value')}
</FormLabel>
<MyNumberInput
@@ -268,7 +287,7 @@ const InputTypeConfig = ({
/>
</Flex>
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 100px'} fontWeight={'medium'}>
<FormLabel flex={'0 0 132px'} fontWeight={'medium'}>
{t('common:core.module.Min Value')}
</FormLabel>
<MyNumberInput
@@ -286,70 +305,77 @@ const InputTypeConfig = ({
{showDefaultValue && (
<Flex alignItems={'center'} minH={'40px'}>
<FormLabel
flex={inputType === FlowNodeInputTypeEnum.switch ? 1 : '0 0 100px'}
fontWeight={'medium'}
>
<FormLabel flex={'0 0 132px'} fontWeight={'medium'}>
{t('common:core.module.Default Value')}
</FormLabel>
{inputType === FlowNodeInputTypeEnum.numberInput && (
<NumberInput flex={1} step={1} min={min} max={max} position={'relative'}>
<NumberInputField
{...register('defaultValue', {
min: min,
max: max
})}
<Flex alignItems={'start'} flex={1} h={10}>
{inputType === FlowNodeInputTypeEnum.numberInput && (
<NumberInput flex={1} step={1} min={min} max={max} position={'relative'}>
<NumberInputField
{...register('defaultValue', {
min: min,
max: max
})}
/>
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
)}
{inputType === FlowNodeInputTypeEnum.textInput && (
<PromptEditor
value={defaultValue}
onChange={(e) => {
setValue('defaultValue', e);
}}
minH={40}
maxH={200}
showOpenModal={false}
bg={'myGray.50'}
/>
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
)}
{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={defaultValue}
/>
)}
{inputType === FlowNodeInputTypeEnum.switch && <Switch {...register('defaultValue')} />}
{inputType === FlowNodeInputTypeEnum.select && (
<MySelect<string>
list={[defaultListValue, ...listValue]
.filter((item) => item.label !== '')
.map((item) => ({
label: item.label,
value: item.value
}))}
value={
defaultValue && listValue.map((item) => item.value).includes(defaultValue)
? defaultValue
: ''
}
onchange={(e) => {
setValue('defaultValue', e);
}}
w={'200px'}
/>
)}
)}
{inputType === FlowNodeInputTypeEnum.JSONEditor && (
<JsonEditor
bg={'myGray.50'}
resize
w={'full'}
onChange={(e) => {
setValue('defaultValue', e);
}}
defaultValue={defaultValue}
/>
)}
{inputType === FlowNodeInputTypeEnum.switch && (
<Switch {...register('defaultValue')} />
)}
{inputType === FlowNodeInputTypeEnum.select && (
<MySelect<string>
list={[defaultListValue, ...listValue]
.filter((item) => item.label !== '')
.map((item) => ({
label: item.label,
value: item.value
}))}
value={
defaultValue && listValue.map((item) => item.value).includes(defaultValue)
? defaultValue
: ''
}
onchange={(e) => {
setValue('defaultValue', e);
}}
w={'200px'}
/>
)}
</Flex>
</Flex>
)}
{inputType === FlowNodeInputTypeEnum.addInputParam && (
<>
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 100px'} fontWeight={'medium'}>
<FormLabel flex={'0 0 132px'} fontWeight={'medium'}>
{t('common:core.module.Input Type')}
</FormLabel>
<Box fontSize={'14px'}>{t('workflow:only_the_reference_type_is_supported')}</Box>
@@ -432,7 +458,7 @@ const InputTypeConfig = ({
transform={snapshot.isDragging ? `scale(0.5)` : ''}
transformOrigin={'top left'}
>
<FormLabel flex={'0 0 100px'} fontWeight={'medium'}>
<FormLabel flex={'0 0 132px'} fontWeight={'medium'}>
{`${t('common:core.module.variable.variable options')} ${i + 1}`}
</FormLabel>
<FormControl>

View File

@@ -16,10 +16,6 @@ const RenderList: {
types: [FlowNodeInputTypeEnum.reference],
Component: dynamic(() => import('./templates/Reference'))
},
{
types: [FlowNodeInputTypeEnum.input],
Component: dynamic(() => import('./templates/TextInput'))
},
{
types: [FlowNodeInputTypeEnum.select],
Component: dynamic(() => import('./templates/Select'))
@@ -33,8 +29,8 @@ const RenderList: {
Component: dynamic(() => import('./templates/Switch'))
},
{
types: [FlowNodeInputTypeEnum.textarea],
Component: dynamic(() => import('./templates/Textarea'))
types: [FlowNodeInputTypeEnum.textInput],
Component: dynamic(() => import('./templates/TextInput'))
},
{
types: [FlowNodeInputTypeEnum.selectApp],
@@ -67,6 +63,14 @@ const RenderList: {
{
types: [FlowNodeInputTypeEnum.settingDatasetQuotePrompt],
Component: dynamic(() => import('./templates/SettingQuotePrompt'))
},
{
types: [FlowNodeInputTypeEnum.input],
Component: dynamic(() => import('./templates/TextInput'))
},
{
types: [FlowNodeInputTypeEnum.textarea],
Component: dynamic(() => import('./templates/Textarea'))
}
];

View File

@@ -1,37 +1,65 @@
import React, { useMemo } from 'react';
import React, { useCallback, useMemo } from 'react';
import type { RenderInputProps } from '../type';
import { Input } from '@chakra-ui/react';
import { useTranslation } from 'next-i18next';
import PromptEditor from '@fastgpt/web/components/common/Textarea/PromptEditor';
import { useContextSelector } from 'use-context-selector';
import { WorkflowContext } from '@/pages/app/detail/components/WorkflowComponents/context';
import { useTranslation } from 'next-i18next';
import { useCreation } from 'ahooks';
import { AppContext } from '@/pages/app/detail/components/context';
import { getEditorVariables } from '../../../../../utils';
const TextInput = ({ item, nodeId }: RenderInputProps) => {
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
const TextInputRender = ({ inputs = [], item, nodeId }: RenderInputProps) => {
const { t } = useTranslation();
const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList);
const edges = useContextSelector(WorkflowContext, (v) => v.edges);
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
const { appDetail } = useContextSelector(AppContext, (v) => v);
// get variable
const variables = useCreation(() => {
return getEditorVariables({
nodeId,
nodeList,
edges,
appDetail,
t
});
}, [nodeId, nodeList, edges, appDetail, t]);
const onChange = useCallback(
(e: string) => {
onChangeNode({
nodeId,
type: 'updateInput',
key: item.key,
value: {
...item,
value: e
}
});
},
[item, nodeId, onChangeNode]
);
const Render = useMemo(() => {
return (
<Input
placeholder={t(item.placeholder as any) ?? t(item.description as any)}
defaultValue={item.value}
bg={'white'}
px={3}
borderRadius={'sm'}
onBlur={(e) => {
onChangeNode({
nodeId,
type: 'updateInput',
key: item.key,
value: {
...item,
value: e.target.value
}
});
}}
<PromptEditor
variableLabels={variables}
variables={variables}
title={t(item.label as any)}
maxLength={item.maxLength}
minH={40}
maxH={120}
placeholder={t((item.placeholder as any) || '')}
value={item.value}
onChange={onChange}
isFlow={true}
/>
);
}, [item, nodeId, onChangeNode, t]);
}, [item.label, item.maxLength, item.placeholder, item.value, onChange, t, variables]);
return Render;
};
export default React.memo(TextInput);
export default React.memo(TextInputRender);