-
+
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 0b9a11cb0b18..bbb954854d89 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
@@ -1,37 +1,123 @@
-import {
- OsdsButton,
- OsdsSpinner,
- OsdsText,
- OsdsChip,
-} from '@ovhcloud/ods-components/react';
+import { OsdsButton, 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 { ODS_CHIP_SIZE, ODS_BUTTON_SIZE } from '@ovhcloud/ods-components';
import {
TilesInputComponent,
useCatalogPrice,
} from '@ovh-ux/manager-react-components';
import { useTranslation } from 'react-i18next';
-import { useState } from 'react';
-import { TAddon, TCatalog } from '@ovh-ux/manager-pci-common';
+import { useMemo, useState } from 'react';
+import { useParams } from 'react-router-dom';
import { useTranslateBytes } from '@/pages/new/hooks/useTranslateBytes';
-import { useConsumptionVolumesAddon } from '@/api/hooks/useConsumptionVolumesAddon';
import { StepState } from '@/pages/new/hooks/useStep';
-import { TLocalisation } from '@/api/hooks/useRegions';
+import { useVolumeCatalog } from '@/api/hooks/useCatalog';
+import { TVolumeAddon } from '@/api/data/catalog';
+import { TRegion } from '@/api/data/regions';
+
+const BETA_TAG = 'is_new';
+
+function VolumeTypeTile({
+ volumeType,
+ currentRegion,
+}: Readonly<{ volumeType: TVolumeAddon; currentRegion: TRegion }>) {
+ const { t } = useTranslation(['add', 'common']);
+ const { projectId } = useParams();
+ const {
+ data: { filters },
+ } = useVolumeCatalog(projectId);
+ const tBytes = useTranslateBytes();
+ const { getFormattedCatalogPrice } = useCatalogPrice(6, {
+ hideTaxLabel: true,
+ });
+
+ const pricing = volumeType.pricings[0];
+
+ const isNew = useMemo(
+ () =>
+ volumeType.tags.includes(BETA_TAG) ||
+ filters.deployment.some(
+ (deployment) =>
+ currentRegion.filters.deployment.includes(deployment.name) &&
+ deployment.tags.includes(BETA_TAG),
+ ),
+ [filters, volumeType],
+ );
+
+ return (
+
+
+
+ {volumeType.name}
+
+ {isNew && (
+
+ {t('common:pci_projects_project_storages_blocks_new')}
+
+ )}
+
+
+
+ {pricing.specs.volume.iops.guaranteed
+ ? t(
+ 'pci_projects_project_storages_blocks_add_type_addon_iops_guaranteed',
+ {
+ iops: pricing.specs.volume.iops.level,
+ separator: ', ',
+ },
+ )
+ : t(
+ 'pci_projects_project_storages_blocks_add_type_addon_iops_not_guaranteed',
+ {
+ iops:
+ pricing.specs.volume.iops.max ||
+ pricing.specs.volume.iops.level,
+ separator: ', ',
+ },
+ )}
+ {t(
+ 'pci_projects_project_storages_blocks_add_type_addon_capacity_max',
+ {
+ capacity: tBytes(
+ pricing.specs.volume.capacity.max,
+ 0,
+ false,
+ 'GB',
+ false,
+ ),
+ },
+ )}{' '}
+
+ {t('pci_projects_project_storages_blocks_add_type_addon_price', {
+ price: getFormattedCatalogPrice(volumeType.pricings[0]?.price),
+ })}
+
+
+
+ );
+}
export interface VolumeTypeStepProps {
projectId: string;
- region: TLocalisation;
+ region: TRegion;
step: StepState;
- onSubmit: (volumeType: TAddon) => void;
+ onSubmit: (volumeType: TVolumeAddon) => void;
}
export function VolumeTypeStep({
@@ -40,97 +126,32 @@ export function VolumeTypeStep({
step,
onSubmit,
}: 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, {
- hideTaxLabel: true,
- });
+ const { t } = useTranslation('stepper');
+ const { data } = useVolumeCatalog(projectId);
- const { volumeTypes, isPending } = useConsumptionVolumesAddon(
- projectId,
- region,
+ const [volumeType, setVolumeType] = useState(undefined);
+
+ const volumeTypes = useMemo(
+ () =>
+ data?.models
+ .map((m) => ({
+ ...m,
+ pricings: m.pricings.filter((p) => p.regions.includes(region.name)),
+ }))
+ .filter((m) => m.pricings.length > 0) || [],
+ [data, region],
);
const displayedTypes =
volumeType && step.isLocked ? [volumeType] : volumeTypes;
- if (isPending) {
- return ;
- }
-
return (
<>
-
+
value={volumeType}
items={displayedTypes || []}
- label={(vType: TCatalog['addons'][0]) => (
-
-
-
- {vType.blobs.technical.name}
-
- {vType.blobs.tags.includes('is_new') && (
-
- {tCommon('pci_projects_project_storages_blocks_new')}
-
- )}
-
-
-
- {vType.blobs.technical.volume.iops.guaranteed
- ? t(
- 'pci_projects_project_storages_blocks_add_type_addon_iops_guaranteed',
- {
- iops: vType.blobs.technical.volume.iops.level,
- separator: ', ',
- },
- )
- : t(
- 'pci_projects_project_storages_blocks_add_type_addon_iops_not_guaranteed',
- {
- iops:
- vType.blobs.technical.volume.iops.max ||
- vType.blobs.technical.volume.iops.level,
- separator: ', ',
- },
- )}
- {t(
- 'pci_projects_project_storages_blocks_add_type_addon_capacity_max',
- {
- capacity: tBytes(
- vType.blobs.technical.volume.capacity.max,
- 0,
- false,
- 'GB',
- false,
- ),
- },
- )}{' '}
-
- {t(
- 'pci_projects_project_storages_blocks_add_type_addon_price',
- {
- price: getFormattedCatalogPrice(vType.pricings[0]?.price),
- },
- )}
-
-
-
+ label={(vType: TVolumeAddon) => (
+
)}
onInput={setVolumeType}
/>
@@ -142,7 +163,7 @@ export function VolumeTypeStep({
onClick={() => onSubmit(volumeType)}
className="w-fit"
>
- {tStepper('common_stepper_next_button_label')}
+ {t('common_stepper_next_button_label')}
)}
diff --git a/packages/manager/apps/pci-block-storage/src/pages/new/components/website-link.ts b/packages/manager/apps/pci-block-storage/src/pages/new/components/website-link.ts
new file mode 100644
index 000000000000..144bf4a819f1
--- /dev/null
+++ b/packages/manager/apps/pci-block-storage/src/pages/new/components/website-link.ts
@@ -0,0 +1,23 @@
+export const GLOBAL_INFRASTRUCTURE_URL = {
+ ASIA: 'https://www.ovhcloud.com/asia/about-us/global-infrastructure/',
+ AU: 'https://www.ovhcloud.com/en-au/about-us/global-infrastructure/',
+ CA: 'https://www.ovhcloud.com/en-ca/about-us/global-infrastructure/',
+ GB: 'https://www.ovhcloud.com/en-gb/about-us/global-infrastructure/',
+ IE: 'https://www.ovhcloud.com/en-ie/about-us/global-infrastructure/',
+ IN: 'https://www.ovhcloud.com/en-in/about-us/global-infrastructure/',
+ SG: 'https://www.ovhcloud.com/en-sg/about-us/global-infrastructure/',
+ DE: 'https://www.ovhcloud.com/de/about-us/global-infrastructure/',
+ ES: 'https://www.ovhcloud.com/es-es/about-us/global-infrastructure/',
+ FR: 'https://www.ovhcloud.com/fr/about-us/global-infrastructure/',
+ IT: 'https://www.ovhcloud.com/it/about-us/global-infrastructure/',
+ MA: 'https://www.ovhcloud.com/fr-ma/about-us/global-infrastructure/',
+ SN: 'https://www.ovhcloud.com/fr-sn/about-us/global-infrastructure/',
+ TN: 'https://www.ovhcloud.com/fr-tn/about-us/global-infrastructure/',
+ NL: 'https://www.ovhcloud.com/nl/about-us/global-infrastructure/',
+ PL: 'https://www.ovhcloud.com/nl/about-us/global-infrastructure/',
+ PT: 'https://www.ovhcloud.com/pt/about-us/global-infrastructure/',
+ QC: 'https://www.ovhcloud.com/fr-ca/about-us/global-infrastructure/',
+ US: 'https://www.ovhcloud.com/en/about-us/global-infrastructure/',
+ WS: 'https://www.ovhcloud.com/es/about-us/global-infrastructure/',
+ DEFAULT: 'https://www.ovhcloud.com/en/about-us/global-infrastructure/',
+};
diff --git a/packages/manager/apps/pci-block-storage/src/pages/new/form.type.ts b/packages/manager/apps/pci-block-storage/src/pages/new/form.type.ts
index 2752ed1ee007..048413a06067 100644
--- a/packages/manager/apps/pci-block-storage/src/pages/new/form.type.ts
+++ b/packages/manager/apps/pci-block-storage/src/pages/new/form.type.ts
@@ -1,9 +1,10 @@
-import { TAddon } from '@ovh-ux/manager-pci-common';
-import { TLocalisation } from '@/api/hooks/useRegions';
+import { TVolumeAddon, TVolumePricing } from '@/api/data/catalog';
+import { TRegion } from '@/api/data/regions';
export type TFormState = {
- region: TLocalisation;
- volumeType: TAddon;
+ region: TRegion;
+ volumeType: TVolumeAddon;
+ pricing: TVolumePricing;
volumeName: string;
volumeCapacity: number;
availabilityZone: string;
diff --git a/packages/manager/apps/pci-block-storage/src/pages/new/hooks/useVolumeStepper.ts b/packages/manager/apps/pci-block-storage/src/pages/new/hooks/useVolumeStepper.ts
index 05c3b89f698a..d12dac7d4741 100644
--- a/packages/manager/apps/pci-block-storage/src/pages/new/hooks/useVolumeStepper.ts
+++ b/packages/manager/apps/pci-block-storage/src/pages/new/hooks/useVolumeStepper.ts
@@ -1,18 +1,12 @@
-import { useEffect, useMemo, useState } from 'react';
-import { TAddon, useProjectRegions } from '@ovh-ux/manager-pci-common';
+import { useEffect, useState } from 'react';
import { Step, useStep } from '@/pages/new/hooks/useStep';
import { TFormState } from '@/pages/new/form.type';
-import { TLocalisation } from '@/api/hooks/useRegions';
-import {
- isProductWithAvailabilityZone,
- isRegionWith3AZ,
-} from '@/api/data/availableVolumes';
+import { TVolumeAddon } from '@/api/data/catalog';
+import { useHas3AZRegion } from '@/api/hooks/useHas3AZRegion';
+import { isRegionWith3AZ, TRegion } from '@/api/data/regions';
export function useVolumeStepper(projectId: string) {
- const { data } = useProjectRegions(projectId);
- const is3AZAvailable = useMemo(() => !!data && data.some(isRegionWith3AZ), [
- data,
- ]);
+ const { has3AZ } = useHas3AZRegion(projectId);
const [form, setForm] = useState