diff --git a/react/src/App.tsx b/react/src/App.tsx index e12681a1c..4bd66d7df 100644 --- a/react/src/App.tsx +++ b/react/src/App.tsx @@ -11,7 +11,7 @@ import { useSuspendedBackendaiClient } from './hooks'; import { useBAISettingUserState } from './hooks/useBAISetting'; import Page401 from './pages/Page401'; import Page404 from './pages/Page404'; -import VFolderListPage from './pages/VFolderListPage'; +// import VFolderListPage from './pages/VFolderListPage'; import { Skeleton, theme } from 'antd'; import React, { Suspense } from 'react'; import { FC } from 'react'; @@ -64,6 +64,10 @@ const AdminDashboardPage = React.lazy( ); const DashboardPage = React.lazy(() => import('./pages/DashboardPage')); +const NeoVFolderListPage = React.lazy( + () => import('./pages/NeoVFolderListPage'), +); + const RedirectToStart = () => { useSuspendedBackendaiClient(); const pathName = '/start'; @@ -250,7 +254,8 @@ const router = createBrowserRouter([ handle: { labelKey: 'webui.menu.Data&Storage' }, element: ( - + {/* */} + ), }, diff --git a/react/src/components/AllocatedResourcesCard.tsx b/react/src/components/AllocatedResourcesCard.tsx index 853a44a91..7284a31d5 100644 --- a/react/src/components/AllocatedResourcesCard.tsx +++ b/react/src/components/AllocatedResourcesCard.tsx @@ -1,8 +1,21 @@ -import { useCurrentProjectValue } from '../hooks/useCurrentProject'; +import { humanReadableBinarySize, iSizeToSize } from '../helper'; +import { useSuspendedBackendaiClient } from '../hooks'; +import { useResourceSlotsDetails } from '../hooks/backendai'; +import { useSuspenseTanQuery } from '../hooks/reactQueryAlias'; +import { + useCurrentProjectValue, + useCurrentResourceGroupValue, +} from '../hooks/useCurrentProject'; +import { + ResourceSlots, + ResourceAllocation, + limitParser, +} from '../hooks/useResourceLimitAndRemaining'; +import BAILayoutCard from './BAILayoutCard'; import Flex from './Flex'; import ResourceGroupSelect from './ResourceGroupSelect'; +import ResourceGroupSelectForCurrentProject from './ResourceGroupSelectForCurrentProject'; import ResourceUnit, { ResourceUnitProps } from './ResourceUnit'; -import BAILayoutCard from './BAILayoutCard'; import { QuestionCircleOutlined, SyncOutlined } from '@ant-design/icons'; import { Button, @@ -30,33 +43,101 @@ const AllocatedResourcesCard: React.FC = ({ }) => { const { token } = theme.useToken(); const { t } = useTranslation(); + const currentResourceGroup = useCurrentResourceGroupValue(); // use global state const currentProject = useCurrentProjectValue(); + const baiClient = useSuspendedBackendaiClient(); + const { mergedResourceSlots } = useResourceSlotsDetails(); + + const { data: resourceAllocation, refetch } = useSuspenseTanQuery< + ResourceAllocation | undefined + >({ + queryKey: ['check-presets', currentProject.name, currentResourceGroup], + queryFn: () => { + if (currentResourceGroup) { + return baiClient.resourcePreset + .check({ + group: currentProject.name, + scaling_group: currentResourceGroup, + }) + .catch(() => {}); + } else { + return; + } + }, + // onSuccess: (data) => { + // if (!data) { + // refetch(); + // } + // }, + // suspense: !_.isEmpty(currentResourceGroup), //prevent flicking + }); + + const mergeResources = (remaining: any, using: any) => { + let merged: ResourceSlots = { + cpu: '', + mem: '', + }; + + [remaining, using].forEach((obj) => { + Object.entries(obj).forEach(([key, value]) => { + const numValue = parseFloat(value as string) || 0; + merged[key] = (parseFloat(merged[key] || '0') + numValue).toString(); + }); + }); + + return merged; + }; + + const remaining = + resourceAllocation?.scaling_groups[currentResourceGroup as string] + ?.remaining || {}; + const using = + resourceAllocation?.scaling_groups[currentResourceGroup as string]?.using || + {}; + const mergedResources: ResourceSlots = mergeResources(remaining, using); + + const accelerators = _.omit(mergedResources, ['cpu', 'mem']); + const usingAccelerators: { [key: string]: string } = _.omit(using, [ + 'cpu', + 'mem', + ]); + + console.log(iSizeToSize(limitParser(using?.mem) + '', 'g', 0)); + + const acceleratorData = _.map(accelerators, (value, key) => ({ + name: mergedResourceSlots[key]?.human_readable_name || key.toUpperCase(), + displayUnit: mergedResourceSlots[key]?.display_unit || 'Unit', + value: usingAccelerators[key], + percentage: + (parseInt(usingAccelerators[key]) / parseInt(mergedResources[key])) * 100, + })); - const resourceUnitMockData: Array = [ + const resourceUnitData: Array = [ { name: 'CPU', displayUnit: 'Core', - value: 12, - percentage: (4 / 12) * 100, + value: using?.cpu as string, + percentage: + (parseInt(using?.cpu as string) / parseInt(mergedResources.cpu)) * 100, }, { name: 'RAM', displayUnit: 'GiB', - value: 256, - percentage: (8 / 12) * 100, - }, - { - name: 'FGPU', - displayUnit: 'GiB', - value: 3.5, - percentage: (4 / 12) * 100, - }, - { - name: 'ATOM', - displayUnit: 'Unit', - value: 2, - percentage: (2 / 12) * 100, + value: iSizeToSize(limitParser(using?.mem) + '', 'g', 0)?.number?.toFixed( + 1, + ) as string, + percentage: + (parseInt( + iSizeToSize(limitParser(using?.mem) + '', 'g', 0) + ?.numberFixed as string, + ) / + parseInt( + iSizeToSize(limitParser(mergedResources.mem) + '', 'g', 0) + ?.numberFixed as string, + )) * + 100, }, + ...acceleratorData, ]; return ( = ({ } extra={ <> - + variant="borderless" + showSearch + />