4.8-fix (#1305)
* fix if-else find variables (#92) * fix if-else find variables * change workflow output type * fix tooltip style * fix * 4.8 (#93) * api middleware * perf: app version histories * faq * perf: value type show * fix: ts * fix: Run the same node multiple times * feat: auto save workflow * perf: auto save workflow --------- Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { Box, Flex, IconButton, useTheme, useDisclosure, Button } from '@chakra-ui/react';
|
||||
import { PluginItemSchema } from '@fastgpt/global/core/plugin/type';
|
||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
||||
@@ -7,16 +7,14 @@ import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import dynamic from 'next/dynamic';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import MyTooltip from '@/components/MyTooltip';
|
||||
import { filterExportModules, flowNode2StoreNodes } from '@/components/core/workflow/utils';
|
||||
import { flowNode2StoreNodes } from '@/components/core/workflow/utils';
|
||||
import { putUpdatePlugin } from '@/web/core/plugin/api';
|
||||
import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/index.d';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import MyMenu from '@fastgpt/web/components/common/MyMenu';
|
||||
import {
|
||||
getWorkflowStore,
|
||||
useFlowProviderStore
|
||||
} from '@/components/core/workflow/Flow/FlowProvider';
|
||||
import { StoreEdgeItemType } from '@fastgpt/global/core/workflow/type/edge';
|
||||
import {
|
||||
checkWorkflowNodeAndConnection,
|
||||
filterSensitiveNodesData
|
||||
@@ -51,107 +49,109 @@ const Header = ({ plugin, onClose }: Props) => {
|
||||
}, [edges, onUpdateNodeError, t, toast]);
|
||||
|
||||
const { mutate: onclickSave, isLoading } = useRequest({
|
||||
mutationFn: ({ nodes, edges }: { nodes: StoreNodeItemType[]; edges: StoreEdgeItemType[] }) => {
|
||||
return putUpdatePlugin({
|
||||
id: plugin._id,
|
||||
modules: nodes,
|
||||
edges
|
||||
});
|
||||
},
|
||||
successToast: '保存配置成功',
|
||||
errorToast: '保存配置异常'
|
||||
mutationFn: async () => {
|
||||
const workflow = await flowData2StoreDataAndCheck();
|
||||
if (workflow) {
|
||||
await putUpdatePlugin({
|
||||
id: plugin._id,
|
||||
modules: workflow.nodes,
|
||||
edges: workflow.edges
|
||||
});
|
||||
toast({
|
||||
status: 'success',
|
||||
title: t('common.Save Success')
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex
|
||||
py={3}
|
||||
px={[2, 5, 8]}
|
||||
borderBottom={theme.borders.base}
|
||||
alignItems={'center'}
|
||||
userSelect={'none'}
|
||||
>
|
||||
<MyTooltip label={t('common.Back')} offset={[10, 10]}>
|
||||
<IconButton
|
||||
size={'smSquare'}
|
||||
icon={<MyIcon name={'common/backLight'} w={'14px'} />}
|
||||
variant={'whiteBase'}
|
||||
aria-label={''}
|
||||
onClick={() => {
|
||||
onClose();
|
||||
}}
|
||||
/>
|
||||
</MyTooltip>
|
||||
<Box ml={[3, 5]} fontSize={['md', '2xl']} flex={1}>
|
||||
{plugin.name}
|
||||
</Box>
|
||||
const onCopy = useCallback(async () => {
|
||||
const data = await flowData2StoreDataAndCheck();
|
||||
if (data) {
|
||||
copyData(
|
||||
JSON.stringify(
|
||||
{
|
||||
nodes: filterSensitiveNodesData(data.nodes),
|
||||
edges: data.edges
|
||||
},
|
||||
null,
|
||||
2
|
||||
),
|
||||
t('app.Export Config Successful')
|
||||
);
|
||||
}
|
||||
}, [copyData, flowData2StoreDataAndCheck, t]);
|
||||
|
||||
<MyMenu
|
||||
Button={
|
||||
<IconButton
|
||||
mr={[3, 5]}
|
||||
icon={<MyIcon name={'more'} w={'14px'} p={2} />}
|
||||
aria-label={''}
|
||||
size={'sm'}
|
||||
variant={'whitePrimary'}
|
||||
/>
|
||||
}
|
||||
menuList={[
|
||||
{ label: t('app.Import Configs'), icon: 'common/importLight', onClick: onOpenImport },
|
||||
{
|
||||
label: t('app.Export Configs'),
|
||||
icon: 'export',
|
||||
onClick: async () => {
|
||||
const data = await flowData2StoreDataAndCheck();
|
||||
if (data) {
|
||||
copyData(
|
||||
JSON.stringify(
|
||||
{
|
||||
nodes: filterSensitiveNodesData(data.nodes),
|
||||
edges: data.edges
|
||||
},
|
||||
null,
|
||||
2
|
||||
),
|
||||
t('app.Export Config Successful')
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
]}
|
||||
/>
|
||||
{/* <MyTooltip label={t('module.Preview Plugin')}>
|
||||
<IconButton
|
||||
mr={[3, 5]}
|
||||
icon={<MyIcon name={'core/modules/previewLight'} w={['14px', '16px']} />}
|
||||
size={'smSquare'}
|
||||
aria-label={'save'}
|
||||
variant={'whitePrimary'}
|
||||
onClick={async () => {
|
||||
const modules = await flowData2StoreDataAndCheck();
|
||||
if (modules) {
|
||||
setPreviewModules(modules);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</MyTooltip> */}
|
||||
<Button
|
||||
size={'sm'}
|
||||
isLoading={isLoading}
|
||||
leftIcon={<MyIcon name={'common/saveFill'} w={['14px', '16px']} />}
|
||||
onClick={async () => {
|
||||
const modules = await flowData2StoreDataAndCheck();
|
||||
if (modules) {
|
||||
onclickSave(modules);
|
||||
}
|
||||
}}
|
||||
const Render = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
<Flex
|
||||
py={3}
|
||||
px={[2, 5, 8]}
|
||||
borderBottom={theme.borders.base}
|
||||
alignItems={'center'}
|
||||
userSelect={'none'}
|
||||
>
|
||||
{t('common.Save')}
|
||||
</Button>
|
||||
</Flex>
|
||||
{isOpenImport && <ImportSettings onClose={onCloseImport} />}
|
||||
</>
|
||||
);
|
||||
<MyTooltip label={t('common.Back')} offset={[10, 10]}>
|
||||
<IconButton
|
||||
size={'smSquare'}
|
||||
icon={<MyIcon name={'common/backLight'} w={'14px'} />}
|
||||
variant={'whiteBase'}
|
||||
aria-label={''}
|
||||
onClick={() => {
|
||||
onClose();
|
||||
}}
|
||||
/>
|
||||
</MyTooltip>
|
||||
<Box ml={[3, 5]} fontSize={['md', '2xl']} flex={1}>
|
||||
{plugin.name}
|
||||
</Box>
|
||||
|
||||
<MyMenu
|
||||
Button={
|
||||
<IconButton
|
||||
mr={[3, 5]}
|
||||
icon={<MyIcon name={'more'} w={'14px'} p={2} />}
|
||||
aria-label={''}
|
||||
size={'sm'}
|
||||
variant={'whitePrimary'}
|
||||
/>
|
||||
}
|
||||
menuList={[
|
||||
{ label: t('app.Import Configs'), icon: 'common/importLight', onClick: onOpenImport },
|
||||
{
|
||||
label: t('app.Export Configs'),
|
||||
icon: 'export',
|
||||
onClick: onCopy
|
||||
}
|
||||
]}
|
||||
/>
|
||||
<Button
|
||||
size={'sm'}
|
||||
isLoading={isLoading}
|
||||
leftIcon={<MyIcon name={'common/saveFill'} w={['14px', '16px']} />}
|
||||
onClick={onclickSave}
|
||||
>
|
||||
{t('common.Save')}
|
||||
</Button>
|
||||
</Flex>
|
||||
{isOpenImport && <ImportSettings onClose={onCloseImport} />}
|
||||
</>
|
||||
);
|
||||
}, [
|
||||
isLoading,
|
||||
isOpenImport,
|
||||
onClose,
|
||||
onCloseImport,
|
||||
onCopy,
|
||||
onOpenImport,
|
||||
onclickSave,
|
||||
plugin.name,
|
||||
t,
|
||||
theme.borders.base
|
||||
]);
|
||||
|
||||
return Render;
|
||||
};
|
||||
|
||||
export default React.memo(Header);
|
||||
|
||||
@@ -13,6 +13,7 @@ import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||
import { v1Workflow2V2 } from '@/web/core/workflow/adapt';
|
||||
import { useBeforeunload } from '@fastgpt/web/hooks/useBeforeunload';
|
||||
|
||||
type Props = { pluginId: string };
|
||||
|
||||
@@ -42,18 +43,16 @@ const Render = ({ pluginId }: Props) => {
|
||||
'检测到您的高级编排为旧版,系统将为您自动格式化成新版工作流。\n\n由于版本差异较大,会导致许多工作流无法正常排布,请重新手动连接工作流。如仍异常,可尝试删除对应节点后重新添加。\n\n你可以直接点击测试进行调试,无需点击保存,点击保存为新版工作流。'
|
||||
});
|
||||
|
||||
const workflowStringData = JSON.stringify({
|
||||
nodes: pluginDetail?.modules || [],
|
||||
edges: pluginDetail?.edges || []
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (isV2Workflow) {
|
||||
initData(
|
||||
JSON.parse(
|
||||
JSON.stringify({
|
||||
nodes: pluginDetail?.modules || [],
|
||||
edges: pluginDetail?.edges || []
|
||||
})
|
||||
)
|
||||
);
|
||||
initData(JSON.parse(workflowStringData));
|
||||
}
|
||||
}, [isV2Workflow, pluginDetail?.edges, pluginDetail?.modules]);
|
||||
}, [initData, isV2Workflow, workflowStringData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isV2Workflow && pluginDetail) {
|
||||
@@ -61,7 +60,11 @@ const Render = ({ pluginId }: Props) => {
|
||||
initData(JSON.parse(JSON.stringify(v1Workflow2V2((pluginDetail.modules || []) as any))));
|
||||
})();
|
||||
}
|
||||
}, [isV2Workflow, openConfirm, pluginDetail]);
|
||||
}, [initData, isV2Workflow, openConfirm, pluginDetail]);
|
||||
|
||||
useBeforeunload({
|
||||
tip: t('core.common.tip.leave page')
|
||||
});
|
||||
|
||||
return pluginDetail ? (
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user