Global variables support external variable; Extract module support default value (#921)

This commit is contained in:
Archer
2024-03-05 14:13:22 +08:00
committed by GitHub
parent 42a8184ea0
commit af581bc903
30 changed files with 306 additions and 200 deletions

View File

@@ -178,7 +178,7 @@ export const FlowProvider = ({
const source = nodes.find((node) => node.id === connect.source)?.data;
const sourceType = (() => {
if (source?.flowType === FlowNodeTypeEnum.classifyQuestion) {
return ModuleIOValueTypeEnum.string;
return ModuleIOValueTypeEnum.boolean;
}
if (source?.flowType === FlowNodeTypeEnum.pluginInput) {
return source?.inputs.find((input) => input.key === connect.sourceHandle)?.valueType;
@@ -189,7 +189,7 @@ export const FlowProvider = ({
const targetType = nodes
.find((node) => node.id === connect.target)
?.data?.inputs.find((input) => input.key === connect.targetHandle)?.valueType;
console.log(source, targetType);
if (!sourceType || !targetType) {
return toast({
status: 'warning',

View File

@@ -25,7 +25,7 @@ import {
useDisclosure
} from '@chakra-ui/react';
import { QuestionOutlineIcon, SmallAddIcon } from '@chakra-ui/icons';
import { VariableInputEnum } from '@fastgpt/global/core/module/constants';
import { VariableInputEnum, variableMap } from '@fastgpt/global/core/module/constants';
import type { VariableItemType } from '@fastgpt/global/core/module/type.d';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { useForm } from 'react-hook-form';
@@ -52,23 +52,12 @@ const VariableEdit = ({
const [refresh, setRefresh] = useState(false);
const VariableTypeList = useMemo(
() => [
{
title: t('core.module.variable.input type'),
icon: 'core/app/variable/input',
value: VariableInputEnum.input
},
{
title: t('core.module.variable.textarea type'),
icon: 'core/app/variable/textarea',
value: VariableInputEnum.textarea
},
{
title: t('core.module.variable.select type'),
icon: 'core/app/variable/select',
value: VariableInputEnum.select
}
],
() =>
Object.entries(variableMap).map(([key, value]) => ({
title: t(value.title),
icon: value.icon,
value: key
})),
[t]
);
@@ -79,9 +68,12 @@ const VariableEdit = ({
getValues: getValuesEdit,
setValue: setValuesEdit,
control: editVariableController,
handleSubmit: handleSubmitEdit
handleSubmit: handleSubmitEdit,
watch
} = useForm<{ variable: VariableItemType }>();
const variableType = watch('variable.type');
const {
fields: selectEnums,
append: appendEnums,
@@ -140,11 +132,11 @@ const VariableEdit = ({
<Table bg={'white'}>
<Thead>
<Tr>
<Th w={'18px !important'} p={0} />
<Th>{t('core.module.variable.variable name')}</Th>
<Th>{t('core.module.variable.key')}</Th>
<Th>{t('common.Require Input')}</Th>
<Th></Th>
<Th w={'18px !important'} p={0} bg={'myGray.50'} />
<Th bg={'myGray.50'}>{t('core.module.variable.variable name')}</Th>
<Th bg={'myGray.50'}>{t('core.module.variable.key')}</Th>
<Th bg={'myGray.50'}>{t('common.Require Input')}</Th>
<Th bg={'myGray.50'}></Th>
</Tr>
</Thead>
<Tbody>
@@ -188,12 +180,15 @@ const VariableEdit = ({
title={t('core.module.Variable Setting')}
isOpen={isOpenEdit}
onClose={onCloseEdit}
maxW={['90vw', '500px']}
>
<ModalBody>
<Flex alignItems={'center'}>
<Box w={'70px'}>{t('common.Require Input')}</Box>
<Switch {...registerEdit('variable.required')} />
</Flex>
{variableType !== VariableInputEnum.external && (
<Flex alignItems={'center'}>
<Box w={'70px'}>{t('common.Require Input')}</Box>
<Switch {...registerEdit('variable.required')} />
</Flex>
)}
<Flex mt={5} alignItems={'center'}>
<Box w={'80px'}>{t('core.module.variable.variable name')}</Box>
<Input
@@ -216,8 +211,8 @@ const VariableEdit = ({
</Box>
<MyRadio
gridGap={4}
gridTemplateColumns={'repeat(3,1fr)'}
value={getValuesEdit('variable.type')}
gridTemplateColumns={'repeat(2,1fr)'}
value={variableType}
list={VariableTypeList}
color={'myGray.600'}
hiddenCircle
@@ -227,7 +222,14 @@ const VariableEdit = ({
}}
/>
{getValuesEdit('variable.type') === VariableInputEnum.input && (
{/* desc */}
{variableMap[variableType]?.desc && (
<Box mt={2} fontSize={'sm'} color={'myGray.500'} whiteSpace={'pre-wrap'}>
{t(variableMap[variableType].desc)}
</Box>
)}
{variableType === VariableInputEnum.input && (
<>
<Box mt={5} mb={2}>
{t('core.module.variable.text max length')}
@@ -251,7 +253,7 @@ const VariableEdit = ({
</>
)}
{getValuesEdit('variable.type') === VariableInputEnum.select && (
{variableType === VariableInputEnum.select && (
<>
<Box mt={5} mb={2}>
{t('core.module.variable.variable options')}

View File

@@ -16,10 +16,11 @@ import { useTranslation } from 'next-i18next';
import MyTooltip from '@/components/MyTooltip';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
export const defaultField = {
export const defaultField: ContextExtractAgentItemType = {
required: false,
defaultValue: '',
desc: '',
key: '',
required: true,
enum: ''
};
@@ -33,9 +34,10 @@ const ExtractFieldModal = ({
onSubmit: (data: ContextExtractAgentItemType) => void;
}) => {
const { t } = useTranslation();
const { register, handleSubmit } = useForm<ContextExtractAgentItemType>({
const { register, handleSubmit, watch } = useForm<ContextExtractAgentItemType>({
defaultValues: defaultField
});
const required = watch('required');
return (
<MyModal
@@ -43,19 +45,41 @@ const ExtractFieldModal = ({
iconSrc="/imgs/module/extract.png"
title={t('core.module.extract.Field Setting Title')}
onClose={onClose}
w={['90vw', '500px']}
>
<ModalBody>
<Flex alignItems={'center'}>
<Box flex={'0 0 70px'}>{t('common.Require Input')}</Box>
<Flex mt={2} alignItems={'center'}>
<Flex alignItems={'center'} flex={['0 0 80px', '0 0 100px']}>
{t('core.module.extract.Required')}
<MyTooltip label={t('core.module.extract.Required Description')} forceShow>
<QuestionOutlineIcon ml={1} />
</MyTooltip>
</Flex>
<Switch {...register('required')} />
</Flex>
{required && (
<Flex mt={5} alignItems={'center'}>
<Box flex={['0 0 80px', '0 0 100px']}>{t('core.module.Default value')}</Box>
<Input
bg={'myGray.50'}
placeholder={t('core.module.Default value placeholder')}
{...register('defaultValue')}
/>
</Flex>
)}
<Flex mt={5} alignItems={'center'}>
<Box flex={'0 0 70px'}>{t('core.module.Field key')}</Box>
<Input placeholder="name/age/sql" {...register('key', { required: true })} />
<Box flex={['0 0 80px', '0 0 100px']}>{t('core.module.Field key')}</Box>
<Input
bg={'myGray.50'}
placeholder="name/age/sql"
{...register('key', { required: true })}
/>
</Flex>
<Flex mt={5} alignItems={'center'}>
<Box flex={'0 0 70px'}>{t('core.module.Field Description')}</Box>
<Box flex={['0 0 80px', '0 0 100px']}>{t('core.module.Field Description')}</Box>
<Input
bg={'myGray.50'}
placeholder={t('core.module.extract.Field Description Placeholder')}
{...register('desc', { required: true })}
/>
@@ -68,14 +92,16 @@ const ExtractFieldModal = ({
</MyTooltip>
</Flex>
<Textarea rows={5} placeholder={'apple\npeach\nwatermelon'} {...register('enum')} />
<Textarea
rows={5}
bg={'myGray.50'}
placeholder={'apple\npeach\nwatermelon'}
{...register('enum')}
/>
</Box>
</ModalBody>
<ModalFooter>
<Button variant={'whiteBase'} mr={3} onClick={onClose}>
{t('common.Close')}
</Button>
<Button onClick={handleSubmit(onSubmit)}>{t('common.Confirm')}</Button>
</ModalFooter>
</MyModal>

View File

@@ -1,5 +1,16 @@
import React, { useState } from 'react';
import { Box, Button, Table, Thead, Tbody, Tr, Th, Td, TableContainer } from '@chakra-ui/react';
import {
Box,
Button,
Table,
Thead,
Tbody,
Tr,
Th,
Td,
TableContainer,
Flex
} from '@chakra-ui/react';
import { NodeProps } from 'reactflow';
import { FlowModuleItemType } from '@fastgpt/global/core/module/type.d';
import { useTranslation } from 'next-i18next';
@@ -36,75 +47,87 @@ const NodeExtract = ({ data }: NodeProps<FlowModuleItemType>) => {
}: {
value?: ContextExtractAgentItemType[];
}) => (
<Box pt={2}>
<Box position={'absolute'} top={0} right={0}>
<Box>
<Flex alignItems={'center'}>
<Box flex={'1 0 0'}>{t('core.module.extract.Target field')}</Box>
<Button
size={'sm'}
variant={'whitePrimary'}
leftIcon={<AddIcon fontSize={'10px'} />}
onClick={() => setEditExtractField(defaultField)}
>
{t('core.module.extract.Add field')}
</Button>
</Box>
<TableContainer>
<Table>
<Thead>
<Tr>
<Th> key</Th>
<Th></Th>
<Th></Th>
<Th></Th>
</Tr>
</Thead>
<Tbody>
{extractKeys.map((item, index) => (
<Tr
key={index}
position={'relative'}
whiteSpace={'pre-wrap'}
wordBreak={'break-all'}
>
<Td>{item.key}</Td>
<Td>{item.desc}</Td>
<Td>{item.required ? '✔' : ''}</Td>
<Td whiteSpace={'nowrap'}>
<MyIcon
mr={3}
name={'common/settingLight'}
w={'16px'}
cursor={'pointer'}
onClick={() => {
setEditExtractField(item);
}}
/>
<MyIcon
name={'delete'}
w={'16px'}
cursor={'pointer'}
onClick={() => {
onChangeNode({
moduleId,
type: 'updateInput',
key: ModuleInputKeyEnum.extractKeys,
value: {
...props,
value: extractKeys.filter((extract) => item.key !== extract.key)
}
});
onChangeNode({
moduleId,
type: 'delOutput',
key: item.key
});
}}
/>
</Td>
</Flex>
<Box
mt={2}
borderRadius={'md'}
overflow={'hidden'}
borderWidth={'1px'}
borderBottom="none"
>
<TableContainer>
<Table bg={'white'}>
<Thead>
<Tr>
<Th bg={'myGray.50'}> key</Th>
<Th bg={'myGray.50'}></Th>
<Th bg={'myGray.50'}></Th>
<Th bg={'myGray.50'}></Th>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
</Thead>
<Tbody>
{extractKeys.map((item, index) => (
<Tr
key={index}
position={'relative'}
whiteSpace={'pre-wrap'}
wordBreak={'break-all'}
>
<Td>{item.key}</Td>
<Td>{item.desc}</Td>
<Td>{item.required ? '✔' : ''}</Td>
<Td whiteSpace={'nowrap'}>
<MyIcon
mr={3}
name={'common/settingLight'}
w={'16px'}
cursor={'pointer'}
onClick={() => {
setEditExtractField(item);
}}
/>
<MyIcon
name={'delete'}
w={'16px'}
cursor={'pointer'}
onClick={() => {
onChangeNode({
moduleId,
type: 'updateInput',
key: ModuleInputKeyEnum.extractKeys,
value: {
...props,
value: extractKeys.filter(
(extract) => item.key !== extract.key
)
}
});
onChangeNode({
moduleId,
type: 'delOutput',
key: item.key
});
}}
/>
</Td>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
</Box>
</Box>
)
}}
@@ -142,7 +165,6 @@ const NodeExtract = ({ data }: NodeProps<FlowModuleItemType>) => {
const newOutput = {
key: data.key,
label: `提取结果-${data.desc}`,
description: '无法提取时不会返回',
valueType: ModuleIOValueTypeEnum.string,
type: FlowNodeOutputTypeEnum.source,
targets: []