From d2171684e860b6a51857652e003df2b02e71bf99 Mon Sep 17 00:00:00 2001 From: Simon Chaumet Date: Thu, 31 Oct 2024 18:00:25 +0100 Subject: [PATCH] feat(pci-block-storage): add exten beta (#13489) Extend volume capacity to 12To Add banner for beta extension Implement dependent regions on block tiles ref: TAPC-1609, TAPC-2071, TAPC-2072, TAPC-1139, TAPC-1505, TAPC-2063, TAPC-1711, TAPC-1716, TAPC-1728, TAPC-1938 Signed-off-by: Simon Chaumet Co-authored-by: Yann Lojewski Co-authored-by: CDS Translator Agent --- .../translations/common/Messages_de_DE.json | 3 +- .../translations/common/Messages_en_GB.json | 3 +- .../translations/common/Messages_es_ES.json | 3 +- .../translations/common/Messages_fr_CA.json | 4 +- .../translations/common/Messages_fr_FR.json | 4 +- .../translations/common/Messages_it_IT.json | 3 +- .../translations/common/Messages_pl_PL.json | 3 +- .../translations/common/Messages_pt_PT.json | 3 +- .../exten-banner-beta/Messages_de_DE.json | 3 + .../exten-banner-beta/Messages_en_GB.json | 3 + .../exten-banner-beta/Messages_es_ES.json | 3 + .../exten-banner-beta/Messages_fr_CA.json | 3 + .../exten-banner-beta/Messages_fr_FR.json | 3 + .../exten-banner-beta/Messages_it_IT.json | 3 + .../exten-banner-beta/Messages_pl_PL.json | 3 + .../exten-banner-beta/Messages_pt_PT.json | 3 + .../pci-block-storage/src/api/data/quota.ts | 39 +++++++++++- .../src/api/hooks/useQuota.ts | 6 +- .../exten-banner-beta/ExtenBannerBeta.tsx | 62 +++++++++++++++++++ .../apps/pci-block-storage/src/constants.ts | 1 - .../src/pages/edit/Edit.page.spec.tsx | 5 +- .../src/pages/edit/Edit.page.tsx | 31 +++++----- .../src/pages/new/New.page.tsx | 5 ++ .../new/components/CapacityStep.component.tsx | 24 ++++--- .../pages/new/components/PriceEstimate.tsx | 20 +++--- .../components/VolumeTypeStep.component.tsx | 20 +++++- .../KubeRegionSelector.component.tsx | 7 +-- .../src/api/data/availability.ts | 13 ++-- .../src/api/hook/useAvailability.ts | 23 +++---- 29 files changed, 232 insertions(+), 74 deletions(-) create mode 100644 packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_de_DE.json create mode 100644 packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_en_GB.json create mode 100644 packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_es_ES.json create mode 100644 packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_fr_CA.json create mode 100644 packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_fr_FR.json create mode 100644 packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_it_IT.json create mode 100644 packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_pl_PL.json create mode 100644 packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_pt_PT.json create mode 100644 packages/manager/apps/pci-block-storage/src/components/exten-banner-beta/ExtenBannerBeta.tsx diff --git a/packages/manager/apps/pci-block-storage/public/translations/common/Messages_de_DE.json b/packages/manager/apps/pci-block-storage/public/translations/common/Messages_de_DE.json index 5f07570cc57b..e264c034e35a 100644 --- a/packages/manager/apps/pci-block-storage/public/translations/common/Messages_de_DE.json +++ b/packages/manager/apps/pci-block-storage/public/translations/common/Messages_de_DE.json @@ -17,5 +17,6 @@ "pci_projects_project_storages_blocks_instance_attach_label": "Mit Instanz verbinden", "pci_projects_project_storages_blocks_create_backup_label": "Backup erstellen", "pci_projects_project_storages_blocks_delete_label": "Löschen", - "pci_projects_project_storages_blocks_add_label": "Volume erstellen" + "pci_projects_project_storages_blocks_add_label": "Volume erstellen", + "pci_projects_project_storages_blocks_new": "Beta" } diff --git a/packages/manager/apps/pci-block-storage/public/translations/common/Messages_en_GB.json b/packages/manager/apps/pci-block-storage/public/translations/common/Messages_en_GB.json index e10516a227bc..625409878633 100644 --- a/packages/manager/apps/pci-block-storage/public/translations/common/Messages_en_GB.json +++ b/packages/manager/apps/pci-block-storage/public/translations/common/Messages_en_GB.json @@ -17,5 +17,6 @@ "pci_projects_project_storages_blocks_instance_attach_label": "Attach to instance", "pci_projects_project_storages_blocks_create_backup_label": "Create a backup ", "pci_projects_project_storages_blocks_delete_label": "Delete", - "pci_projects_project_storages_blocks_add_label": "Create a volume " + "pci_projects_project_storages_blocks_add_label": "Create a volume ", + "pci_projects_project_storages_blocks_new": "Beta" } diff --git a/packages/manager/apps/pci-block-storage/public/translations/common/Messages_es_ES.json b/packages/manager/apps/pci-block-storage/public/translations/common/Messages_es_ES.json index 27ea12d969e4..740f259aa655 100644 --- a/packages/manager/apps/pci-block-storage/public/translations/common/Messages_es_ES.json +++ b/packages/manager/apps/pci-block-storage/public/translations/common/Messages_es_ES.json @@ -17,5 +17,6 @@ "pci_projects_project_storages_blocks_instance_attach_label": "Asociar a la instancia", "pci_projects_project_storages_blocks_create_backup_label": "Crear una copia de seguridad", "pci_projects_project_storages_blocks_delete_label": "Eliminar", - "pci_projects_project_storages_blocks_add_label": "Crear un volumen" + "pci_projects_project_storages_blocks_add_label": "Crear un volumen", + "pci_projects_project_storages_blocks_new": "Beta" } diff --git a/packages/manager/apps/pci-block-storage/public/translations/common/Messages_fr_CA.json b/packages/manager/apps/pci-block-storage/public/translations/common/Messages_fr_CA.json index 2f0ed9fa6c80..bd4accaa88c1 100644 --- a/packages/manager/apps/pci-block-storage/public/translations/common/Messages_fr_CA.json +++ b/packages/manager/apps/pci-block-storage/public/translations/common/Messages_fr_CA.json @@ -18,5 +18,7 @@ "pci_projects_project_storages_blocks_instance_attach_label": "Attacher à l'instance", "pci_projects_project_storages_blocks_create_backup_label": "Créer une sauvegarde", "pci_projects_project_storages_blocks_delete_label": "Supprimer", - "pci_projects_project_storages_blocks_add_label": "Créer un volume" + "pci_projects_project_storages_blocks_add_label": "Créer un volume", + + "pci_projects_project_storages_blocks_new": "Beta" } diff --git a/packages/manager/apps/pci-block-storage/public/translations/common/Messages_fr_FR.json b/packages/manager/apps/pci-block-storage/public/translations/common/Messages_fr_FR.json index 2f0ed9fa6c80..bd4accaa88c1 100644 --- a/packages/manager/apps/pci-block-storage/public/translations/common/Messages_fr_FR.json +++ b/packages/manager/apps/pci-block-storage/public/translations/common/Messages_fr_FR.json @@ -18,5 +18,7 @@ "pci_projects_project_storages_blocks_instance_attach_label": "Attacher à l'instance", "pci_projects_project_storages_blocks_create_backup_label": "Créer une sauvegarde", "pci_projects_project_storages_blocks_delete_label": "Supprimer", - "pci_projects_project_storages_blocks_add_label": "Créer un volume" + "pci_projects_project_storages_blocks_add_label": "Créer un volume", + + "pci_projects_project_storages_blocks_new": "Beta" } diff --git a/packages/manager/apps/pci-block-storage/public/translations/common/Messages_it_IT.json b/packages/manager/apps/pci-block-storage/public/translations/common/Messages_it_IT.json index c702fa8f94e2..50f2025ea09f 100644 --- a/packages/manager/apps/pci-block-storage/public/translations/common/Messages_it_IT.json +++ b/packages/manager/apps/pci-block-storage/public/translations/common/Messages_it_IT.json @@ -17,5 +17,6 @@ "pci_projects_project_storages_blocks_instance_attach_label": "Associa all’istanza", "pci_projects_project_storages_blocks_create_backup_label": "Crea un backup", "pci_projects_project_storages_blocks_delete_label": "Eliminare", - "pci_projects_project_storages_blocks_add_label": "Crea un volume" + "pci_projects_project_storages_blocks_add_label": "Crea un volume", + "pci_projects_project_storages_blocks_new": "Beta" } diff --git a/packages/manager/apps/pci-block-storage/public/translations/common/Messages_pl_PL.json b/packages/manager/apps/pci-block-storage/public/translations/common/Messages_pl_PL.json index c02cf76d2170..7dcdf9f17419 100644 --- a/packages/manager/apps/pci-block-storage/public/translations/common/Messages_pl_PL.json +++ b/packages/manager/apps/pci-block-storage/public/translations/common/Messages_pl_PL.json @@ -17,5 +17,6 @@ "pci_projects_project_storages_blocks_instance_attach_label": "Podłącz do instancji", "pci_projects_project_storages_blocks_create_backup_label": "Utwórz kopię zapasową", "pci_projects_project_storages_blocks_delete_label": "Usuń", - "pci_projects_project_storages_blocks_add_label": "Utwórz wolumen" + "pci_projects_project_storages_blocks_add_label": "Utwórz wolumen", + "pci_projects_project_storages_blocks_new": "Beta" } diff --git a/packages/manager/apps/pci-block-storage/public/translations/common/Messages_pt_PT.json b/packages/manager/apps/pci-block-storage/public/translations/common/Messages_pt_PT.json index 8fafc43406c3..ad67692c1771 100644 --- a/packages/manager/apps/pci-block-storage/public/translations/common/Messages_pt_PT.json +++ b/packages/manager/apps/pci-block-storage/public/translations/common/Messages_pt_PT.json @@ -17,5 +17,6 @@ "pci_projects_project_storages_blocks_instance_attach_label": "Associar a instância", "pci_projects_project_storages_blocks_create_backup_label": "Criar uma cópia de segurança", "pci_projects_project_storages_blocks_delete_label": "Eliminar", - "pci_projects_project_storages_blocks_add_label": "Criar um volume" + "pci_projects_project_storages_blocks_add_label": "Criar um volume", + "pci_projects_project_storages_blocks_new": "Beta" } diff --git a/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_de_DE.json b/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_de_DE.json new file mode 100644 index 000000000000..5a749e3e4e37 --- /dev/null +++ b/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_de_DE.json @@ -0,0 +1,3 @@ +{ + "exten_banner_description": "Optimieren Sie Ihre Performance mit Block Storage NVMe over Fabric!\nErhältlich in der Betaphase in den Regionen {{regions}}, verdoppeln Sie die Performance Ihrer Classic Volumes und steigern Sie die Effizienz Ihrer rechenintensiven Aufgaben." +} diff --git a/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_en_GB.json b/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_en_GB.json new file mode 100644 index 000000000000..3574b0d37949 --- /dev/null +++ b/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_en_GB.json @@ -0,0 +1,3 @@ +{ + "exten_banner_description": "Optimize your performance with Block Storage NVMe over Fabric!\nAvailable in the beta phase in the {{regions}} regions, double the performance of your Classic volumes and improve the efficiency of your intensive workloads." +} diff --git a/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_es_ES.json b/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_es_ES.json new file mode 100644 index 000000000000..83b6e1e1b782 --- /dev/null +++ b/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_es_ES.json @@ -0,0 +1,3 @@ +{ + "exten_banner_description": "¡Optimice su rendimiento con Block Storage NVMe over Fabric!\nDisponible en fase beta en las regiones {{regions}}, duplique el rendimiento de sus volúmenes Classic y mejore la eficiencia de sus cargas de trabajo intensivas." +} diff --git a/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_fr_CA.json b/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_fr_CA.json new file mode 100644 index 000000000000..95d56a4ccb4b --- /dev/null +++ b/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_fr_CA.json @@ -0,0 +1,3 @@ +{ + "exten_banner_description": "Optimisez vos performances avec Block Storage NVMe over Fabric !\nDisponible en phase bêta dans les régions {{regions}}, doublez les performances de vos volumes Classic et améliorez l'efficacité de vos charges de travail intensives." +} diff --git a/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_fr_FR.json b/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_fr_FR.json new file mode 100644 index 000000000000..95d56a4ccb4b --- /dev/null +++ b/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_fr_FR.json @@ -0,0 +1,3 @@ +{ + "exten_banner_description": "Optimisez vos performances avec Block Storage NVMe over Fabric !\nDisponible en phase bêta dans les régions {{regions}}, doublez les performances de vos volumes Classic et améliorez l'efficacité de vos charges de travail intensives." +} diff --git a/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_it_IT.json b/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_it_IT.json new file mode 100644 index 000000000000..0a85b86848b8 --- /dev/null +++ b/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_it_IT.json @@ -0,0 +1,3 @@ +{ + "exten_banner_description": "Ottimizza le performance con Block Storage NVMe over Fabric!\nDisponibile in fase beta nelle Region {{regions}}, raddoppia le performance dei volumi Classic e migliora l'efficacia dei carichi di lavoro intensivi." +} diff --git a/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_pl_PL.json b/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_pl_PL.json new file mode 100644 index 000000000000..37d2436dea97 --- /dev/null +++ b/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_pl_PL.json @@ -0,0 +1,3 @@ +{ + "exten_banner_description": "Zoptymalizuj swoją wydajność korzystając z Block Storage NVMe over Fabric!\nZwiększ wydajność wolumenów Classic i zwiększ wydajność w przypadku intensywnych obciążeń, dzięki czemu Twoje rozwiązania będą dostępne w fazie beta w regionach {{regions}}." +} diff --git a/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_pt_PT.json b/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_pt_PT.json new file mode 100644 index 000000000000..e62224ecb664 --- /dev/null +++ b/packages/manager/apps/pci-block-storage/public/translations/exten-banner-beta/Messages_pt_PT.json @@ -0,0 +1,3 @@ +{ + "exten_banner_description": "Otimize as suas performances com o Block Storage NVMe over Fabric!\nDisponível na fase beta nas regiões {{regions}}, duplique os desempenhos dos seus volumes Classic e melhore a eficácia das suas cargas de trabalho intensivas." +} diff --git a/packages/manager/apps/pci-block-storage/src/api/data/quota.ts b/packages/manager/apps/pci-block-storage/src/api/data/quota.ts index baae96f89eb9..2a2e16f1ae1a 100644 --- a/packages/manager/apps/pci-block-storage/src/api/data/quota.ts +++ b/packages/manager/apps/pci-block-storage/src/api/data/quota.ts @@ -1,4 +1,6 @@ import { v6 } from '@ovh-ux/manager-core-api'; +import { useFeatureAvailability } from '@ovh-ux/manager-react-components'; +import { useMemo } from 'react'; export interface RegionQuota { region: string; @@ -12,9 +14,40 @@ export interface RegionQuota { export const getRegionsQuota = async ( projectId: string, -): Promise => { - const { data } = await v6.get( - `/cloud/project/${projectId}/quota`, + region?: string, +): Promise => { + const { data } = await v6.get( + `/cloud/project/${projectId}/region/${region}/quota`, ); return data; }; + +function isLocalZone(region: string) { + return region.split('-')[2] === 'LZ'; +} + +function getVolumeMaxSize(region: string) { + return isLocalZone(region) ? 4 * 1000 : 12 * 1000; +} + +export const FA_VOLUME_EXTEND_12TO = 'pci-block-storage:volume-extend-12To'; +export const FA_EXTEN_BANNER = 'pci-block-storage:exten-banner'; + +export function useVolumeMaxSize(region: string | undefined) { + const { data, ...restApi } = useFeatureAvailability([ + FA_VOLUME_EXTEND_12TO, + FA_EXTEN_BANNER, + ]); + + const volumeMaxSize = useMemo(() => { + if (region && data?.[FA_VOLUME_EXTEND_12TO]) { + return getVolumeMaxSize(region); + } + return 4 * 1000; + }, [data, region]); + + return { + ...restApi, + volumeMaxSize, + }; +} diff --git a/packages/manager/apps/pci-block-storage/src/api/hooks/useQuota.ts b/packages/manager/apps/pci-block-storage/src/api/hooks/useQuota.ts index d34244bcfe16..27e57480750a 100644 --- a/packages/manager/apps/pci-block-storage/src/api/hooks/useQuota.ts +++ b/packages/manager/apps/pci-block-storage/src/api/hooks/useQuota.ts @@ -1,8 +1,8 @@ import { useQuery } from '@tanstack/react-query'; import { getRegionsQuota } from '@/api/data/quota'; -export const useRegionsQuota = (projectId: string) => +export const useRegionsQuota = (projectId: string, region: string) => useQuery({ - queryKey: ['project', projectId, 'quota'], - queryFn: () => getRegionsQuota(projectId), + queryKey: ['project', projectId, 'region', region, 'quota'], + queryFn: () => getRegionsQuota(projectId, region), }); diff --git a/packages/manager/apps/pci-block-storage/src/components/exten-banner-beta/ExtenBannerBeta.tsx b/packages/manager/apps/pci-block-storage/src/components/exten-banner-beta/ExtenBannerBeta.tsx new file mode 100644 index 000000000000..8f18e6f7672c --- /dev/null +++ b/packages/manager/apps/pci-block-storage/src/components/exten-banner-beta/ExtenBannerBeta.tsx @@ -0,0 +1,62 @@ +import { useFeatureAvailability } from '@ovh-ux/manager-react-components'; +import { OsdsMessage, OsdsText } from '@ovhcloud/ods-components/react'; +import { + ODS_MESSAGE_TYPE, + ODS_TEXT_COLOR_HUE, + ODS_TEXT_COLOR_INTENT, +} from '@ovhcloud/ods-components'; +import { useTranslation } from 'react-i18next'; +import { useParams } from 'react-router-dom'; +import { useMemo } from 'react'; +import { FA_EXTEN_BANNER } from '@/api/data/quota'; +import { useProjectsAvailableVolumes } from '@/api/hooks/useProjectsAvailableVolumes'; + +const extenProducts = [ + 'volume.high-speed-BETA.consumption', + 'volume.classic-BETA.consumption', +]; + +function Banner() { + const { t } = useTranslation('exten-banner-beta'); + const { projectId } = useParams(); + const { data: availableVolumes } = useProjectsAvailableVolumes(projectId); + + const regionsString = useMemo( + () => + availableVolumes + ? [ + ...new Set( + availableVolumes.plans + .filter((p) => extenProducts.includes(p.code)) + .flatMap((p) => p.regions) + .map((r) => r.name), + ), + ].join(', ') + : '', + [availableVolumes], + ); + + if (!availableVolumes) return null; + + return ( + + + {t('exten_banner_description', { + regions: regionsString, + })} + + + ); +} + +export function ExtenBannerBeta() { + const { data } = useFeatureAvailability([FA_EXTEN_BANNER]); + + if (!data?.[FA_EXTEN_BANNER]) return null; + + return ; +} diff --git a/packages/manager/apps/pci-block-storage/src/constants.ts b/packages/manager/apps/pci-block-storage/src/constants.ts index 686d0dedbaef..c34b8e6b66ef 100644 --- a/packages/manager/apps/pci-block-storage/src/constants.ts +++ b/packages/manager/apps/pci-block-storage/src/constants.ts @@ -51,7 +51,6 @@ export const URL_INFO = { LOCAL_ZONE: LOCAL_ZONE_INFO_URL, }; -export const VOLUME_MAX_SIZE = 4 * 1000; // Should be 10 * 1024 (but API is wrong; export const VOLUME_MIN_SIZE = 10; // 10 Gio export const VOLUME_UNLIMITED_QUOTA = -1; // Should be 10 * 1024 (but API is wrong) export const ALPHA_CHARACTERS_REGEX = /^[a-zA-Z-]+$/; diff --git a/packages/manager/apps/pci-block-storage/src/pages/edit/Edit.page.spec.tsx b/packages/manager/apps/pci-block-storage/src/pages/edit/Edit.page.spec.tsx index 0504c4016484..a194a547576e 100644 --- a/packages/manager/apps/pci-block-storage/src/pages/edit/Edit.page.spec.tsx +++ b/packages/manager/apps/pci-block-storage/src/pages/edit/Edit.page.spec.tsx @@ -23,6 +23,10 @@ vi.mock('@/core/HidePreloader', () => ({ default: () =>
HidePeloader
, })); +vi.mock('@/api/hooks/useQuota', () => ({ + useRegionsQuota: vi.fn().mockReturnValue({ data: [] }), +})); + vi.mock('@ovh-ux/manager-react-components', async (importOriginal) => { const mod = await importOriginal< typeof import('@ovh-ux/manager-react-components') @@ -38,7 +42,6 @@ vi.mock('@ovh-ux/manager-react-components', async (importOriginal) => { addSuccess: vi.fn(), }), useProjectLocalRegions: vi.fn().mockReturnValue({ data: [] }), - useProjectQuota: vi.fn().mockReturnValue({ data: [] }), useProjectUrl: vi.fn().mockReturnValue('/project-url'), useTranslatedMicroRegions: vi .fn() diff --git a/packages/manager/apps/pci-block-storage/src/pages/edit/Edit.page.tsx b/packages/manager/apps/pci-block-storage/src/pages/edit/Edit.page.tsx index cb3d8c728669..5cc5731cdce6 100644 --- a/packages/manager/apps/pci-block-storage/src/pages/edit/Edit.page.tsx +++ b/packages/manager/apps/pci-block-storage/src/pages/edit/Edit.page.tsx @@ -5,7 +5,6 @@ import { useCatalogPrice, useNotifications, useProjectLocalRegions, - useProjectQuota, useProjectUrl, useTranslatedMicroRegions, } from '@ovh-ux/manager-react-components'; @@ -38,11 +37,7 @@ import { OsdsText, } from '@ovhcloud/ods-components/react'; import { useProject } from '@ovh-ux/manager-pci-common'; -import { - VOLUME_MAX_SIZE, - VOLUME_MIN_SIZE, - VOLUME_UNLIMITED_QUOTA, -} from '@/constants'; +import { VOLUME_MIN_SIZE, VOLUME_UNLIMITED_QUOTA } from '@/constants'; import ChipRegion from '@/components/edit/ChipRegion.component'; import { TVolume } from '@/api/data/volume'; import { @@ -51,6 +46,8 @@ import { useVolume, } from '@/api/hooks/useVolume'; import HidePreloader from '@/core/HidePreloader'; +import { useVolumeMaxSize } from '@/api/data/quota'; +import { useRegionsQuota } from '@/api/hooks/useQuota'; type TFormState = { name: string; @@ -95,6 +92,8 @@ export default function EditPage() { isPending: isPendingVolume, } = useVolume(projectId, volumeId); + const { volumeMaxSize } = useVolumeMaxSize(volume?.region); + const { data: localRegions, isPending: isPendingLocal, @@ -106,7 +105,7 @@ export default function EditPage() { size: { value: volume?.size || VOLUME_MIN_SIZE, min: VOLUME_MIN_SIZE, - max: VOLUME_MAX_SIZE, + max: volumeMaxSize, }, bootable: volume?.bootable || false, isInitialized: false, @@ -152,25 +151,23 @@ export default function EditPage() { }, }); - const { data: projectQuota, isPending: isPendingQuota } = useProjectQuota( + const { data: regionQuota, isPending: isPendingQuota } = useRegionsQuota( projectId, + volume?.region, ); const getMaxSize = (_volume: TVolume) => { - if (projectQuota?.length > 0) { - const regionQuota = projectQuota.find( - ({ region }) => region === _volume.region, - ); + if (regionQuota) { if ( regionQuota.volume && regionQuota.volume.maxGigabytes !== VOLUME_UNLIMITED_QUOTA ) { const availableGigabytes = regionQuota.volume.maxGigabytes - regionQuota.volume.usedGigabytes; - return Math.min(_volume.size + availableGigabytes, VOLUME_MAX_SIZE); + return Math.min(_volume.size + availableGigabytes, volumeMaxSize); } } - return VOLUME_MAX_SIZE; + return volumeMaxSize; }; const getVolumePriceEstimationFromCatalog = ( @@ -194,7 +191,7 @@ export default function EditPage() { isPendingQuota; useEffect(() => { - if (volume && projectQuota) { + if (volume && regionQuota) { setFormState({ name: volume.name, size: { @@ -206,7 +203,7 @@ export default function EditPage() { isInitialized: true, }); } - }, [volume, projectQuota]); + }, [volume, regionQuota]); useEffect(() => { const { min, max, value } = formState.size; @@ -443,7 +440,7 @@ export default function EditPage() { {!hasError && - (estimatedPrice?.monthly ? ( + (estimatedPrice?.monthly !== undefined ? ( +
+ +
+
(VOLUME_MIN_SIZE); const [maxSize, setMaxSize] = useState(0); - const { data: regionQuotas, isLoading } = useRegionsQuota(projectId); + const { + data: regionQuotas, + isLoading: isRegionQuotaLoading, + } = useRegionsQuota(projectId, region.name); const isCapacityValid = volumeCapacity >= VOLUME_MIN_SIZE && volumeCapacity <= maxSize; + const { volumeMaxSize, isLoading: isVolumeMaxSizeLoading } = useVolumeMaxSize( + region.name, + ); + + const isLoading = isRegionQuotaLoading && isVolumeMaxSizeLoading; + useEffect(() => { if (!isLoading) { - const quota = regionQuotas?.find(({ region: r }) => r === region?.name); - let availableGigabytes = VOLUME_MAX_SIZE; + let availableGigabytes = volumeMaxSize; if ( - quota?.volume && - quota.volume.maxGigabytes !== VOLUME_UNLIMITED_QUOTA + regionQuotas?.volume && + regionQuotas.volume.maxGigabytes !== VOLUME_UNLIMITED_QUOTA ) { availableGigabytes = Math.min( - VOLUME_MAX_SIZE, - quota.volume.maxGigabytes - quota.volume.usedGigabytes, + volumeMaxSize, + regionQuotas.volume.maxGigabytes - regionQuotas.volume.usedGigabytes, ); } setMaxSize(availableGigabytes); diff --git a/packages/manager/apps/pci-block-storage/src/pages/new/components/PriceEstimate.tsx b/packages/manager/apps/pci-block-storage/src/pages/new/components/PriceEstimate.tsx index 2e2dabb66a0a..34efc4a64694 100644 --- a/packages/manager/apps/pci-block-storage/src/pages/new/components/PriceEstimate.tsx +++ b/packages/manager/apps/pci-block-storage/src/pages/new/components/PriceEstimate.tsx @@ -28,16 +28,14 @@ export function PriceEstimate({ const priceEstimate = price * volumeCapacity * ESTIMATE_MONTHLY_HOURS; return ( - !!priceEstimate && ( - - {t('pci_projects_project_storages_blocks_add_submit_price_text', { - price: getFormattedCatalogPrice(priceEstimate), - })} - - ) + + {t('pci_projects_project_storages_blocks_add_submit_price_text', { + price: getFormattedCatalogPrice(priceEstimate), + })} + ); } diff --git a/packages/manager/apps/pci-block-storage/src/pages/new/components/VolumeTypeStep.component.tsx b/packages/manager/apps/pci-block-storage/src/pages/new/components/VolumeTypeStep.component.tsx index b1d5d719039c..8572d0e9b8ed 100644 --- a/packages/manager/apps/pci-block-storage/src/pages/new/components/VolumeTypeStep.component.tsx +++ b/packages/manager/apps/pci-block-storage/src/pages/new/components/VolumeTypeStep.component.tsx @@ -2,18 +2,23 @@ import { OsdsButton, OsdsSpinner, OsdsText, + OsdsChip, } from '@ovhcloud/ods-components/react'; import { ODS_THEME_COLOR_INTENT, ODS_THEME_TYPOGRAPHY_LEVEL, ODS_THEME_TYPOGRAPHY_SIZE, } from '@ovhcloud/ods-common-theming'; +import { + ODS_CHIP_SIZE, + ODS_BUTTON_SIZE, + ODS_SPINNER_SIZE, +} from '@ovhcloud/ods-components'; import { TilesInputComponent, useCatalogPrice, } from '@ovh-ux/manager-react-components'; -import { ODS_BUTTON_SIZE, ODS_SPINNER_SIZE } from '@ovhcloud/ods-components'; import { useTranslation } from 'react-i18next'; import { useState } from 'react'; import { TAddon, TCatalog } from '@ovh-ux/manager-pci-common'; @@ -37,6 +42,7 @@ export function VolumeTypeStep({ }: Readonly) { const { t } = useTranslation('add'); const { t: tStepper } = useTranslation('stepper'); + const { t: tCommon } = useTranslation('common'); const [volumeType, setVolumeType] = useState(undefined); const tBytes = useTranslateBytes(); const { getFormattedCatalogPrice } = useCatalogPrice(6, { @@ -62,7 +68,7 @@ export function VolumeTypeStep({ items={displayedTypes || []} label={(vType: TCatalog['addons'][0]) => (
-
+
{vType.blobs.technical.name} + {vType.blobs.tags.includes('is_new') && ( + + {tCommon('pci_projects_project_storages_blocks_new')} + + )}
) { - const { data: availability, isPending } = useProductAvailability( - projectId, - 'kubernetes', - ); + const { data: availability, isPending } = useProductAvailability(projectId, { + product: 'kubernetes', + }); if (isPending) { return ; } diff --git a/packages/manager/modules/manager-pci-common/src/api/data/availability.ts b/packages/manager/modules/manager-pci-common/src/api/data/availability.ts index 9a5e568df960..8f4abf8bd7c6 100644 --- a/packages/manager/modules/manager-pci-common/src/api/data/availability.ts +++ b/packages/manager/modules/manager-pci-common/src/api/data/availability.ts @@ -19,15 +19,18 @@ export type TProductAvailability = { }[]; }; +export type ProductAvailabilityFilter = { + addonFamily?: string; + planCode?: string; + planFamily?: string; + product?: string; +}; + export const getProductAvailability = async ( projectId: string, params: { - addonFamily?: string; ovhSubsidiary: string; - planCode?: string; - planFamily?: string; - product?: string; - }, + } & ProductAvailabilityFilter, ): Promise => { const { data } = await v6.get( `/cloud/project/${projectId}/capabilities/productAvailability`, diff --git a/packages/manager/modules/manager-pci-common/src/api/hook/useAvailability.ts b/packages/manager/modules/manager-pci-common/src/api/hook/useAvailability.ts index c03b41751fec..57ac5c298d61 100644 --- a/packages/manager/modules/manager-pci-common/src/api/hook/useAvailability.ts +++ b/packages/manager/modules/manager-pci-common/src/api/hook/useAvailability.ts @@ -1,29 +1,30 @@ import { useQuery } from '@tanstack/react-query'; import { useMe } from '@ovh-ux/manager-react-components'; -import { getProductAvailability } from '../data/availability'; +import { + getProductAvailability, + ProductAvailabilityFilter, +} from '../data/availability'; export const getProductAvailabilityQuery = ( projectId: string, ovhSubsidiary: string, - product?: string, + filter?: ProductAvailabilityFilter, ) => ({ - queryKey: [ - 'product-availability', - projectId, - ovhSubsidiary, - product || 'all', - ], + queryKey: ['product-availability', projectId, ovhSubsidiary, filter], queryFn: () => getProductAvailability(projectId, { ovhSubsidiary, - product, + ...filter, }), }); -export const useProductAvailability = (projectId: string, product?: string) => { +export const useProductAvailability = ( + projectId: string, + filter?: ProductAvailabilityFilter, +) => { const { me } = useMe(); return useQuery({ - ...getProductAvailabilityQuery(projectId, me?.ovhSubsidiary, product), + ...getProductAvailabilityQuery(projectId, me?.ovhSubsidiary, filter), enabled: !!me, }); };