diff --git a/react/src/components/AgentList.tsx b/react/src/components/AgentList.tsx index 75d2bb97ff..83cfaaf7f1 100644 --- a/react/src/components/AgentList.tsx +++ b/react/src/components/AgentList.tsx @@ -14,7 +14,7 @@ import BAIProgressWithLabel from './BAIProgressWithLabel'; import BAIPropertyFilter from './BAIPropertyFilter'; import DoubleTag from './DoubleTag'; import Flex from './Flex'; -import { ResourceTypeIcon, ResourceTypeKey } from './ResourceNumber'; +import { ResourceTypeIcon } from './ResourceNumber'; import TableColumnsSettingModal from './TableColumnsSettingModal'; import { AgentDetailModalFragment$key } from './__generated__/AgentDetailModalFragment.graphql'; import { @@ -361,10 +361,7 @@ const AgentList: React.FC = ({ return ( - + {parsedOccupiedSlots[key] ?? 0}/ {parsedAvailableSlots[key] ?? 0} diff --git a/react/src/components/ResourceAllocationFormItems.tsx b/react/src/components/ResourceAllocationFormItems.tsx index 04ee919f3b..2996ca2875 100644 --- a/react/src/components/ResourceAllocationFormItems.tsx +++ b/react/src/components/ResourceAllocationFormItems.tsx @@ -4,7 +4,7 @@ import { iSizeToSize, } from '../helper'; import { useSuspendedBackendaiClient } from '../hooks'; -import { useResourceSlots } from '../hooks/backendai'; +import { useResourceSlots, useResourceSlotsDetails } from '../hooks/backendai'; import { useCurrentKeyPairResourcePolicyLazyLoadQuery } from '../hooks/hooksUsingRelay'; import { useCurrentProjectValue, @@ -107,6 +107,10 @@ const ResourceAllocationFormItems: React.FC< currentImage: currentImage, }); + const [resourceSlotsDetails] = useResourceSlotsDetails( + currentResourceGroup || undefined, + ); + const acceleratorSlots = _.omitBy(resourceSlots, (value, key) => { if (['cpu', 'mem', 'shmem'].includes(key)) return true; @@ -480,7 +484,9 @@ const ResourceAllocationFormItems: React.FC< , @@ -517,7 +523,9 @@ const ResourceAllocationFormItems: React.FC< > = { [key in string]: V; }; -const ResourceNumber: React.FC = ({ +const ResourceNumber: React.FC = ({ type, value: amount, extra, opts, hideTooltip = false, }) => { - const { t } = useTranslation(); const { token } = theme.useToken(); - const units: ResourceTypeInfo = { - cpu: t('session.core'), - mem: 'GiB', - ...ACCELERATOR_UNIT_MAP, - }; + const currentGroup = useCurrentResourceGroupValue(); + const [resourceSlotsDetails] = useResourceSlotsDetails( + currentGroup || undefined, + ); return ( - {resourceTypes.includes(type) ? ( + {resourceSlotsDetails?.[type] ? ( ) : ( type )} - {units[type] === 'GiB' + {resourceSlotsDetails?.[type].number_format.binary ? Number(iSizeToSize(amount, 'g', 3, true)?.numberFixed).toString() - : units[type] === 'FGPU' + : (resourceSlotsDetails?.[type].number_format.round_length || 0) > 0 ? parseFloat(amount).toFixed(2) : amount} - {units[type]} + + {resourceSlotsDetails?.[type].display_unit || ''} + {type === 'mem' && opts?.shmem && opts?.shmem > 0 ? ( = ({ }; interface AccTypeIconProps extends Omit, 'src'> { - type: ResourceTypeKey; + type: string; showIcon?: boolean; showUnit?: boolean; showTooltip?: boolean; diff --git a/react/src/hooks/backendai.tsx b/react/src/hooks/backendai.tsx index 7413d75546..594c418509 100644 --- a/react/src/hooks/backendai.tsx +++ b/react/src/hooks/backendai.tsx @@ -58,7 +58,7 @@ type ResourceSlotDetail = { /** * Custom hook to fetch resource slot details by resource group name. - * @param resourceGroupName - The name of the resource group. if not provided, it will fetch resource/device_metadata.json + * @param resourceGroupName - The name of the resource group. if not provided, it will use resource/device_metadata.json * @returns An array containing the resource slots and a refresh function. */ export const useResourceSlotsDetails = (resourceGroupName?: string) => { @@ -85,19 +85,18 @@ export const useResourceSlotsDetails = (resourceGroupName?: string) => { }); } }, - staleTime: 0, + staleTime: 3000, }); + // TODO: improve waterfall loading const { data: deviceMetadata } = useTanQuery<{ [key: string]: ResourceSlotDetail; }>({ queryKey: ['backendai-metadata-device', key], queryFn: () => { - return !resourceSlots - ? fetch('resources/device_metadata.json') - .then((response) => response.json()) - .then((result) => result?.deviceInfo) - : {}; + return fetch('resources/device_metadata.json') + .then((response) => response.json()) + .then((result) => result?.deviceInfo); }, staleTime: 1000 * 60 * 60 * 24, }); diff --git a/react/src/pages/EndpointDetailPage.tsx b/react/src/pages/EndpointDetailPage.tsx index f908d1e712..288650fcc0 100644 --- a/react/src/pages/EndpointDetailPage.tsx +++ b/react/src/pages/EndpointDetailPage.tsx @@ -5,7 +5,7 @@ import EndpointTokenGenerationModal from '../components/EndpointTokenGenerationM import Flex from '../components/Flex'; import ImageMetaIcon from '../components/ImageMetaIcon'; import InferenceSessionErrorModal from '../components/InferenceSessionErrorModal'; -import ResourceNumber, { ResourceTypeKey } from '../components/ResourceNumber'; +import ResourceNumber from '../components/ResourceNumber'; import ServiceLauncherModal from '../components/ServiceLauncherModal'; import VFolderLazyView from '../components/VFolderLazyView'; import { InferenceSessionErrorModalFragment$key } from '../components/__generated__/InferenceSessionErrorModalFragment.graphql'; @@ -314,7 +314,7 @@ const EndpointDetailPage: React.FC = () => { {_.map( JSON.parse(endpoint?.resource_slots || '{}'), - (value: string, type: ResourceTypeKey) => { + (value: string, type) => { return (