V4.6.5-alpha (#609)

This commit is contained in:
Archer
2023-12-15 15:57:39 +08:00
committed by GitHub
parent dd7b4b98ae
commit 05bf1b2265
127 changed files with 4283 additions and 2315 deletions

View File

@@ -1,4 +1,4 @@
import React from 'react';
import React, { useCallback } from 'react';
import { Box, Flex, IconButton, useTheme, useDisclosure } from '@chakra-ui/react';
import { PluginItemSchema } from '@fastgpt/global/core/plugin/type';
import { useRequest } from '@/web/common/hooks/useRequest';
@@ -7,10 +7,12 @@ import { useCopyData } from '@/web/common/hooks/useCopyData';
import dynamic from 'next/dynamic';
import MyIcon from '@/components/Icon';
import MyTooltip from '@/components/MyTooltip';
import { flowNode2Modules, useFlowProviderStore } from '@/components/core/module/Flow/FlowProvider';
import { useFlowProviderStore } from '@/components/core/module/Flow/FlowProvider';
import { flowNode2Modules } from '@/components/core/module/utils';
import { putUpdatePlugin } from '@/web/core/plugin/api';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/module/node/constant';
import { ModuleItemType } from '@fastgpt/global/core/module/type';
import { useToast } from '@/web/common/hooks/useToast';
const ImportSettings = dynamic(() => import('@/components/core/module/Flow/ImportSettings'));
const PreviewPlugin = dynamic(() => import('./Preview'));
@@ -20,58 +22,83 @@ type Props = { plugin: PluginItemSchema; onClose: () => void };
const Header = ({ plugin, onClose }: Props) => {
const theme = useTheme();
const { t } = useTranslation();
const { toast } = useToast();
const { copyData } = useCopyData();
const { isOpen: isOpenImport, onOpen: onOpenImport, onClose: onCloseImport } = useDisclosure();
const { nodes, edges, onFixView } = useFlowProviderStore();
const [previewModules, setPreviewModules] = React.useState<ModuleItemType[]>();
const { mutate: onclickSave, isLoading } = useRequest({
mutationFn: () => {
const modules = flowNode2Modules({ nodes, edges });
const flow2ModulesAndCheck = useCallback(() => {
const modules = flowNode2Modules({ nodes, edges });
// check required connect
for (let i = 0; i < modules.length; i++) {
const item = modules[i];
// check required connect
for (let i = 0; i < modules.length; i++) {
const item = modules[i];
// update custom input connected
if (item.flowType === FlowNodeTypeEnum.pluginInput) {
item.inputs.forEach((item) => {
item.connected = true;
// update custom input connected
if (item.flowType === FlowNodeTypeEnum.pluginInput) {
item.inputs.forEach((item) => {
item.connected = true;
});
if (item.outputs.find((output) => output.targets.length === 0)) {
toast({
status: 'warning',
title: t('module.Plugin input must connect')
});
if (item.outputs.find((output) => output.targets.length === 0)) {
return Promise.reject(t('module.Plugin input must connect'));
}
}
if (
item.flowType === FlowNodeTypeEnum.pluginOutput &&
item.inputs.find((input) => !input.connected)
) {
return Promise.reject(t('core.module.Plugin output must connect'));
}
if (
item.inputs.find((input) => {
if (!input.required || input.connected) return false;
if (!input.value || input.value === '' || input.value?.length === 0) return true;
return false;
})
) {
return Promise.reject(`${item.name}】存在未填或未连接参数`);
return false;
}
}
// plugin must have input
const pluginInputModule = modules.find(
(item) => item.flowType === FlowNodeTypeEnum.pluginInput
);
if (!pluginInputModule) {
return Promise.reject(t('module.Plugin input is required'));
}
if (pluginInputModule.inputs.length < 1) {
return Promise.reject(t('module.Plugin input is not value'));
if (
item.flowType === FlowNodeTypeEnum.pluginOutput &&
item.inputs.find((input) => !input.connected)
) {
toast({
status: 'warning',
title: t('core.module.Plugin output must connect')
});
return false;
}
if (
item.inputs.find((input) => {
if (!input.required || input.connected) return false;
if (!input.value || input.value === '' || input.value?.length === 0) return true;
return false;
})
) {
toast({
status: 'warning',
title: `${item.name}】存在未填或未连接参数`
});
return false;
}
}
// plugin must have input
const pluginInputModule = modules.find(
(item) => item.flowType === FlowNodeTypeEnum.pluginInput
);
if (!pluginInputModule) {
toast({
status: 'warning',
title: t('module.Plugin input is required')
});
return false;
}
if (pluginInputModule.inputs.length < 1) {
toast({
status: 'warning',
title: t('module.Plugin input is not value')
});
return false;
}
return modules;
}, [edges, nodes, t, toast]);
const { mutate: onclickSave, isLoading } = useRequest({
mutationFn: (modules: ModuleItemType[]) => {
return putUpdatePlugin({
id: plugin._id,
modules
@@ -90,7 +117,7 @@ const Header = ({ plugin, onClose }: Props) => {
alignItems={'center'}
userSelect={'none'}
>
<MyTooltip label={'返回'} offset={[10, 10]}>
<MyTooltip label={t('common.Back')} offset={[10, 10]}>
<IconButton
size={'sm'}
icon={<MyIcon name={'back'} w={'14px'} />}
@@ -125,12 +152,12 @@ const Header = ({ plugin, onClose }: Props) => {
borderRadius={'lg'}
variant={'base'}
aria-label={'save'}
onClick={() =>
copyData(
JSON.stringify(flowNode2Modules({ nodes, edges }), null, 2),
t('app.Export Config Successful')
)
}
onClick={() => {
const modules = flow2ModulesAndCheck();
if (modules) {
copyData(JSON.stringify(modules, null, 2), t('app.Export Config Successful'));
}
}}
/>
</MyTooltip>
<MyTooltip label={t('module.Preview Plugin')}>
@@ -141,7 +168,10 @@ const Header = ({ plugin, onClose }: Props) => {
aria-label={'save'}
variant={'base'}
onClick={() => {
setPreviewModules(flowNode2Modules({ nodes, edges }));
const modules = flow2ModulesAndCheck();
if (modules) {
setPreviewModules(modules);
}
}}
/>
</MyTooltip>
@@ -151,7 +181,12 @@ const Header = ({ plugin, onClose }: Props) => {
borderRadius={'lg'}
isLoading={isLoading}
aria-label={'save'}
onClick={onclickSave}
onClick={() => {
const modules = flow2ModulesAndCheck();
if (modules) {
onclickSave(modules);
}
}}
/>
</MyTooltip>
</Flex>