perf: onpublish app (#2498)

This commit is contained in:
Archer 2024-08-24 23:43:52 +08:00 committed by GitHub
parent fa106eb24c
commit ad63210f45
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 129 additions and 111 deletions

View File

@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react'; import React, { useCallback, useMemo, useState } from 'react';
import { import {
Box, Box,
Flex, Flex,
@ -39,14 +39,20 @@ const Header = () => {
const router = useRouter(); const router = useRouter();
const { toast } = useToast(); const { toast } = useToast();
const { appDetail, onPublish, currentTab } = useContextSelector(AppContext, (v) => v); const { appDetail, onSaveApp, currentTab } = useContextSelector(AppContext, (v) => v);
const isV2Workflow = appDetail?.version === 'v2'; const isV2Workflow = appDetail?.version === 'v2';
const { isOpen, onOpen, onClose } = useDisclosure();
const {
isOpen: isOpenBackConfirm,
onOpen: onOpenBackConfirm,
onClose: onCloseBackConfirm
} = useDisclosure();
const { const {
isOpen: isSaveAndPublishModalOpen, isOpen: isSaveAndPublishModalOpen,
onOpen: onSaveAndPublishModalOpen, onOpen: onSaveAndPublishModalOpen,
onClose: onSaveAndPublishModalClose onClose: onSaveAndPublishModalClose
} = useDisclosure(); } = useDisclosure();
const [isSave, setIsSave] = useState(false); const [isSave, setIsSave] = useState(false);
const { const {
@ -94,7 +100,7 @@ const Header = () => {
const data = flowData2StoreData(); const data = flowData2StoreData();
if (data) { if (data) {
await onPublish({ await onSaveApp({
...data, ...data,
isPublish, isPublish,
versionName, versionName,
@ -157,34 +163,9 @@ const Header = () => {
name={'common/leftArrowLight'} name={'common/leftArrowLight'}
w={'1.75rem'} w={'1.75rem'}
cursor={'pointer'} cursor={'pointer'}
onClick={isPublished ? onBack : onOpen} onClick={isPublished ? onBack : onOpenBackConfirm}
/> />
<MyModal
isOpen={isOpen}
onClose={onClose}
iconSrc="common/warn"
title={t('common:common.Exit')}
w={'400px'}
>
<ModalBody>
<Box>{t('workflow:workflow.exit_tips')}</Box>
</ModalBody>
<ModalFooter gap={3}>
<Button variant={'whiteDanger'} onClick={onBack}>
{t('common:common.Exit Directly')}
</Button>
<Button
isLoading={loading}
onClick={async () => {
await onClickSave({});
onClose();
onBack();
}}
>
{t('common:common.Save_and_exit')}
</Button>
</ModalFooter>
</MyModal>
{/* app info */} {/* app info */}
<Box ml={1}> <Box ml={1}>
<AppCard isPublished={isPublished} showSaveStatus={isV2Workflow} /> <AppCard isPublished={isPublished} showSaveStatus={isV2Workflow} />
@ -313,6 +294,32 @@ const Header = () => {
}} }}
/> />
)} )}
<MyModal
isOpen={isOpenBackConfirm}
onClose={onCloseBackConfirm}
iconSrc="common/warn"
title={t('common:common.Exit')}
w={'400px'}
>
<ModalBody>
<Box>{t('workflow:workflow.exit_tips')}</Box>
</ModalBody>
<ModalFooter gap={3}>
<Button variant={'whiteDanger'} onClick={onBack}>
{t('common:common.Exit Directly')}
</Button>
<Button
isLoading={loading}
onClick={async () => {
await onClickSave({});
onCloseBackConfirm();
onBack();
}}
>
{t('common:common.Save_and_exit')}
</Button>
</ModalFooter>
</MyModal>
</> </>
); );
}, [ }, [
@ -320,9 +327,9 @@ const Header = () => {
currentTab, currentTab,
isPublished, isPublished,
onBack, onBack,
onOpen, isOpenBackConfirm,
isOpen, onOpenBackConfirm,
onClose, onCloseBackConfirm,
t, t,
loading, loading,
isV2Workflow, isV2Workflow,

View File

@ -22,6 +22,7 @@ import { publishStatusStyle } from '../constants';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { useSystem } from '@fastgpt/web/hooks/useSystem'; import { useSystem } from '@fastgpt/web/hooks/useSystem';
import { useToast } from '@fastgpt/web/hooks/useToast'; import { useToast } from '@fastgpt/web/hooks/useToast';
import { formatTime2YMDHMS } from '@fastgpt/global/common/string/time';
const Header = ({ const Header = ({
appForm, appForm,
@ -34,7 +35,7 @@ const Header = ({
const { isPc } = useSystem(); const { isPc } = useSystem();
const router = useRouter(); const router = useRouter();
const { toast } = useToast(); const { toast } = useToast();
const { appId, appDetail, onPublish, currentTab } = useContextSelector(AppContext, (v) => v); const { appId, appDetail, onSaveApp, currentTab } = useContextSelector(AppContext, (v) => v);
const { data: paths = [] } = useRequest2(() => getAppFolderPath(appId), { const { data: paths = [] } = useRequest2(() => getAppFolderPath(appId), {
manual: false, manual: false,
@ -71,18 +72,20 @@ const Header = ({
const onSubmitPublish = useCallback( const onSubmitPublish = useCallback(
async (data: AppSimpleEditFormType) => { async (data: AppSimpleEditFormType) => {
const { nodes, edges } = form2AppWorkflow(data, t); const { nodes, edges } = form2AppWorkflow(data, t);
await onPublish({ await onSaveApp({
nodes, nodes,
edges, edges,
chatConfig: data.chatConfig, chatConfig: data.chatConfig,
type: AppTypeEnum.simple type: AppTypeEnum.simple,
isPublish: true,
versionName: formatTime2YMDHMS(new Date())
}); });
toast({ toast({
status: 'success', status: 'success',
title: t('app:publish_success') title: t('app:publish_success')
}); });
}, },
[onPublish, t, toast] [onSaveApp, t, toast]
); );
const [historiesDefaultData, setHistoriesDefaultData] = useState<InitProps>(); const [historiesDefaultData, setHistoriesDefaultData] = useState<InitProps>();

View File

@ -39,9 +39,13 @@ const Header = () => {
const router = useRouter(); const router = useRouter();
const { toast } = useToast(); const { toast } = useToast();
const { appDetail, onPublish, currentTab } = useContextSelector(AppContext, (v) => v); const { appDetail, onSaveApp, currentTab } = useContextSelector(AppContext, (v) => v);
const isV2Workflow = appDetail?.version === 'v2'; const isV2Workflow = appDetail?.version === 'v2';
const { isOpen, onOpen, onClose } = useDisclosure(); const {
isOpen: isOpenBackConfirm,
onOpen: onOpenBackConfirm,
onClose: onCloseBackConfirm
} = useDisclosure();
const { const {
isOpen: isSaveAndPublishModalOpen, isOpen: isSaveAndPublishModalOpen,
onOpen: onSaveAndPublishModalOpen, onOpen: onSaveAndPublishModalOpen,
@ -94,7 +98,7 @@ const Header = () => {
const data = flowData2StoreData(); const data = flowData2StoreData();
if (data) { if (data) {
await onPublish({ await onSaveApp({
...data, ...data,
isPublish, isPublish,
versionName, versionName,
@ -157,34 +161,9 @@ const Header = () => {
name={'common/leftArrowLight'} name={'common/leftArrowLight'}
w={'1.75rem'} w={'1.75rem'}
cursor={'pointer'} cursor={'pointer'}
onClick={isPublished ? onBack : onOpen} onClick={isPublished ? onBack : onOpenBackConfirm}
/> />
<MyModal
isOpen={isOpen}
onClose={onClose}
iconSrc="common/warn"
title={t('common:common.Exit')}
w={'400px'}
>
<ModalBody>
<Box>{t('workflow:workflow.exit_tips')}</Box>
</ModalBody>
<ModalFooter gap={3}>
<Button variant={'whiteDanger'} onClick={onBack}>
{t('common:common.Exit Directly')}
</Button>
<Button
isLoading={loading}
onClick={async () => {
await onClickSave({});
onClose();
onBack();
}}
>
{t('common:common.Save_and_exit')}
</Button>
</ModalFooter>
</MyModal>
{/* app info */} {/* app info */}
<Box ml={1}> <Box ml={1}>
<AppCard isPublished={isPublished} showSaveStatus={isV2Workflow} /> <AppCard isPublished={isPublished} showSaveStatus={isV2Workflow} />
@ -313,6 +292,36 @@ const Header = () => {
}} }}
/> />
)} )}
<MyModal
isOpen={isOpenBackConfirm}
onClose={onCloseBackConfirm}
iconSrc="common/warn"
title={t('common:common.Exit')}
w={'400px'}
>
<ModalBody>
<Box>{t('workflow:workflow.exit_tips')}</Box>
</ModalBody>
<ModalFooter gap={3}>
<Button variant={'whiteDanger'} onClick={onBack}>
{t('common:common.Exit Directly')}
</Button>
<Button
isLoading={loading}
onClick={async () => {
await onClickSave({});
onCloseBackConfirm();
onBack();
toast({
status: 'success',
title: t('app:saved_success')
});
}}
>
{t('common:common.Save_and_exit')}
</Button>
</ModalFooter>
</MyModal>
</> </>
); );
}, [ }, [
@ -320,9 +329,9 @@ const Header = () => {
currentTab, currentTab,
isPublished, isPublished,
onBack, onBack,
onOpen, isOpenBackConfirm,
isOpen, onOpenBackConfirm,
onClose, onCloseBackConfirm,
t, t,
loading, loading,
isV2Workflow, isV2Workflow,

View File

@ -28,13 +28,11 @@ import { versionListResponse } from '@/pages/api/core/app/version/listWorkflow';
const WorkflowPublishHistoriesSlider = ({ onClose }: { onClose: () => void }) => { const WorkflowPublishHistoriesSlider = ({ onClose }: { onClose: () => void }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const [currentTab, setCurrentTab] = useState<'myEdit' | 'teamCloud'>('myEdit'); const [currentTab, setCurrentTab] = useState<'myEdit' | 'teamCloud'>('myEdit');
const [isLoading, setIsLoading] = useState(false);
return ( return (
<> <>
<CustomRightDrawer <CustomRightDrawer
onClose={() => onClose()} onClose={() => onClose()}
isLoading={isLoading}
title={ title={
( (
<> <>
@ -58,7 +56,7 @@ const WorkflowPublishHistoriesSlider = ({ onClose }: { onClose: () => void }) =>
showMask={false} showMask={false}
overflow={'unset'} overflow={'unset'}
> >
{currentTab === 'myEdit' ? <MyEdit /> : <TeamCloud setIsLoading={setIsLoading} />} {currentTab === 'myEdit' ? <MyEdit /> : <TeamCloud />}
</CustomRightDrawer> </CustomRightDrawer>
</> </>
); );
@ -81,14 +79,17 @@ const MyEdit = () => {
h={'30px'} h={'30px'}
onClick={async () => { onClick={async () => {
const initialSnapshot = past[past.length - 1]; const initialSnapshot = past[past.length - 1];
const res = await saveSnapshot({ const res = await saveSnapshot({
pastNodes: initialSnapshot.nodes, pastNodes: initialSnapshot.nodes,
pastEdges: initialSnapshot.edges, pastEdges: initialSnapshot.edges,
chatConfig: initialSnapshot.chatConfig, chatConfig: initialSnapshot.chatConfig,
customTitle: t(`app:app.version_initial_copy`) customTitle: t(`app:app.version_initial_copy`)
}); });
if (!res) return; if (res) {
resetSnapshot(initialSnapshot); resetSnapshot(initialSnapshot);
}
toast({ toast({
title: t('workflow:workflow.Switch_success'), title: t('workflow:workflow.Switch_success'),
status: 'success' status: 'success'
@ -120,8 +121,9 @@ const MyEdit = () => {
chatConfig: item.chatConfig, chatConfig: item.chatConfig,
customTitle: `${t('app:app.version_copy')}-${item.title}` customTitle: `${t('app:app.version_copy')}-${item.title}`
}); });
if (!res) return; if (res) {
resetSnapshot(item); resetSnapshot(item);
}
toast({ toast({
title: t('workflow:workflow.Switch_success'), title: t('workflow:workflow.Switch_success'),
status: 'success' status: 'success'
@ -169,7 +171,7 @@ const MyEdit = () => {
); );
}; };
const TeamCloud = ({ setIsLoading }: { setIsLoading: (value: boolean) => void }) => { const TeamCloud = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const { appDetail } = useContextSelector(AppContext, (v) => v); const { appDetail } = useContextSelector(AppContext, (v) => v);
const { saveSnapshot, resetSnapshot } = useContextSelector(WorkflowContext, (v) => v); const { saveSnapshot, resetSnapshot } = useContextSelector(WorkflowContext, (v) => v);
@ -194,11 +196,12 @@ const TeamCloud = ({ setIsLoading }: { setIsLoading: (value: boolean) => void })
const [isEditing, setIsEditing] = useState(false); const [isEditing, setIsEditing] = useState(false);
const { toast } = useToast(); const { toast } = useToast();
const onChangeVersion = async (versionItem: versionListResponse) => { const { runAsync: onChangeVersion, loading: isLoadingVersion } = useRequest2(
setIsLoading(true); async (versionItem: versionListResponse) => {
const versionDetail = await getAppVersionDetail(versionItem._id, versionItem.appId); const versionDetail = await getAppVersionDetail(versionItem._id, versionItem.appId);
setIsLoading(false);
if (!versionDetail) return; if (!versionDetail) return;
const state = { const state = {
nodes: versionDetail.nodes?.map((item) => storeNode2FlowNode({ item })), nodes: versionDetail.nodes?.map((item) => storeNode2FlowNode({ item })),
edges: versionDetail.edges?.map((item) => storeEdgesRenderEdge({ edge: item })), edges: versionDetail.edges?.map((item) => storeEdgesRenderEdge({ edge: item })),
@ -206,27 +209,23 @@ const TeamCloud = ({ setIsLoading }: { setIsLoading: (value: boolean) => void })
chatConfig: versionDetail.chatConfig chatConfig: versionDetail.chatConfig
}; };
const res = await saveSnapshot({ await saveSnapshot({
pastNodes: state.nodes, pastNodes: state.nodes,
pastEdges: state.edges, pastEdges: state.edges,
chatConfig: state.chatConfig, chatConfig: state.chatConfig,
customTitle: `${t('app:app.version_copy')}-${state.title}` customTitle: `${t('app:app.version_copy')}-${state.title}`
}); });
if (!res) {
return toast({
title: t('workflow:workflow.Switch_failed'),
status: 'warning'
});
}
resetSnapshot(state); resetSnapshot(state);
toast({ toast({
title: t('workflow:workflow.Switch_success'), title: t('workflow:workflow.Switch_success'),
status: 'success' status: 'success'
}); });
}; }
);
return ( return (
<ScrollList isLoading={isLoading} flex={'1 0 0'} px={5}> <ScrollList isLoading={isLoading || isLoadingVersion} flex={'1 0 0'} px={5}>
{list.map((data, index) => { {list.map((data, index) => {
const item = data.data; const item = data.data;
const firstPublishedIndex = list.findIndex((data) => data.data.isPublish); const firstPublishedIndex = list.findIndex((data) => data.data.isPublish);

View File

@ -35,7 +35,7 @@ type AppContextType = {
onOpenInfoEdit: () => void; onOpenInfoEdit: () => void;
onOpenTeamTagModal: () => void; onOpenTeamTagModal: () => void;
onDelApp: () => void; onDelApp: () => void;
onPublish: (data: PostPublishAppProps) => Promise<void>; onSaveApp: (data: PostPublishAppProps) => Promise<void>;
appLatestVersion: appLatestVersion:
| { | {
nodes: StoreNodeItemType[]; nodes: StoreNodeItemType[];
@ -70,7 +70,7 @@ export const AppContext = createContext<AppContextType>({
onDelApp: function (): void { onDelApp: function (): void {
throw new Error('Function not implemented.'); throw new Error('Function not implemented.');
}, },
onPublish: function (data: PostPublishAppProps): Promise<void> { onSaveApp: function (data: PostPublishAppProps): Promise<void> {
throw new Error('Function not implemented.'); throw new Error('Function not implemented.');
}, },
appLatestVersion: undefined, appLatestVersion: undefined,
@ -150,7 +150,7 @@ const AppContextProvider = ({ children }: { children: ReactNode }) => {
})); }));
}); });
const { runAsync: onPublish } = useRequest2(async (data: PostPublishAppProps) => { const { runAsync: onSaveApp } = useRequest2(async (data: PostPublishAppProps) => {
await postPublishApp(appId, data); await postPublishApp(appId, data);
setAppDetail((state) => ({ setAppDetail((state) => ({
...state, ...state,
@ -190,7 +190,7 @@ const AppContextProvider = ({ children }: { children: ReactNode }) => {
onOpenInfoEdit, onOpenInfoEdit,
onOpenTeamTagModal, onOpenTeamTagModal,
onDelApp, onDelApp,
onPublish, onSaveApp,
appLatestVersion, appLatestVersion,
reloadAppLatestVersion, reloadAppLatestVersion,
reloadApp reloadApp