diff --git a/frontend/providers/devbox/.prettierrc.js b/frontend/providers/devbox/.prettierrc.js deleted file mode 100644 index b48f2c3caef..00000000000 --- a/frontend/providers/devbox/.prettierrc.js +++ /dev/null @@ -1,20 +0,0 @@ -module.exports = { - printWidth: 100, - tabWidth: 2, - useTabs: false, - semi: true, - singleQuote: true, - quoteProps: 'as-needed', - jsxSingleQuote: false, - trailingComma: 'none', - bracketSpacing: true, - jsxBracketSameLine: false, - arrowParens: 'always', - rangeStart: 0, - rangeEnd: Infinity, - requirePragma: false, - insertPragma: false, - proseWrap: 'preserve', - htmlWhitespaceSensitivity: 'css', - endOfLine: 'lf' -} diff --git a/frontend/providers/devbox/.prettierrc.json b/frontend/providers/devbox/.prettierrc.json new file mode 100644 index 00000000000..c3bc434d271 --- /dev/null +++ b/frontend/providers/devbox/.prettierrc.json @@ -0,0 +1,18 @@ +{ + "printWidth": 100, + "tabWidth": 2, + "useTabs": false, + "semi": false, + "singleQuote": true, + "quoteProps": "as-needed", + "trailingComma": "none", + "bracketSpacing": true, + "jsxBracketSameLine": true, + "bracketSameLine": true, + "arrowParens": "always", + "requirePragma": false, + "insertPragma": false, + "proseWrap": "preserve", + "htmlWhitespaceSensitivity": "ignore", + "endOfLine": "auto" +} diff --git a/frontend/providers/devbox/app/[lang]/(platform)/(home)/components/DevboxList.tsx b/frontend/providers/devbox/app/[lang]/(platform)/(home)/components/DevboxList.tsx index 7c0ff942e5b..0264056cc81 100644 --- a/frontend/providers/devbox/app/[lang]/(platform)/(home)/components/DevboxList.tsx +++ b/frontend/providers/devbox/app/[lang]/(platform)/(home)/components/DevboxList.tsx @@ -1,117 +1,113 @@ -import { Box, Button, Flex, Image, MenuButton, Text } from '@chakra-ui/react'; -import { SealosMenu, useMessage } from '@sealos/ui'; -import { useTranslations } from 'next-intl'; -import dynamic from 'next/dynamic'; -import { useCallback, useState } from 'react'; -import { sealosApp } from 'sealos-desktop-sdk/app'; +import { Box, Button, Flex, Image, MenuButton, Text } from '@chakra-ui/react' +import { MyTable, SealosMenu, useMessage } from '@sealos/ui' +import { useTranslations } from 'next-intl' +import dynamic from 'next/dynamic' +import { useCallback, useState } from 'react' +import { sealosApp } from 'sealos-desktop-sdk/app' -import { pauseDevbox, restartDevbox, startDevbox } from '@/api/devbox'; -import { useRouter } from '@/i18n'; -import { useGlobalStore } from '@/stores/global'; -import { DevboxListItemTypeV2 } from '@/types/devbox'; +import { pauseDevbox, restartDevbox, startDevbox } from '@/api/devbox' +import { useRouter } from '@/i18n' +import { useGlobalStore } from '@/stores/global' +import { DevboxListItemTypeV2 } from '@/types/devbox' -import DevboxStatusTag from '@/components/DevboxStatusTag'; -import MyIcon from '@/components/Icon'; -import IDEButton from '@/components/IDEButton'; -import ReleaseModal from '@/components/modals/releaseModal'; -import PodLineChart from '@/components/PodLineChart'; -import { AdvancedTable } from '@/components/AdvancedTable'; +import DevboxStatusTag from '@/components/DevboxStatusTag' +import MyIcon from '@/components/Icon' +import IDEButton from '@/components/IDEButton' +import ReleaseModal from '@/components/modals/releaseModal' +import PodLineChart from '@/components/PodLineChart' -const DelModal = dynamic(() => import('@/components/modals/DelModal')); +const DelModal = dynamic(() => import('@/components/modals/DelModal')) const DevboxList = ({ devboxList = [], refetchDevboxList }: { - devboxList: DevboxListItemTypeV2[]; - refetchDevboxList: () => void; + devboxList: DevboxListItemTypeV2[] + refetchDevboxList: () => void }) => { - const router = useRouter(); - const t = useTranslations(); - const { message: toast } = useMessage(); - const duplicatedDevboxList = Array(20) - .fill(0) - .flatMap(() => [...devboxList]); + const router = useRouter() + const t = useTranslations() + const { message: toast } = useMessage() // TODO: Unified Loading Behavior - const { setLoading } = useGlobalStore(); + const { setLoading } = useGlobalStore() - const [onOpenRelease, setOnOpenRelease] = useState(false); - const [delDevbox, setDelDevbox] = useState(null); + const [onOpenRelease, setOnOpenRelease] = useState(false) + const [delDevbox, setDelDevbox] = useState(null) const [currentDevboxListItem, setCurrentDevboxListItem] = useState( null - ); + ) const handleOpenRelease = (devbox: DevboxListItemTypeV2) => { - setCurrentDevboxListItem(devbox); - setOnOpenRelease(true); - }; + setCurrentDevboxListItem(devbox) + setOnOpenRelease(true) + } const handlePauseDevbox = useCallback( async (devbox: DevboxListItemTypeV2) => { try { - setLoading(true); - await pauseDevbox({ devboxName: devbox.name }); + setLoading(true) + await pauseDevbox({ devboxName: devbox.name }) toast({ title: t('pause_success'), status: 'success' - }); + }) } catch (error: any) { toast({ title: typeof error === 'string' ? error : error.message || t('pause_error'), status: 'error' - }); - console.error(error); + }) + console.error(error) } - refetchDevboxList(); - setLoading(false); + refetchDevboxList() + setLoading(false) }, [refetchDevboxList, setLoading, t, toast] - ); + ) const handleRestartDevbox = useCallback( async (devbox: DevboxListItemTypeV2) => { try { - setLoading(true); - await restartDevbox({ devboxName: devbox.name }); + setLoading(true) + await restartDevbox({ devboxName: devbox.name }) toast({ title: t('restart_success'), status: 'success' - }); + }) } catch (error: any) { toast({ title: typeof error === 'string' ? error : error.message || t('restart_error'), status: 'error' - }); - console.error(error, '=='); + }) + console.error(error, '==') } - refetchDevboxList(); - setLoading(false); + refetchDevboxList() + setLoading(false) }, [refetchDevboxList, setLoading, t, toast] - ); + ) const handleStartDevbox = useCallback( async (devbox: DevboxListItemTypeV2) => { try { - setLoading(true); - await startDevbox({ devboxName: devbox.name }); + setLoading(true) + await startDevbox({ devboxName: devbox.name }) toast({ title: t('start_success'), status: 'success' - }); + }) } catch (error: any) { toast({ title: typeof error === 'string' ? error : error.message || t('start_error'), status: 'error' - }); - console.error(error, '=='); + }) + console.error(error, '==') } - refetchDevboxList(); - setLoading(false); + refetchDevboxList() + setLoading(false) }, [refetchDevboxList, setLoading, t, toast] - ); + ) const handleGoToTerminal = useCallback( async (devbox: DevboxListItemTypeV2) => { - const defaultCommand = `kubectl exec -it $(kubectl get po -l app.kubernetes.io/name=${devbox.name} -oname) -- sh -c "clear; (bash || ash || sh)"`; + const defaultCommand = `kubectl exec -it $(kubectl get po -l app.kubernetes.io/name=${devbox.name} -oname) -- sh -c "clear; (bash || ash || sh)"` try { sealosApp.runEvents('openDesktopApp', { appKey: 'system-terminal', @@ -119,22 +115,22 @@ const DevboxList = ({ defaultCommand }, messageData: { type: 'new terminal', command: defaultCommand } - }); + }) } catch (error: any) { toast({ title: typeof error === 'string' ? error : error.message || t('jump_terminal_error'), status: 'error' - }); - console.error(error); + }) + console.error(error) } }, [t, toast] - ); + ) const columns: { - title: string; - dataIndex?: keyof DevboxListItemTypeV2; - key: string; - render?: (item: DevboxListItemTypeV2) => JSX.Element; + title: string + dataIndex?: keyof DevboxListItemTypeV2 + key: string + render?: (item: DevboxListItemTypeV2) => JSX.Element }[] = [ { title: t('name'), @@ -152,7 +148,7 @@ const DevboxList = ({ {item.name} - ); + ) } }, { @@ -165,7 +161,7 @@ const DevboxList = ({ dataIndex: 'createTime', key: 'createTime', render: (item) => { - return {item.createTime}; + return {item.createTime} } }, { @@ -183,8 +179,7 @@ const DevboxList = ({ right={'4px'} bottom={'0px'} pointerEvents={'none'} - textShadow="1px 1px 0 #FFF, -1px -1px 0 #FFF, 1px -1px 0 #FFF, -1px 1px 0 #FFF" - > + textShadow="1px 1px 0 #FFF, -1px -1px 0 #FFF, 1px -1px 0 #FFF, -1px 1px 0 #FFF"> {item?.usedCpu?.yData[item?.usedCpu?.yData?.length - 1]}% @@ -206,8 +201,7 @@ const DevboxList = ({ right={'4px'} bottom={'0px'} pointerEvents={'none'} - textShadow="1px 1px 0 #FFF, -1px -1px 0 #FFF, 1px -1px 0 #FFF, -1px 1px 0 #FFF" - > + textShadow="1px 1px 0 #FFF, -1px -1px 0 #FFF, 1px -1px 0 #FFF, -1px 1px 0 #FFF"> {item?.usedMemory?.yData[item?.usedMemory?.yData?.length - 1]}% @@ -238,9 +232,8 @@ const DevboxList = ({ minW={'unset'} // leftIcon={} onClick={() => { - router.push(`/devbox/detail/${item.name}`); - }} - > + router.push(`/devbox/detail/${item.name}`) + }}> {/* {t('detail')} */} @@ -344,10 +337,10 @@ const DevboxList = ({ ) } - ]; + ] return ( <> - + {!!delDevbox && ( { - router.push(`/devbox/detail/${currentDevboxListItem?.name}`); + router.push(`/devbox/detail/${currentDevboxListItem?.name}`) }} onClose={() => { - setOnOpenRelease(false); - setCurrentDevboxListItem(null); + setOnOpenRelease(false) + setCurrentDevboxListItem(null) }} devbox={currentDevboxListItem} /> )} - ); -}; + ) +} -export default DevboxList; +export default DevboxList diff --git a/frontend/providers/devbox/components/AdvancedTable.tsx b/frontend/providers/devbox/components/AdvancedTable.tsx deleted file mode 100644 index 401d677a628..00000000000 --- a/frontend/providers/devbox/components/AdvancedTable.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import React from 'react'; -import { Box, BoxProps, Grid, Flex } from '@chakra-ui/react'; - -interface Props extends BoxProps { - columns: { - title: string; - dataIndex?: string; - key: string; - render?: (item: any) => JSX.Element; - }[]; - data: any[]; - itemClass?: string; -} - -export const AdvancedTable = ({ columns, data, itemClass = '' }: Props) => { - return ( - <> - - {columns.map((item, i) => ( - - {item.title} - - ))} - - {data.map((item: any, index1) => ( - - {columns.map((col, index2) => ( - - {col.render ? col.render(item) : col.dataIndex ? `${item[col.dataIndex]}` : ''} - - ))} - - ))} - - ); -}; diff --git a/frontend/providers/devbox/stores/devbox.ts b/frontend/providers/devbox/stores/devbox.ts index 30690a18bb9..6618dbb04b8 100644 --- a/frontend/providers/devbox/stores/devbox.ts +++ b/frontend/providers/devbox/stores/devbox.ts @@ -1,6 +1,6 @@ -import { create } from 'zustand'; -import { devtools } from 'zustand/middleware'; -import { immer } from 'zustand/middleware/immer'; +import { create } from 'zustand' +import { devtools } from 'zustand/middleware' +import { immer } from 'zustand/middleware/immer' import { getDevboxByName, @@ -9,44 +9,40 @@ import { getDevboxVersionList, getMyDevboxList, getSSHConnectionInfo -} from '@/api/devbox'; -import { devboxStatusMap, PodStatusEnum } from '@/constants/devbox'; +} from '@/api/devbox' +import { devboxStatusMap, PodStatusEnum } from '@/constants/devbox' import type { DevboxDetailType, DevboxDetailTypeV2, DevboxListItemTypeV2, DevboxVersionListItemType -} from '@/types/devbox'; +} from '@/types/devbox' type State = { - devboxList: DevboxListItemTypeV2[]; - requestCache: Map>; - setDevboxList: () => Promise; - loadAvgMonitorData: (devboxName: string) => Promise; - devboxVersionList: DevboxVersionListItemType[]; + devboxList: DevboxListItemTypeV2[] + requestCache: Map> + setDevboxList: () => Promise + loadAvgMonitorData: (devboxName: string) => Promise + devboxVersionList: DevboxVersionListItemType[] startedTemplate?: { - uid: string; - iconId: string | null; - name: string; - }; - setStartedTemplate: ( - template: - | { - uid: string; - iconId: string | null; - name: string; - } - | undefined - ) => void; + uid: string, + iconId: string | null, + name: string, + } + setStartedTemplate: (template: { + uid: string, + iconId: string | null, + name: string, + } | undefined) => void, setDevboxVersionList: ( devboxName: string, devboxUid: string - ) => Promise; - devboxDetail?: DevboxDetailTypeV2; - setDevboxDetail: (devboxName: string, sealosDomain: string) => Promise; - intervalLoadPods: (devboxName: string, updateDetail: boolean) => Promise; - loadDetailMonitorData: (devboxName: string) => Promise; -}; + ) => Promise + devboxDetail?: DevboxDetailTypeV2 + setDevboxDetail: (devboxName: string, sealosDomain: string) => Promise + intervalLoadPods: (devboxName: string, updateDetail: boolean) => Promise + loadDetailMonitorData: (devboxName: string) => Promise +} export const useDevboxStore = create()( devtools( @@ -54,15 +50,15 @@ export const useDevboxStore = create()( devboxList: [], requestCache: new Map(), setDevboxList: async () => { - const res = await getMyDevboxList(); + const res = await getMyDevboxList() set((state) => { - state.devboxList = res; - }); - return res; + state.devboxList = res + }) + return res }, loadAvgMonitorData: async (devboxName) => { - const pods = await getDevboxPodsByDevboxName(devboxName); - const queryName = pods.length > 0 ? pods[0].podName : devboxName; + const pods = await getDevboxPodsByDevboxName(devboxName) + const queryName = pods.length > 0 ? pods[0].podName : devboxName const [averageCpuData, averageMemoryData] = await Promise.all([ getDevboxMonitorData({ @@ -75,7 +71,7 @@ export const useDevboxStore = create()( queryName: queryName, step: '2m' }) - ]); + ]) set((state) => { state.devboxList = state.devboxList.map((item) => ({ ...item, @@ -85,70 +81,69 @@ export const useDevboxStore = create()( item.name === devboxName && averageMemoryData[0] ? averageMemoryData[0] : item.usedMemory - })); - }); + })) + }) }, devboxVersionList: [], setDevboxVersionList: async (devboxName, devboxUid) => { - const res = await getDevboxVersionList(devboxName, devboxUid); + const res = await getDevboxVersionList(devboxName, devboxUid) set((state) => { - state.devboxVersionList = res; - }); - return res; + state.devboxVersionList = res + }) + return res }, setStartedTemplate(templateRepository) { set((state) => { - if (!templateRepository) state.startedTemplate = undefined; - else - state.startedTemplate = { - uid: templateRepository.uid, - iconId: templateRepository.iconId, - name: templateRepository.name - }; - }); + if(!templateRepository) state.startedTemplate = undefined + else state.startedTemplate = { + uid: templateRepository.uid, + iconId: templateRepository.iconId, + name: templateRepository.name + } + }) }, startedTemplate: undefined, devboxDetail: undefined, setDevboxDetail: async (devboxName: string, sealosDomain: string) => { - const detail = await getDevboxByName(devboxName); + const detail = await getDevboxByName(devboxName) if (detail.status.value !== 'Running') { set((state) => { - state.devboxDetail = detail; - }); - return detail; + state.devboxDetail = detail + }) + return detail } - const pods = await getDevboxPodsByDevboxName(devboxName); + const pods = await getDevboxPodsByDevboxName(devboxName) const { base64PrivateKey, userName } = await getSSHConnectionInfo({ devboxName: detail.name - }); + }) - const sshPrivateKey = Buffer.from(base64PrivateKey, 'base64').toString('utf-8'); + const sshPrivateKey = Buffer.from(base64PrivateKey, 'base64').toString('utf-8') const sshConfig = { sshUser: userName, sshDomain: sealosDomain, sshPort: detail.sshPort, sshPrivateKey - }; + } // add sshConfig - detail.sshConfig = sshConfig as DevboxDetailType['sshConfig']; + detail.sshConfig = sshConfig as DevboxDetailType['sshConfig'] // add upTime by Pod - detail.upTime = pods[0].upTime; + detail.upTime = pods[0].upTime set((state) => { - state.devboxDetail = detail; - }); + state.devboxDetail = detail + }) - return detail; + return detail }, intervalLoadPods: async (devboxName, updateDetail) => { - if (!devboxName) return Promise.reject('devbox name is empty'); + if (!devboxName) return Promise.reject('devbox name is empty') - const pods = await getDevboxPodsByDevboxName(devboxName); + const pods = await getDevboxPodsByDevboxName(devboxName) // TODO: change Running to podStatusMap.running // TODO: check status enum and backend status enum @@ -156,24 +151,24 @@ export const useDevboxStore = create()( pods.length === 0 ? devboxStatusMap.Stopped : pods.filter((pod) => pod.status.value === PodStatusEnum.running).length > 0 - ? devboxStatusMap.Running - : devboxStatusMap.Pending; + ? devboxStatusMap.Running + : devboxStatusMap.Pending set((state) => { if (state?.devboxDetail?.name === devboxName && updateDetail) { - state.devboxDetail.status = devboxStatus; + state.devboxDetail.status = devboxStatus } state.devboxList = state.devboxList.map((item) => ({ ...item, status: item.name === devboxName ? devboxStatus : item.status - })); - }); - return 'success'; + })) + }) + return 'success' }, loadDetailMonitorData: async (devboxName) => { - const pods = await getDevboxPodsByDevboxName(devboxName); + const pods = await getDevboxPodsByDevboxName(devboxName) - const queryName = pods.length > 0 ? pods[0].podName : devboxName; + const queryName = pods.length > 0 ? pods[0].podName : devboxName const [averageCpuData, averageMemoryData] = await Promise.all([ getDevboxMonitorData({ @@ -186,28 +181,28 @@ export const useDevboxStore = create()( queryName: queryName, step: '2m' }) - ]); + ]) set((state) => { if (state?.devboxDetail?.name === devboxName && state.devboxDetail?.isPause !== true) { state.devboxDetail.usedCpu = averageCpuData[0] ? averageCpuData[0] : { - xData: new Array(30).fill(0), - yData: new Array(30).fill('0'), - name: '' - }; + xData: new Array(30).fill(0), + yData: new Array(30).fill('0'), + name: '' + } state.devboxDetail.usedMemory = averageMemoryData[0] ? averageMemoryData[0] : { - xData: new Array(30).fill(0), - yData: new Array(30).fill('0'), - name: '' - }; + xData: new Array(30).fill(0), + yData: new Array(30).fill('0'), + name: '' + } } - }); - return 'success'; + }) + return 'success' } })) ) -); +)