diff --git a/react/src/components/DeploymentPresetDetailContent.tsx b/react/src/components/DeploymentPresetDetailContent.tsx index b83478c544..424325e583 100644 --- a/react/src/components/DeploymentPresetDetailContent.tsx +++ b/react/src/components/DeploymentPresetDetailContent.tsx @@ -3,6 +3,8 @@ Copyright (c) 2015-2026 Lablup Inc. All rights reserved. */ import type { DeploymentPresetDetailContentFragment$key } from '../__generated__/DeploymentPresetDetailContentFragment.graphql'; +import { convertToBinaryUnit } from '../helper'; +import { ResourceNumbersOfSession } from '../pages/SessionLauncherPage'; import { Descriptions, Typography } from 'antd'; import { BAICard, BAIFlex } from 'backend.ai-ui'; import React from 'react'; @@ -26,7 +28,6 @@ const DeploymentPresetDetailContent: React.FC< id name description - rank runtimeVariantId runtimeVariant { id @@ -51,6 +52,14 @@ const DeploymentPresetDetailContent: React.FC< value } } + resourceSlots { + edges { + node { + slotName + quantity + } + } + } deploymentDefaults { openToPublic replicaCount @@ -88,7 +97,13 @@ const DeploymentPresetDetailContent: React.FC< items={[ { label: t('adminDeploymentPreset.Image'), - children: preset.execution?.image || '-', + children: preset.execution?.image ? ( + + {preset.execution.image} + + ) : ( + '-' + ), }, { label: t('adminDeploymentPreset.Runtime'), @@ -122,26 +137,57 @@ const DeploymentPresetDetailContent: React.FC< title={t('adminDeploymentPreset.SectionResources')} styles={{ body: { paddingTop: 0 } }} > - opt.name !== 'shmem') - .map((opt) => ({ - label: opt.name, - children: opt.value, - })) ?? []), - ]} - /> + + { + const slots = (preset.resourceSlots?.edges ?? []) + .map((e) => e?.node) + .filter((n) => n != null); + const cpuSlot = slots.find((n) => n!.slotName === 'cpu'); + const memSlot = slots.find((n) => n!.slotName === 'mem'); + const accelSlot = slots.find( + (n) => n!.slotName !== 'cpu' && n!.slotName !== 'mem', + ); + const memBytes = memSlot ? parseFloat(memSlot.quantity) : 0; + const memGiB = + convertToBinaryUnit(memBytes, 'g', 0, true)?.number ?? 0; + return { + cpu: cpuSlot ? parseFloat(cpuSlot.quantity) : 0, + mem: `${memGiB}g`, + ...(accelSlot + ? { + accelerator: parseFloat(accelSlot.quantity), + acceleratorType: accelSlot.slotName, + } + : {}), + }; + })()} + /> + {(shmem || + (preset.resource?.resourceOpts?.filter((o) => o.name !== 'shmem') + .length ?? 0) > 0) && ( + opt.name !== 'shmem') + .map((opt) => ({ + label: opt.name, + children: opt.value, + })) ?? []), + ]} + /> + )} + = ({ description rank runtimeVariantId + ...DeploymentPresetDetailContentFragment } } } @@ -152,17 +156,7 @@ const VFolderDeployModalContent: React.FC = ({ return ( deploymentRevisionPresets?.edges ?.map((edge) => edge?.node) - .filter( - ( - node, - ): node is { - readonly id: string; - readonly name: string; - readonly description: string | null; - readonly rank: number; - readonly runtimeVariantId: string; - } => node != null, - ) ?? [] + .filter((node): node is NonNullable => node != null) ?? [] ); }, [deploymentRevisionPresets]); @@ -278,9 +272,8 @@ const VFolderDeployModalContent: React.FC = ({ const [userSelectedPresetId, setUserSelectedPresetId] = useState< string | undefined >(undefined); - const [presetDetailId, setPresetDetailId] = useState( - undefined, - ); + const [presetDetailFrgmt, setPresetDetailFrgmt] = + useState(null); const effectivePresetId = userSelectedPresetId ?? (availablePresets[0]?.id ? toLocalId(availablePresets[0].id) : undefined); @@ -408,7 +401,12 @@ const VFolderDeployModalContent: React.FC = ({