From 6adede25f9c8e01cbeed60a64476b68434de3d5c Mon Sep 17 00:00:00 2001 From: zjy <3161362058@qq.com> Date: Thu, 28 Nov 2024 14:10:45 +0800 Subject: [PATCH 1/4] feat:optimize launchpad unify redirect handling --- frontend/desktop/next-i18next.config.js | 4 +- .../applaunchpad/src/constants/editApp.ts | 3 +- .../providers/applaunchpad/src/mock/apps.ts | 3 +- .../providers/applaunchpad/src/pages/_app.tsx | 8 +- .../src/pages/app/edit/components/Header.tsx | 4 +- .../applaunchpad/src/pages/app/edit/index.tsx | 19 ++-- .../applaunchpad/src/pages/redirect.tsx | 87 +++++++++++++++++++ .../providers/applaunchpad/src/types/app.d.ts | 11 ++- .../providers/applaunchpad/src/utils/adapt.ts | 4 +- .../applaunchpad/src/utils/deployYaml2Json.ts | 2 + 10 files changed, 125 insertions(+), 20 deletions(-) create mode 100644 frontend/providers/applaunchpad/src/pages/redirect.tsx diff --git a/frontend/desktop/next-i18next.config.js b/frontend/desktop/next-i18next.config.js index 381e292c0cc..1ef264034d3 100644 --- a/frontend/desktop/next-i18next.config.js +++ b/frontend/desktop/next-i18next.config.js @@ -4,9 +4,9 @@ module.exports = { i18n: { - defaultLocale: 'zh', + defaultLocale: 'en', locales: ['en', 'zh'], localeDetection: false }, reloadOnPrerender: process.env.NODE_ENV === 'development' -}; +} diff --git a/frontend/providers/applaunchpad/src/constants/editApp.ts b/frontend/providers/applaunchpad/src/constants/editApp.ts index 3f904094475..9b19828fbfc 100644 --- a/frontend/providers/applaunchpad/src/constants/editApp.ts +++ b/frontend/providers/applaunchpad/src/constants/editApp.ts @@ -62,7 +62,8 @@ export const defaultEditVal: AppEditType = { manufacturers: 'nvidia', type: '', amount: 1 - } + }, + labels: {} }; export const GpuAmountMarkList = [ diff --git a/frontend/providers/applaunchpad/src/mock/apps.ts b/frontend/providers/applaunchpad/src/mock/apps.ts index 66b02e00f69..f6809b3a744 100644 --- a/frontend/providers/applaunchpad/src/mock/apps.ts +++ b/frontend/providers/applaunchpad/src/mock/apps.ts @@ -315,5 +315,6 @@ export const MockAppEditSyncedFields: AppEditSyncedFields = { } ], cmdParam: 'sleep 10', - runCMD: '/bin/bash -c' + runCMD: '/bin/bash -c', + labels: {} }; diff --git a/frontend/providers/applaunchpad/src/pages/_app.tsx b/frontend/providers/applaunchpad/src/pages/_app.tsx index d1ef6c7b0be..935cc4cdef0 100644 --- a/frontend/providers/applaunchpad/src/pages/_app.tsx +++ b/frontend/providers/applaunchpad/src/pages/_app.tsx @@ -122,9 +122,13 @@ const App = ({ Component, pageProps }: AppProps) => { // record route useEffect(() => { return () => { - setLastRoute(router.asPath); + const currentPath = router.asPath; + if (router.isReady && !currentPath.includes('/redirect')) { + console.log(currentPath); + setLastRoute(currentPath); + } }; - }, [router.pathname]); + }, [router.pathname, router.isReady, setLastRoute]); useEffect(() => { const lang = getLangStore() || 'zh'; diff --git a/frontend/providers/applaunchpad/src/pages/app/edit/components/Header.tsx b/frontend/providers/applaunchpad/src/pages/app/edit/components/Header.tsx index c50a36208f2..e116c1c57df 100644 --- a/frontend/providers/applaunchpad/src/pages/app/edit/components/Header.tsx +++ b/frontend/providers/applaunchpad/src/pages/app/edit/components/Header.tsx @@ -41,7 +41,9 @@ const Header = ({ alignItems={'center'} cursor={'pointer'} gap={'6px'} - onClick={() => router.replace(lastRoute)} + onClick={() => { + router.replace(lastRoute); + }} > diff --git a/frontend/providers/applaunchpad/src/pages/app/edit/index.tsx b/frontend/providers/applaunchpad/src/pages/app/edit/index.tsx index 1ec0a53ded7..e23a0a94b97 100644 --- a/frontend/providers/applaunchpad/src/pages/app/edit/index.tsx +++ b/frontend/providers/applaunchpad/src/pages/app/edit/index.tsx @@ -285,21 +285,18 @@ const EditApp = ({ appName, tabType }: { appName?: string; tabType: string }) => useEffect(() => { try { - const query = router.query as { formData?: string }; + console.log('edit page already', already, router.query); + if (!already) return; + const query = router.query as { formData?: string; name?: string }; if (!query.formData) return; + const parsedData: Partial = JSON.parse( decodeURIComponent(query.formData) ); - const basicFields: (keyof AppEditSyncedFields)[] = [ - 'imageName', - 'replicas', - 'cpu', - 'memory', - 'cmdParam', - 'runCMD', - 'appName' - ]; + const basicFields: (keyof AppEditSyncedFields)[] = router.query?.name + ? ['imageName', 'cpu', 'memory'] + : ['imageName', 'replicas', 'cpu', 'memory', 'cmdParam', 'runCMD', 'appName', 'labels']; basicFields.forEach((field) => { if (parsedData[field] !== undefined) { @@ -321,7 +318,7 @@ const EditApp = ({ appName, tabType }: { appName?: string; tabType: string }) => formHook.setValue('networks', completeNetworks); } } catch (error) {} - }, [router.query]); + }, [router.query, already]); return ( <> diff --git a/frontend/providers/applaunchpad/src/pages/redirect.tsx b/frontend/providers/applaunchpad/src/pages/redirect.tsx new file mode 100644 index 00000000000..c51956842c1 --- /dev/null +++ b/frontend/providers/applaunchpad/src/pages/redirect.tsx @@ -0,0 +1,87 @@ +import { getAppByName } from '@/api/app'; +import { DESKTOP_DOMAIN } from '@/store/static'; +import { AppEditSyncedFields } from '@/types/app'; +import { useRouter } from 'next/router'; +import { useEffect } from 'react'; + +const RedirectPage = () => { + const router = useRouter(); + + useEffect(() => { + const handleRedirect = (formData?: string) => { + if (formData) { + const parsedData: Partial = JSON.parse(decodeURIComponent(formData)); + console.log(parsedData, 'parsedData'); + + const appName = parsedData?.appName; + if (appName) { + getAppByName(appName) + .then((app) => { + console.log(app, 'app'); + if (app.isPause) { + router.replace({ + pathname: '/app/detail', + query: { name: appName } + }); + } else { + router.replace({ + pathname: '/app/edit', + query: { name: appName, formData } + }); + } + }) + .catch((err) => { + router.replace({ + pathname: '/app/edit', + query: { formData } + }); + }); + } else { + router.replace('/apps'); + } + } else { + router.replace('/apps'); + } + }; + + const handleUrlParams = () => { + const { formData } = router.query as { formData?: string }; + handleRedirect(formData); + }; + + const handlePostMessage = ( + e: MessageEvent<{ + type?: string; + formData?: string; + }> + ) => { + const whitelist = [`https://${DESKTOP_DOMAIN}`]; + if (!whitelist.includes(e.origin)) { + return; + } + + try { + if (e.data?.type === 'InternalAppCall') { + const { formData } = e.data; + handleRedirect(formData); + } + } catch (error) { + console.log('app redirect error:', error); + } + }; + + window.addEventListener('message', handlePostMessage); + + if (router.isReady) { + handleUrlParams(); + } + + return () => { + window.removeEventListener('message', handlePostMessage); + }; + }, [router.isReady, router.query]); + + return null; +}; + +export default RedirectPage; diff --git a/frontend/providers/applaunchpad/src/types/app.d.ts b/frontend/providers/applaunchpad/src/types/app.d.ts index 69db7c38f67..e6539a03fb0 100644 --- a/frontend/providers/applaunchpad/src/types/app.d.ts +++ b/frontend/providers/applaunchpad/src/types/app.d.ts @@ -107,11 +107,20 @@ export interface AppEditType { path: string; value: number; }[]; + labels: { [key: string]: string }; } export type AppEditSyncedFields = Pick< AppEditType, - 'imageName' | 'replicas' | 'cpu' | 'memory' | 'networks' | 'cmdParam' | 'runCMD' | 'appName' + | 'imageName' + | 'replicas' + | 'cpu' + | 'memory' + | 'networks' + | 'cmdParam' + | 'runCMD' + | 'appName' + | 'labels' >; export type TAppSourceType = 'app_store' | 'sealaf'; diff --git a/frontend/providers/applaunchpad/src/utils/adapt.ts b/frontend/providers/applaunchpad/src/utils/adapt.ts index 0c05b3787f0..5b5b723db81 100644 --- a/frontend/providers/applaunchpad/src/utils/adapt.ts +++ b/frontend/providers/applaunchpad/src/utils/adapt.ts @@ -382,8 +382,10 @@ export const adaptEditAppData = (app: AppDetailType): AppEditType => { 'configMapList', 'secret', 'storeList', - 'gpu' + 'gpu', + 'labels' ]; + const res: Record = {}; keys.forEach((key) => { diff --git a/frontend/providers/applaunchpad/src/utils/deployYaml2Json.ts b/frontend/providers/applaunchpad/src/utils/deployYaml2Json.ts index 1f10a7a932e..3fa0ebe293f 100644 --- a/frontend/providers/applaunchpad/src/utils/deployYaml2Json.ts +++ b/frontend/providers/applaunchpad/src/utils/deployYaml2Json.ts @@ -15,6 +15,7 @@ import yaml from 'js-yaml'; export const json2DeployCr = (data: AppEditType, type: 'deployment' | 'statefulset') => { const totalStorage = data.storeList.reduce((acc, item) => acc + item.value, 0); + console.log(data, 'form'); const metadata = { name: data.appName, @@ -25,6 +26,7 @@ export const json2DeployCr = (data: AppEditType, type: 'deployment' | 'statefuls [deployPVCResizeKey]: `${totalStorage}Gi` }, labels: { + ...(data.labels || {}), [appDeployKey]: data.appName, app: data.appName } From 2fd7835a40bbc766cd2304e3ed741caec327a123 Mon Sep 17 00:00:00 2001 From: zjy <3161362058@qq.com> Date: Thu, 28 Nov 2024 16:20:43 +0800 Subject: [PATCH 2/4] delete log --- frontend/providers/applaunchpad/src/pages/_app.tsx | 11 +---------- .../providers/applaunchpad/src/pages/redirect.tsx | 4 +--- .../applaunchpad/src/utils/deployYaml2Json.ts | 1 - 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/frontend/providers/applaunchpad/src/pages/_app.tsx b/frontend/providers/applaunchpad/src/pages/_app.tsx index 935cc4cdef0..d7aa016e22c 100644 --- a/frontend/providers/applaunchpad/src/pages/_app.tsx +++ b/frontend/providers/applaunchpad/src/pages/_app.tsx @@ -124,7 +124,6 @@ const App = ({ Component, pageProps }: AppProps) => { return () => { const currentPath = router.asPath; if (router.isReady && !currentPath.includes('/redirect')) { - console.log(currentPath); setLastRoute(currentPath); } }; @@ -142,7 +141,6 @@ const App = ({ Component, pageProps }: AppProps) => { e: MessageEvent<{ type?: string; name?: string; - formData?: string; }> ) => { const whitelist = [`https://${DESKTOP_DOMAIN}`]; @@ -151,7 +149,7 @@ const App = ({ Component, pageProps }: AppProps) => { } try { if (e.data?.type === 'InternalAppCall') { - const { name, formData } = e.data; + const { name } = e.data; if (name) { router.push({ pathname: '/app/detail', @@ -159,13 +157,6 @@ const App = ({ Component, pageProps }: AppProps) => { name: name } }); - } else if (formData) { - router.push({ - pathname: '/app/edit', - query: { - formData: formData - } - }); } } } catch (error) { diff --git a/frontend/providers/applaunchpad/src/pages/redirect.tsx b/frontend/providers/applaunchpad/src/pages/redirect.tsx index c51956842c1..33333fe7e4f 100644 --- a/frontend/providers/applaunchpad/src/pages/redirect.tsx +++ b/frontend/providers/applaunchpad/src/pages/redirect.tsx @@ -11,13 +11,11 @@ const RedirectPage = () => { const handleRedirect = (formData?: string) => { if (formData) { const parsedData: Partial = JSON.parse(decodeURIComponent(formData)); - console.log(parsedData, 'parsedData'); - const appName = parsedData?.appName; + if (appName) { getAppByName(appName) .then((app) => { - console.log(app, 'app'); if (app.isPause) { router.replace({ pathname: '/app/detail', diff --git a/frontend/providers/applaunchpad/src/utils/deployYaml2Json.ts b/frontend/providers/applaunchpad/src/utils/deployYaml2Json.ts index 3fa0ebe293f..a290b372ed8 100644 --- a/frontend/providers/applaunchpad/src/utils/deployYaml2Json.ts +++ b/frontend/providers/applaunchpad/src/utils/deployYaml2Json.ts @@ -15,7 +15,6 @@ import yaml from 'js-yaml'; export const json2DeployCr = (data: AppEditType, type: 'deployment' | 'statefulset') => { const totalStorage = data.storeList.reduce((acc, item) => acc + item.value, 0); - console.log(data, 'form'); const metadata = { name: data.appName, From 1318c2f074efe2399a83b94e65da6fb89fefbd67 Mon Sep 17 00:00:00 2001 From: zjy <3161362058@qq.com> Date: Fri, 29 Nov 2024 10:12:59 +0800 Subject: [PATCH 3/4] update --- .../providers/applaunchpad/src/pages/_app.tsx | 14 +++++---- .../applaunchpad/src/pages/redirect.tsx | 30 +------------------ 2 files changed, 10 insertions(+), 34 deletions(-) diff --git a/frontend/providers/applaunchpad/src/pages/_app.tsx b/frontend/providers/applaunchpad/src/pages/_app.tsx index d7aa016e22c..5a42c0e0dec 100644 --- a/frontend/providers/applaunchpad/src/pages/_app.tsx +++ b/frontend/providers/applaunchpad/src/pages/_app.tsx @@ -141,6 +141,7 @@ const App = ({ Component, pageProps }: AppProps) => { e: MessageEvent<{ type?: string; name?: string; + formData?: string; }> ) => { const whitelist = [`https://${DESKTOP_DOMAIN}`]; @@ -149,13 +150,16 @@ const App = ({ Component, pageProps }: AppProps) => { } try { if (e.data?.type === 'InternalAppCall') { - const { name } = e.data; - if (name) { + const { name, formData } = e.data; + if (formData) { + router.push({ + pathname: '/redirect', + query: { formData } + }); + } else if (name) { router.push({ pathname: '/app/detail', - query: { - name: name - } + query: { name } }); } } diff --git a/frontend/providers/applaunchpad/src/pages/redirect.tsx b/frontend/providers/applaunchpad/src/pages/redirect.tsx index 33333fe7e4f..4d2d6b35344 100644 --- a/frontend/providers/applaunchpad/src/pages/redirect.tsx +++ b/frontend/providers/applaunchpad/src/pages/redirect.tsx @@ -1,5 +1,4 @@ import { getAppByName } from '@/api/app'; -import { DESKTOP_DOMAIN } from '@/store/static'; import { AppEditSyncedFields } from '@/types/app'; import { useRouter } from 'next/router'; import { useEffect } from 'react'; @@ -47,37 +46,10 @@ const RedirectPage = () => { handleRedirect(formData); }; - const handlePostMessage = ( - e: MessageEvent<{ - type?: string; - formData?: string; - }> - ) => { - const whitelist = [`https://${DESKTOP_DOMAIN}`]; - if (!whitelist.includes(e.origin)) { - return; - } - - try { - if (e.data?.type === 'InternalAppCall') { - const { formData } = e.data; - handleRedirect(formData); - } - } catch (error) { - console.log('app redirect error:', error); - } - }; - - window.addEventListener('message', handlePostMessage); - if (router.isReady) { handleUrlParams(); } - - return () => { - window.removeEventListener('message', handlePostMessage); - }; - }, [router.isReady, router.query]); + }, [router, router.isReady, router.query]); return null; }; From 852fa63080d543b90ce9c57b79b21cea260c53df Mon Sep 17 00:00:00 2001 From: zjy <3161362058@qq.com> Date: Fri, 29 Nov 2024 10:39:05 +0800 Subject: [PATCH 4/4] fix pathname --- frontend/providers/applaunchpad/src/pages/_app.tsx | 4 ++-- frontend/providers/applaunchpad/src/pages/redirect.tsx | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/frontend/providers/applaunchpad/src/pages/_app.tsx b/frontend/providers/applaunchpad/src/pages/_app.tsx index 5a42c0e0dec..3f4e5f25314 100644 --- a/frontend/providers/applaunchpad/src/pages/_app.tsx +++ b/frontend/providers/applaunchpad/src/pages/_app.tsx @@ -152,12 +152,12 @@ const App = ({ Component, pageProps }: AppProps) => { if (e.data?.type === 'InternalAppCall') { const { name, formData } = e.data; if (formData) { - router.push({ + router.replace({ pathname: '/redirect', query: { formData } }); } else if (name) { - router.push({ + router.replace({ pathname: '/app/detail', query: { name } }); diff --git a/frontend/providers/applaunchpad/src/pages/redirect.tsx b/frontend/providers/applaunchpad/src/pages/redirect.tsx index 4d2d6b35344..03ddc8b5b88 100644 --- a/frontend/providers/applaunchpad/src/pages/redirect.tsx +++ b/frontend/providers/applaunchpad/src/pages/redirect.tsx @@ -1,10 +1,12 @@ import { getAppByName } from '@/api/app'; +import { useGlobalStore } from '@/store/global'; import { AppEditSyncedFields } from '@/types/app'; import { useRouter } from 'next/router'; import { useEffect } from 'react'; const RedirectPage = () => { const router = useRouter(); + const { setLastRoute } = useGlobalStore(); useEffect(() => { const handleRedirect = (formData?: string) => { @@ -21,6 +23,7 @@ const RedirectPage = () => { query: { name: appName } }); } else { + setLastRoute(`/app/detail?name=${appName}`); router.replace({ pathname: '/app/edit', query: { name: appName, formData } @@ -28,6 +31,7 @@ const RedirectPage = () => { } }) .catch((err) => { + setLastRoute('/'); router.replace({ pathname: '/app/edit', query: { formData }