From 6a8dc6812ce884aec3585d8c7394327ee45be229 Mon Sep 17 00:00:00 2001 From: mlhiter <3076438032@qq.com> Date: Fri, 21 Feb 2025 15:46:26 +0800 Subject: [PATCH] fix: merge cause code bug --- frontend/providers/devbox/api/template.ts | 3 + .../form/BasicConfiguration/GpuSelector.tsx | 1 + .../devbox/create/components/form/index.tsx | 34 +------ .../[lang]/(platform)/devbox/create/page.tsx | 94 ------------------- .../detail/[name]/components/BasicInfo.tsx | 8 +- .../templateRepository/listOfficial/route.ts | 7 +- frontend/providers/devbox/types/k8s.d.ts | 4 + 7 files changed, 21 insertions(+), 130 deletions(-) diff --git a/frontend/providers/devbox/api/template.ts b/frontend/providers/devbox/api/template.ts index 055e070455c..81fc247feca 100644 --- a/frontend/providers/devbox/api/template.ts +++ b/frontend/providers/devbox/api/template.ts @@ -14,6 +14,9 @@ export const listOfficialTemplateRepository = () => kind: TemplateRepositoryKind; iconId: string; description: string | null; + templateRepositoryTags: { + tag: Tag; + }[]; }[]; }>(`/api/templateRepository/listOfficial`); export const listTemplateRepository = ( diff --git a/frontend/providers/devbox/app/[lang]/(platform)/devbox/create/components/form/BasicConfiguration/GpuSelector.tsx b/frontend/providers/devbox/app/[lang]/(platform)/devbox/create/components/form/BasicConfiguration/GpuSelector.tsx index f8b3a593331..43650cb206f 100644 --- a/frontend/providers/devbox/app/[lang]/(platform)/devbox/create/components/form/BasicConfiguration/GpuSelector.tsx +++ b/frontend/providers/devbox/app/[lang]/(platform)/devbox/create/components/form/BasicConfiguration/GpuSelector.tsx @@ -25,6 +25,7 @@ export default function GpuSelector({ ['list-official-template-repository'], listOfficialTemplateRepository ); + const templateData = useMemo( () => templateRepositoryQuery.data?.templateRepositoryList || [], [templateRepositoryQuery.data] diff --git a/frontend/providers/devbox/app/[lang]/(platform)/devbox/create/components/form/index.tsx b/frontend/providers/devbox/app/[lang]/(platform)/devbox/create/components/form/index.tsx index d230e5e6e31..ef621296aec 100644 --- a/frontend/providers/devbox/app/[lang]/(platform)/devbox/create/components/form/index.tsx +++ b/frontend/providers/devbox/app/[lang]/(platform)/devbox/create/components/form/index.tsx @@ -1,12 +1,6 @@ 'use client'; 'use client'; -import { Box, Flex, Grid, useTheme } from '@chakra-ui/react'; -import { Tabs } from '@sealos/ui'; -import { throttle } from 'lodash'; -import { useTranslations } from 'next-intl'; -import { useEffect, useState } from 'react'; -import { useFormContext } from 'react-hook-form'; import { Box, Flex, Grid, useTheme } from '@chakra-ui/react'; import { Tabs } from '@sealos/ui'; import { throttle } from 'lodash'; @@ -14,22 +8,13 @@ import { useTranslations } from 'next-intl'; import { useEffect, useState } from 'react'; import { useFormContext } from 'react-hook-form'; -import MyIcon from '@/components/Icon'; -import PriceBox from '@/components/PriceBox'; -import QuotaBox from '@/components/QuotaBox'; -import { useRouter } from '@/i18n'; import MyIcon from '@/components/Icon'; import PriceBox from '@/components/PriceBox'; import QuotaBox from '@/components/QuotaBox'; import { useRouter } from '@/i18n'; -import { useDevboxStore } from '@/stores/devbox'; import { useDevboxStore } from '@/stores/devbox'; -import type { DevboxEditTypeV2 } from '@/types/devbox'; -import { obj2Query } from '@/utils/tools'; -import BasicConfiguration from './BasicConfiguration'; -import NetworkConfiguration from './NetworkConfiguration'; import type { DevboxEditTypeV2 } from '@/types/devbox'; import { obj2Query } from '@/utils/tools'; import BasicConfiguration from './BasicConfiguration'; @@ -60,50 +45,35 @@ const Form = ({ icon: 'network' } ]; - const [activeNav, setActiveNav] = useState(navList[0].id); - const { devboxList } = useDevboxStore(); - ]; + const [activeNav, setActiveNav] = useState(navList[0].id); const { devboxList } = useDevboxStore(); // listen scroll and set activeNav useEffect(() => { const scrollFn = throttle((e: Event) => { - if (!e.target) return; if (!e.target) return; const doms = navList.map((item) => ({ dom: document.getElementById(item.id), id: item.id })); - })); - const dom = e.target as HTMLDivElement; - const scrollTop = dom.scrollTop; const dom = e.target as HTMLDivElement; const scrollTop = dom.scrollTop; for (let i = doms.length - 1; i >= 0; i--) { const offsetTop = doms[i].dom?.offsetTop || 0; - const offsetTop = doms[i].dom?.offsetTop || 0; if (scrollTop + 500 >= offsetTop) { setActiveNav(doms[i].id); break; - setActiveNav(doms[i].id); - break; } } }, 200); - document.getElementById('form-container')?.addEventListener('scroll', scrollFn); - }, 200); - document.getElementById('form-container')?.addEventListener('scroll', scrollFn); return () => { document.getElementById('form-container')?.removeEventListener('scroll', scrollFn); - }; - document.getElementById('form-container')?.removeEventListener('scroll', scrollFn); }; // eslint-disable-next-line }, []); - }, []); const boxStyles = { border: theme.borders.base, @@ -111,7 +81,6 @@ const Form = ({ mb: 4, bg: 'white' }; - }; return ( import('@/components/modals/ErrorModal')); const ErrorModal = dynamic(() => import('@/components/modals/ErrorModal')); const DevboxCreatePage = () => { const { env } = useEnvStore(); @@ -80,8 +57,6 @@ const DevboxCreatePage = () => { const [errorMessage, setErrorMessage] = useState(''); const [yamlList, setYamlList] = useState([]); - const tabType = searchParams.get('type') || 'form'; - const devboxName = searchParams.get('name') || ''; const tabType = searchParams.get('type') || 'form'; const devboxName = searchParams.get('name') || ''; @@ -89,10 +64,7 @@ const DevboxCreatePage = () => { // fix a bug: searchParams will disappear when go into this page const [captureDevboxName, setCaptureDevboxName] = useState(''); const { updateTemplateModalConfig, config: templateConfig } = useTemplateStore(); - const [captureDevboxName, setCaptureDevboxName] = useState(''); - const { updateTemplateModalConfig, config: templateConfig } = useTemplateStore(); useEffect(() => { - const name = searchParams.get('name'); const name = searchParams.get('name'); if (name) { setCaptureDevboxName(name); @@ -101,54 +73,40 @@ const DevboxCreatePage = () => { router.replace(`/devbox/create?name=${captureDevboxName}`, undefined); } }, [searchParams, router, captureDevboxName]); - }, [searchParams, router, captureDevboxName]); // eslint-disable-next-line react-hooks/exhaustive-deps const isEdit = useMemo(() => !!devboxName, []); - const isEdit = useMemo(() => !!devboxName, []); - const { title, applyBtnText, applyMessage, applySuccess, applyError } = editModeMap(isEdit); const { title, applyBtnText, applyMessage, applySuccess, applyError } = editModeMap(isEdit); const { openConfirm, ConfirmChild } = useConfirm({ content: applyMessage }); - }); // compute container width const { screenWidth, lastRoute } = useGlobalStore(); - const { screenWidth, lastRoute } = useGlobalStore(); const pxVal = useMemo(() => { - const val = Math.floor((screenWidth - 1050) / 2); const val = Math.floor((screenWidth - 1050) / 2); if (val < 20) { return 20; - return 20; } return val; }, [screenWidth]); - return val; - }, [screenWidth]); const formHook = useForm({ defaultValues: defaultDevboxEditValueV2 }); - }); // updateyamlList every time yamlList change const debouncedUpdateYaml = useMemo( - () => () => debounce((data: DevboxEditTypeV2, env) => { try { const newYamlList = generateYamlList(data, env); setYamlList(newYamlList); - const newYamlList = generateYamlList(data, env); - setYamlList(newYamlList); } catch (error) { console.error('Failed to generate yaml:', error); - console.error('Failed to generate yaml:', error); } }, 300), [] @@ -171,7 +129,6 @@ const DevboxCreatePage = () => { debouncedUpdateYaml(value as DevboxEditTypeV2, env); } }); - }); return () => { subscription.unsubscribe(); debouncedUpdateYaml.cancel(); @@ -189,45 +146,32 @@ const DevboxCreatePage = () => { if (!devboxName) { setYamlList(generateDefaultYamlList()); return null; - setYamlList(generateDefaultYamlList()); - return null; } setIsLoading(true); return setDevboxDetail(devboxName, env.sealosDomain); - setIsLoading(true); - return setDevboxDetail(devboxName, env.sealosDomain); }, { onSuccess(res) { if (!res) { return; - return; } oldDevboxEditData.current = res; formOldYamls.current = generateYamlList(res, env); crOldYamls.current = generateYamlList(res, env) as DevboxKindsType[]; formHook.reset(res); - oldDevboxEditData.current = res; - formOldYamls.current = generateYamlList(res, env); - crOldYamls.current = generateYamlList(res, env) as DevboxKindsType[]; - formHook.reset(res); }, onError(err) { toast({ title: String(err), status: 'error' }); - }); }, onSettled() { setIsLoading(false); - setIsLoading(false); } } ); - ); const submitSuccess = async (formData: DevboxEditTypeV2) => { - setIsLoading(true); setIsLoading(true); try { // gpu inventory check @@ -246,19 +190,15 @@ const DevboxCreatePage = () => { const quoteCheckRes = checkQuotaAllow( { ...formData, nodeports: devboxList.length + 1 } as DevboxEditTypeV2 & { nodeports: number; - nodeports: number; }, { ...oldDevboxEditData.current, nodeports: devboxList.length } as DevboxEditType & { nodeports: number; - nodeports: number; } ); - ); if (quoteCheckRes) { - setIsLoading(false); setIsLoading(false); return toast({ status: 'warning', @@ -266,14 +206,9 @@ const DevboxCreatePage = () => { duration: 5000, isClosable: true }); - }); } // update if (isEdit) { - const yamlList = generateYamlList(formData, env); - setYamlList(yamlList); - const parsedNewYamlList = yamlList.map((item) => item.value); - const parsedOldYamlList = formOldYamls.current.map((item) => item.value); const yamlList = generateYamlList(formData, env); setYamlList(yamlList); const parsedNewYamlList = yamlList.map((item) => item.value); @@ -281,9 +216,7 @@ const DevboxCreatePage = () => { const areYamlListsEqual = new Set(parsedNewYamlList).size === new Set(parsedOldYamlList).size && [...new Set(parsedNewYamlList)].every((item) => new Set(parsedOldYamlList).has(item)); - [...new Set(parsedNewYamlList)].every((item) => new Set(parsedOldYamlList).has(item)); if (areYamlListsEqual) { - setIsLoading(false); setIsLoading(false); return toast({ status: 'info', @@ -291,11 +224,7 @@ const DevboxCreatePage = () => { duration: 5000, isClosable: true }); - }); } - if (!parsedNewYamlList) { - // prevent empty yamlList - return setErrorMessage(t('submit_form_error')); if (!parsedNewYamlList) { // prevent empty yamlList return setErrorMessage(t('submit_form_error')); @@ -305,23 +234,18 @@ const DevboxCreatePage = () => { parsedNewYamlList: parsedNewYamlList, originalYamlList: crOldYamls.current }); - }); await updateDevbox({ patch, devboxName: formData.name }); - }); } else { await createDevbox({ devboxForm: formData }); - await createDevbox({ devboxForm: formData }); } addDevboxIDE('vscode', formData.name); - addDevboxIDE('vscode', formData.name); toast({ title: t(applySuccess), status: 'success' }); - }); updateTemplateModalConfig({ ...templateConfig, lastRoute @@ -331,33 +255,24 @@ const DevboxCreatePage = () => { } router.push(lastRoute); } catch (error) { - console.log('error', error); console.log('error', error); if (error instanceof String && error.includes('402')) { setErrorMessage(t('outstanding_tips')); } else setErrorMessage(JSON.stringify(error)); - setErrorMessage(t('outstanding_tips')); - } else setErrorMessage(JSON.stringify(error)); } setIsLoading(false); }; - setIsLoading(false); - }; const submitError = useCallback(() => { // deep search message const deepSearch = (obj: any): string => { if (!obj || typeof obj !== 'object') { return t('submit_form_error'); - return t('submit_form_error'); } if (!!obj.message) { return obj.message; - return obj.message; } return deepSearch(Object.values(obj)[0]); - }; - return deepSearch(Object.values(obj)[0]); }; toast({ title: deepSearch(formHook.formState.errors), @@ -367,8 +282,6 @@ const DevboxCreatePage = () => { isClosable: true }); }, [formHook.formState.errors, toast, t]); - }); - }, [formHook.formState.errors, toast, t]); return ( <> @@ -409,12 +322,5 @@ const DevboxCreatePage = () => { ); }; - {!!errorMessage && ( - setErrorMessage('')} /> - )} - - ); -}; export default DevboxCreatePage; -export default DevboxCreatePage; diff --git a/frontend/providers/devbox/app/[lang]/(platform)/devbox/detail/[name]/components/BasicInfo.tsx b/frontend/providers/devbox/app/[lang]/(platform)/devbox/detail/[name]/components/BasicInfo.tsx index 717e0eb7219..43acdd31828 100644 --- a/frontend/providers/devbox/app/[lang]/(platform)/devbox/detail/[name]/components/BasicInfo.tsx +++ b/frontend/providers/devbox/app/[lang]/(platform)/devbox/detail/[name]/components/BasicInfo.tsx @@ -3,13 +3,16 @@ import { useTranslations } from 'next-intl'; import React, { useCallback, useState } from 'react'; import { Box, Text, Flex, Image, Spinner, Tooltip, Button } from '@chakra-ui/react'; -import MyIcon from '@/components/Icon'; import { useEnvStore } from '@/stores/env'; +import { usePriceStore } from '@/stores/price'; import { useDevboxStore } from '@/stores/devbox'; import { getTemplateConfig } from '@/api/template'; import { getSSHConnectionInfo } from '@/api/devbox'; -import { JetBrainsGuideData } from '@/components/IDEButton'; import { downLoadBlob, parseTemplateConfig } from '@/utils/tools'; + +import MyIcon from '@/components/Icon'; +import GPUItem from '@/components/GPUItem'; +import { JetBrainsGuideData } from '@/components/IDEButton'; import SshConnectModal from '@/components/modals/SshConnectModal'; const BasicInfo = () => { @@ -18,6 +21,7 @@ const BasicInfo = () => { const { env } = useEnvStore(); const { devboxDetail } = useDevboxStore(); + const { sourcePrice, setSourcePrice } = usePriceStore(); const [loading, setLoading] = useState(false); const [onOpenSsHConnect, setOnOpenSsHConnect] = useState(false); diff --git a/frontend/providers/devbox/app/api/templateRepository/listOfficial/route.ts b/frontend/providers/devbox/app/api/templateRepository/listOfficial/route.ts index 0c96ee5da53..e8d8fa421b3 100644 --- a/frontend/providers/devbox/app/api/templateRepository/listOfficial/route.ts +++ b/frontend/providers/devbox/app/api/templateRepository/listOfficial/route.ts @@ -25,7 +25,12 @@ export const GET = async function GET(req: NextRequest) { iconId: true, name: true, uid: true, - description: true + description: true, + templateRepositoryTags: { + select: { + tag: true + } + } } }); return jsonRes({ diff --git a/frontend/providers/devbox/types/k8s.d.ts b/frontend/providers/devbox/types/k8s.d.ts index f0c3286af6e..df02526a53a 100644 --- a/frontend/providers/devbox/types/k8s.d.ts +++ b/frontend/providers/devbox/types/k8s.d.ts @@ -185,6 +185,10 @@ export interface KBDevboxSpecV2 { resource: { cpu: string; memory: string; + [gpuResourceKey]?: string; + }; + nodeSelector?: { + [gpuNodeSelectorKey]: string; }; state: DevboxStatusEnum; tolerations?: {