From 63c5ba4a512d15fd06d2675d6d2bb5d14357463b Mon Sep 17 00:00:00 2001 From: Tsiorifamonjena Date: Thu, 10 Oct 2024 16:26:38 +0200 Subject: [PATCH 01/11] feat(pci.private-network): enable the edition of the CIDR (#13289) ref: TAPC-1791 Signed-off-by: tsiorifamonjena Co-Authored-by: CDS Translator Agent --- .../translations/new/Messages_de_DE.json | 3 +- .../translations/new/Messages_en_GB.json | 3 +- .../translations/new/Messages_es_ES.json | 3 +- .../translations/new/Messages_fr_CA.json | 3 +- .../translations/new/Messages_fr_FR.json | 3 +- .../translations/new/Messages_it_IT.json | 3 +- .../translations/new/Messages_pl_PL.json | 3 +- .../translations/new/Messages_pt_PT.json | 3 +- .../src/api/utils/utils.spec.ts | 32 +++++ .../src/api/utils/utils.ts | 9 ++ .../src/pages/new/steps/ConfigurationStep.tsx | 117 ++++++++++++------ 11 files changed, 135 insertions(+), 47 deletions(-) diff --git a/packages/manager/apps/pci-private-network/public/translations/new/Messages_de_DE.json b/packages/manager/apps/pci-private-network/public/translations/new/Messages_de_DE.json index 74a20877b8c6..5bf68dcd196a 100644 --- a/packages/manager/apps/pci-private-network/public/translations/new/Messages_de_DE.json +++ b/packages/manager/apps/pci-private-network/public/translations/new/Messages_de_DE.json @@ -36,5 +36,6 @@ "pci_projects_project_network_private_create_loading": "Das private Netzwerk wird erstellt. Dies kann einige Minuten dauern", "pci_projects_project_network_private_create_success": "Das private Netzwerk wurde erstellt", "pci_projects_project_network_private_create_error": "Bei der Erstellung des privaten Netzwerks ist ein Fehler aufgetreten: {{ message }}", - "pci_projects_project_network_private_create_vlan_id_warning": "Die VLAN-ID 0 wird standardmäßig für andere Produkte verwendet, auch außerhalb des Public-Cloud-Universums. Private IPs müssen mit Bedacht verwaltet werden." + "pci_projects_project_network_private_create_vlan_id_warning": "Die VLAN-ID 0 wird standardmäßig für andere Produkte verwendet, auch außerhalb des Public-Cloud-Universums. Private IPs müssen mit Bedacht verwaltet werden.", + "pci_projects_network_cidr": "Gültige IP-Adresse angeben" } diff --git a/packages/manager/apps/pci-private-network/public/translations/new/Messages_en_GB.json b/packages/manager/apps/pci-private-network/public/translations/new/Messages_en_GB.json index 11522d6d697f..935d7b02da3d 100644 --- a/packages/manager/apps/pci-private-network/public/translations/new/Messages_en_GB.json +++ b/packages/manager/apps/pci-private-network/public/translations/new/Messages_en_GB.json @@ -36,5 +36,6 @@ "pci_projects_project_network_private_create_loading": "Your private network is being created. This may take a few minutes.", "pci_projects_project_network_private_create_success": "Private network created.", "pci_projects_project_network_private_create_error": "An error has occurred modifying the private network: {{ message }}", - "pci_projects_project_network_private_create_vlan_id_warning": "VLAN id 0 is used by default for other products, including non-Public Cloud products and solutions. Private IPs must be carefully managed" + "pci_projects_project_network_private_create_vlan_id_warning": "VLAN id 0 is used by default for other products, including non-Public Cloud products and solutions. Private IPs must be carefully managed", + "pci_projects_network_cidr": "Please enter a valid IP address" } diff --git a/packages/manager/apps/pci-private-network/public/translations/new/Messages_es_ES.json b/packages/manager/apps/pci-private-network/public/translations/new/Messages_es_ES.json index 6a0ec85065bf..1814878f9cf0 100644 --- a/packages/manager/apps/pci-private-network/public/translations/new/Messages_es_ES.json +++ b/packages/manager/apps/pci-private-network/public/translations/new/Messages_es_ES.json @@ -36,5 +36,6 @@ "pci_projects_project_network_private_create_loading": "Creando la red privada... La operación podría tardar unos minutos.", "pci_projects_project_network_private_create_success": "Se ha creado la red privada.", "pci_projects_project_network_private_create_error": "Se ha producido un error al crear la red privada: {{ message }}.", - "pci_projects_project_network_private_create_vlan_id_warning": "La VLAN ID 0 se utiliza por defecto en otros productos, inclusive fuera del universo Public Cloud. Por favor, preste atención al gestionar sus IP privadas." + "pci_projects_project_network_private_create_vlan_id_warning": "La VLAN ID 0 se utiliza por defecto en otros productos, inclusive fuera del universo Public Cloud. Por favor, preste atención al gestionar sus IP privadas.", + "pci_projects_network_cidr": "Introduzca una dirección IP válida" } diff --git a/packages/manager/apps/pci-private-network/public/translations/new/Messages_fr_CA.json b/packages/manager/apps/pci-private-network/public/translations/new/Messages_fr_CA.json index d9ee38aa03f2..696930497d44 100644 --- a/packages/manager/apps/pci-private-network/public/translations/new/Messages_fr_CA.json +++ b/packages/manager/apps/pci-private-network/public/translations/new/Messages_fr_CA.json @@ -36,5 +36,6 @@ "pci_projects_project_network_private_create_loading": "La création du réseau privé est en cours. Cela peut prendre quelques minutes", "pci_projects_project_network_private_create_success": "Le réseau privé a bien été créé", "pci_projects_project_network_private_create_error": "Une erreur est survenue lors de la création du réseau privé : {{ message }}", - "pci_projects_project_network_private_create_vlan_id_warning": "Le VLAN id 0 est utilisé par défaut sur d'autres produits y compris en dehors de l'univers Public Cloud. Les IP privées doivent être gérées avec attention" + "pci_projects_project_network_private_create_vlan_id_warning": "Le VLAN id 0 est utilisé par défaut sur d'autres produits y compris en dehors de l'univers Public Cloud. Les IP privées doivent être gérées avec attention", + "pci_projects_network_cidr": "Veuillez saisir une adresse IP valide" } diff --git a/packages/manager/apps/pci-private-network/public/translations/new/Messages_fr_FR.json b/packages/manager/apps/pci-private-network/public/translations/new/Messages_fr_FR.json index d9ee38aa03f2..696930497d44 100644 --- a/packages/manager/apps/pci-private-network/public/translations/new/Messages_fr_FR.json +++ b/packages/manager/apps/pci-private-network/public/translations/new/Messages_fr_FR.json @@ -36,5 +36,6 @@ "pci_projects_project_network_private_create_loading": "La création du réseau privé est en cours. Cela peut prendre quelques minutes", "pci_projects_project_network_private_create_success": "Le réseau privé a bien été créé", "pci_projects_project_network_private_create_error": "Une erreur est survenue lors de la création du réseau privé : {{ message }}", - "pci_projects_project_network_private_create_vlan_id_warning": "Le VLAN id 0 est utilisé par défaut sur d'autres produits y compris en dehors de l'univers Public Cloud. Les IP privées doivent être gérées avec attention" + "pci_projects_project_network_private_create_vlan_id_warning": "Le VLAN id 0 est utilisé par défaut sur d'autres produits y compris en dehors de l'univers Public Cloud. Les IP privées doivent être gérées avec attention", + "pci_projects_network_cidr": "Veuillez saisir une adresse IP valide" } diff --git a/packages/manager/apps/pci-private-network/public/translations/new/Messages_it_IT.json b/packages/manager/apps/pci-private-network/public/translations/new/Messages_it_IT.json index 84b134e8300c..acaa961765bb 100644 --- a/packages/manager/apps/pci-private-network/public/translations/new/Messages_it_IT.json +++ b/packages/manager/apps/pci-private-network/public/translations/new/Messages_it_IT.json @@ -36,5 +36,6 @@ "pci_projects_project_network_private_create_loading": "La creazione della rete privata è in corso. L’operazione potrebbe richiedere alcuni minuti.", "pci_projects_project_network_private_create_success": "La rete privata è stata creata correttamente.", "pci_projects_project_network_private_create_error": "Si è verificato un errore durante la modifica della rete privata: {{ message }}", - "pci_projects_project_network_private_create_vlan_id_warning": "Il VLAN id 0 è utilizzato di default su altri prodotti, anche al di fuori dell'universo Public Cloud. Gli IP privati devono essere gestiti con attenzione" + "pci_projects_project_network_private_create_vlan_id_warning": "Il VLAN id 0 è utilizzato di default su altri prodotti, anche al di fuori dell'universo Public Cloud. Gli IP privati devono essere gestiti con attenzione", + "pci_projects_network_cidr": "Inserisci un indirizzo IP valido" } diff --git a/packages/manager/apps/pci-private-network/public/translations/new/Messages_pl_PL.json b/packages/manager/apps/pci-private-network/public/translations/new/Messages_pl_PL.json index 0acf0655c8f6..ae06e7c73c87 100644 --- a/packages/manager/apps/pci-private-network/public/translations/new/Messages_pl_PL.json +++ b/packages/manager/apps/pci-private-network/public/translations/new/Messages_pl_PL.json @@ -36,5 +36,6 @@ "pci_projects_project_network_private_create_loading": "Trwa tworzenie prywatnej sieci. Może to zająć kilka minut.", "pci_projects_project_network_private_create_success": "Prywatna sieć została utworzona.", "pci_projects_project_network_private_create_error": "Wystąpił błąd podczas tworzenia sieci prywatnej: {{ message }}", - "pci_projects_project_network_private_create_vlan_id_warning": "Identyfikator VLAN 0 jest domyślnie używany w innych produktach, w tym także tych spoza środowiska Public Cloud. Prywatnymi adresami IP należy zarządzać ostrożnie." + "pci_projects_project_network_private_create_vlan_id_warning": "Identyfikator VLAN 0 jest domyślnie używany w innych produktach, w tym także tych spoza środowiska Public Cloud. Prywatnymi adresami IP należy zarządzać ostrożnie.", + "pci_projects_network_cidr": "Wprowadź poprawny adres IP" } diff --git a/packages/manager/apps/pci-private-network/public/translations/new/Messages_pt_PT.json b/packages/manager/apps/pci-private-network/public/translations/new/Messages_pt_PT.json index 3dab7d91af70..2f10dd6d867a 100644 --- a/packages/manager/apps/pci-private-network/public/translations/new/Messages_pt_PT.json +++ b/packages/manager/apps/pci-private-network/public/translations/new/Messages_pt_PT.json @@ -36,5 +36,6 @@ "pci_projects_project_network_private_create_loading": "A criação da rede privada está em curso. Esta operação poderá demorar alguns minutos", "pci_projects_project_network_private_create_success": "A rede privada foi criada com êxito", "pci_projects_project_network_private_create_error": "Ocorreu um erro ao criar a rede privada: {{ message }}", - "pci_projects_project_network_private_create_vlan_id_warning": "O VLAN id 0 é utilizado por predefinição noutros produtos, mesmo fora do universo Public Cloud. Os IP privados devem ser geridos com atenção" + "pci_projects_project_network_private_create_vlan_id_warning": "O VLAN id 0 é utilizado por predefinição noutros produtos, mesmo fora do universo Public Cloud. Os IP privados devem ser geridos com atenção", + "pci_projects_network_cidr": "Introduza um endereço IP válido" } diff --git a/packages/manager/apps/pci-private-network/src/api/utils/utils.spec.ts b/packages/manager/apps/pci-private-network/src/api/utils/utils.spec.ts index 598e2ccc5c65..de895f11e1af 100644 --- a/packages/manager/apps/pci-private-network/src/api/utils/utils.spec.ts +++ b/packages/manager/apps/pci-private-network/src/api/utils/utils.spec.ts @@ -3,6 +3,8 @@ import { getLocalZoneRegions, isLocalZoneRegion, paginateResults, + isValidCidrMask, + isValidIpAddress, } from './utils'; import { TRegion } from '@/api/data/regions'; @@ -85,3 +87,33 @@ describe('getAutoGeneratedName', () => { expect(result).toMatch(/^\d+-\d+$/); }); }); + +describe('isValidCidrMask', () => { + it.each([0, 33])( + 'should return false when number is not between 8 and 29', + (cidr) => { + const result = isValidCidrMask(cidr); + expect(result).toBe(false); + }, + ); + + it('should return true when number is between 8 and 29', () => { + const result = isValidCidrMask(16); + expect(result).toBe(true); + }); +}); + +describe('isValidIpAddress', () => { + it('should return true when IP is correct', () => { + const result = isValidIpAddress('10.0.0.1'); + expect(result).toBe(true); + }); + + it.each(['172.0.0.0.1', '172.0.0a', '172.0.259'])( + 'should return false when IP is incorrect', + (ip) => { + const result = isValidIpAddress(ip); + expect(result).toBe(false); + }, + ); +}); diff --git a/packages/manager/apps/pci-private-network/src/api/utils/utils.ts b/packages/manager/apps/pci-private-network/src/api/utils/utils.ts index d864e9fe6f51..52029c1d8080 100644 --- a/packages/manager/apps/pci-private-network/src/api/utils/utils.ts +++ b/packages/manager/apps/pci-private-network/src/api/utils/utils.ts @@ -37,3 +37,12 @@ export const getAutoGeneratedName = (prefix = ''): string => { return `${prefixPart}${date}-${randomNumber}`; }; + +export function isValidCidrMask(mask: number): boolean { + return mask >= 8 && mask <= 29; +} + +export function isValidIpAddress(ip: string): boolean { + const regex = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; + return regex.test(ip); +} diff --git a/packages/manager/apps/pci-private-network/src/pages/new/steps/ConfigurationStep.tsx b/packages/manager/apps/pci-private-network/src/pages/new/steps/ConfigurationStep.tsx index a9724c5dad3b..15f99bd9f640 100644 --- a/packages/manager/apps/pci-private-network/src/pages/new/steps/ConfigurationStep.tsx +++ b/packages/manager/apps/pci-private-network/src/pages/new/steps/ConfigurationStep.tsx @@ -33,7 +33,7 @@ import { OsdsSpinner, OsdsText, } from '@ovhcloud/ods-components/react'; -import { useContext, useEffect, useState } from 'react'; +import { useContext, useEffect, useState, useMemo } from 'react'; import { useParams } from 'react-router-dom'; import { ShellContext } from '@ovh-ux/manager-react-shell-client'; import { useGatewayByRegion } from '@/api/hooks/useGateway'; @@ -54,6 +54,7 @@ import { StepsEnum, useNewNetworkStore, } from '@/pages/new/store'; +import { isValidCidrMask, isValidIpAddress } from '@/api/utils/utils'; const isVlanAvailable = ( networks: TAggregatedNetwork[], @@ -86,9 +87,7 @@ export default function ConfigurationStep({ const store = useNewNetworkStore(); const { clearNotifications } = useNotifications(); - const { t } = useTranslation('new'); - const { t: tCommon } = useTranslation('common'); - const { t: tNew } = useTranslation('new'); + const { t } = useTranslation(['common', 'new']); const { data: regions, @@ -220,9 +219,31 @@ export default function ConfigurationStep({ const missingNameError = isNetworkNameInputTouched && !store.form.privateNetworkName.length; + const isIpValid = useMemo(() => isValidIpAddress(store.form.address), [ + store.form.address, + ]); + const isMaskValid = useMemo(() => isValidCidrMask(store.form.cidr), [ + store.form.cidr, + ]); + + const isCreateBtnDisabled = useMemo( + () => + !store.form.privateNetworkName || + (!store.form.createGateway && store.project.isDiscovery) || + (store.form.dhcp && (!isIpValid || !isMaskValid)), + [ + store.form.privateNetworkName, + store.form.createGateway, + store.form.dhcp, + store.project.isDiscovery, + isIpValid, + isMaskValid, + ], + ); + return ( { store.updateStep.unCheck(StepsEnum.CONFIGURATION); @@ -230,7 +251,7 @@ export default function ConfigurationStep({ store.updateStep.close(StepsEnum.SUMMARY); }, - label: tCommon('common_stepper_modify_this_step'), + label: t('common_stepper_modify_this_step'), isDisabled: false, }} order={2} @@ -241,12 +262,10 @@ export default function ConfigurationStep({ {!isNetworkLoading ? (
- {t('pci_projects_project_network_private_create_name')} + {t('new:pci_projects_project_network_private_create_name')} {t( - 'pci_projects_project_network_private_create_public_gateway', + 'new:pci_projects_project_network_private_create_public_gateway', )} @@ -308,7 +327,7 @@ export default function ConfigurationStep({ @@ -338,7 +357,7 @@ export default function ConfigurationStep({ {t( - 'pci_projects_project_network_private_create_layer_2_options', + 'new:pci_projects_project_network_private_create_layer_2_options', )}
@@ -378,7 +397,7 @@ export default function ConfigurationStep({ size={ODS_TEXT_SIZE._500} > {t( - 'pci_projects_project_network_private_create_configure_choose_vlan', + 'new:pci_projects_project_network_private_create_configure_choose_vlan', )} @@ -390,7 +409,9 @@ export default function ConfigurationStep({ level={ODS_TEXT_LEVEL.body} size={ODS_TEXT_SIZE._400} > - {t('pci_projects_project_network_private_create_vlan_tip')} + {t( + 'new:pci_projects_project_network_private_create_vlan_tip', + )}
@@ -401,7 +422,7 @@ export default function ConfigurationStep({ size={ODS_TEXT_SIZE._400} > {t( - 'pci_projects_project_network_private_create_vlan_id_warning', + 'new:pci_projects_project_network_private_create_vlan_id_warning', )} @@ -418,7 +439,7 @@ export default function ConfigurationStep({ slot="label" > {t( - 'pci_projects_project_network_private_create_configure_vlan', + 'new:pci_projects_project_network_private_create_configure_vlan', )} @@ -472,7 +493,7 @@ export default function ConfigurationStep({ slot="helper" > {t( - 'pci_projects_project_network_private_create_configure_vlan_limits', + 'new:pci_projects_project_network_private_create_configure_vlan_limits', )}
@@ -490,7 +511,7 @@ export default function ConfigurationStep({ size={ODS_TEXT_SIZE._400} > {t( - 'pci_projects_project_network_private_create_configure_vlan_taken', + 'new:pci_projects_project_network_private_create_configure_vlan_taken', )} @@ -507,7 +528,7 @@ export default function ConfigurationStep({ className="mb-6" > {t( - 'pci_projects_project_network_private_create_dhcp_address_distribution_options', + 'new:pci_projects_project_network_private_create_dhcp_address_distribution_options', )}
@@ -529,7 +550,7 @@ export default function ConfigurationStep({ size={ODS_TEXT_SIZE._500} > {t( - 'pci_projects_project_network_private_create_enable_dhcp', + 'new:pci_projects_project_network_private_create_enable_dhcp', )} @@ -543,29 +564,41 @@ export default function ConfigurationStep({ {t( - 'pci_projects_project_network_private_create_configure_address', + 'new:pci_projects_project_network_private_create_configure_address', )} { + store.setForm({ address: target.value as string }); + }} inline - disabled /> {t( - 'pci_projects_project_network_private_create_configure_mask', + 'new:pci_projects_project_network_private_create_configure_mask', )} { + store.setForm({ cidr: +target.value }); + }} inline - disabled /> @@ -583,13 +616,22 @@ export default function ConfigurationStep({ level={ODS_TEXT_LEVEL.body} > {t( - 'pci_projects_project_network_private_create_configure_api', + 'new:pci_projects_project_network_private_create_configure_api', )}
+ {(!isIpValid || !isMaskValid) && ( + + {t('new:pci_projects_network_cidr')} + + )} + {store.form.dhcp && (
{t( - 'pci_projects_project_network_private_create_announce_first_address', + 'new:pci_projects_project_network_private_create_announce_first_address', )} @@ -631,7 +673,7 @@ export default function ConfigurationStep({ level={ODS_TEXT_LEVEL.body} size={ODS_TEXT_SIZE._500} > - {t('pci_projects_project_network_private_create_loading')} + {t('new:pci_projects_project_network_private_create_loading')}
)} @@ -653,15 +695,12 @@ export default function ConfigurationStep({ } }} className="w-fit" - {...(!store.form.privateNetworkName || - (!store.form.createGateway && store.project.isDiscovery) - ? { disabled: true } - : {})} + disabled={isCreateBtnDisabled || undefined} > {t( store.form.createGateway - ? 'pci_projects_project_network_private_create_next' - : 'pci_projects_project_network_private_create_submit', + ? 'new:pci_projects_project_network_private_create_next' + : 'new:pci_projects_project_network_private_create_submit', )} )} @@ -669,7 +708,7 @@ export default function ConfigurationStep({
- {tNew('pci_projects_project_network_private_create_loading')} + {t('new:pci_projects_project_network_private_create_loading')}
)} From 7368463fe9f19b038ccbe660812c156ffb8d04af Mon Sep 17 00:00:00 2001 From: Yann Lojewski Date: Thu, 10 Oct 2024 16:27:11 +0200 Subject: [PATCH 02/11] Revert "Revert "feat(pci.instance): open backup creation for LZ regions (#13250)"" (#13524) This reverts commit aaa546091bddd537b0668c17b2c5c887376f6887. Co-authored-by: Yann Lojewski --- .../instances/backup/backup.routing.js | 8 ++++++- .../instance/backup/backup.contants.js | 3 +++ .../instance/backup/backup.controller.js | 20 +++++++++++++++- .../instances/instance/backup/backup.html | 2 +- .../backup/translations/Messages_de_DE.json | 2 +- .../backup/translations/Messages_en_GB.json | 2 +- .../backup/translations/Messages_es_ES.json | 2 +- .../backup/translations/Messages_fr_CA.json | 2 +- .../backup/translations/Messages_fr_FR.json | 2 +- .../backup/translations/Messages_it_IT.json | 2 +- .../backup/translations/Messages_pl_PL.json | 2 +- .../backup/translations/Messages_pt_PT.json | 2 +- .../project/instances/instance/instance.html | 2 +- .../projects/project/instances/instances.html | 2 +- .../project/instances/instances.service.js | 24 +++++++++++-------- .../instance-backups.controller.js | 8 ++++++- .../instance-backups/instance-backups.html | 10 ++++++++ .../instance-backups.service.js | 18 +++++--------- 18 files changed, 77 insertions(+), 36 deletions(-) diff --git a/packages/manager/modules/pci/src/projects/project/instances/backup/backup.routing.js b/packages/manager/modules/pci/src/projects/project/instances/backup/backup.routing.js index 062af911ed83..308b2eee2070 100644 --- a/packages/manager/modules/pci/src/projects/project/instances/backup/backup.routing.js +++ b/packages/manager/modules/pci/src/projects/project/instances/backup/backup.routing.js @@ -14,7 +14,13 @@ export default /* @ngInject */ ($stateProvider) => { PciProjectsProjectInstanceService, projectId, instanceId, - ) => PciProjectsProjectInstanceService.get(projectId, instanceId), + customerRegions, + ) => + PciProjectsProjectInstanceService.get( + projectId, + instanceId, + customerRegions, + ), monthlyPrice: /* @ngInject */ ( PciProjectsProjectInstanceService, projectId, diff --git a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/backup.contants.js b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/backup.contants.js index 4190630f9e41..835f429bced8 100644 --- a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/backup.contants.js +++ b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/backup.contants.js @@ -3,6 +3,9 @@ export const FLAVORS_TYPE = { iops: 'ovh.iops', }; +export const HOURS_PER_MONTH = 730; + export default { FLAVORS_TYPE, + HOURS_PER_MONTH, }; diff --git a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/backup.controller.js b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/backup.controller.js index de08a110fd12..804f12e50591 100644 --- a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/backup.controller.js +++ b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/backup.controller.js @@ -1,6 +1,6 @@ import get from 'lodash/get'; -import { FLAVORS_TYPE } from './backup.contants'; +import { FLAVORS_TYPE, HOURS_PER_MONTH } from './backup.contants'; export default class PciInstanceBackupController { /* @ngInject */ @@ -10,6 +10,7 @@ export default class PciInstanceBackupController { CucCloudMessage, PciProjectsProjectInstanceService, atInternet, + coreConfig, ) { this.$filter = $filter; this.$translate = $translate; @@ -17,6 +18,7 @@ export default class PciInstanceBackupController { this.PciProjectsProjectInstanceService = PciProjectsProjectInstanceService; this.atInternet = atInternet; this.FLAVORS_TYPE = FLAVORS_TYPE; + this.coreConfig = coreConfig; } $onInit() { @@ -70,4 +72,20 @@ export default class PciInstanceBackupController { type: 'action', }); } + + formatPrice() { + const { price } = this.monthlyPrice; + if (this.instance.isLocalZone) { + const { value, currencyCode } = price; + return `~${new Intl.NumberFormat( + this.coreConfig.getUserLocale().replace('_', '-'), + { + style: 'currency', + currency: currencyCode, + maximumFractionDigits: 3, + }, + ).format(value * HOURS_PER_MONTH)}`; + } + return price.text; + } } diff --git a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/backup.html b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/backup.html index 343233a102c6..c3106589951a 100644 --- a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/backup.html +++ b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/backup.html @@ -29,7 +29,7 @@ diff --git a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_de_DE.json b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_de_DE.json index 12280c324832..2511c8fd24f3 100644 --- a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_de_DE.json +++ b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_de_DE.json @@ -5,7 +5,7 @@ "pci_projects_project_instances_instance_backup_price": "Preis: {{ price }} ohne MWSt./Monat/GB", "pci_projects_project_instances_instance_backup_submit_label": "Bestätigen", "pci_projects_project_instances_instance_backup_cancel_label": "Abbrechen", - "pci_projects_project_instances_instance_backup_success_message": "Das Backup {{ backup }} wird erstellt", + "pci_projects_project_instances_instance_backup_success_message": "Das Backup {{ backup }} wird erstellt. Um sich den Status und die Details des Vorgangs anzusehen, gehen Sie bitte auf die Seite „Instance Backup“. Wenn das Backup nicht sofort angezeigt wird, können Sie Ihre Seite aktualisieren, damit auch die Liste aktualisiert wird.", "pci_projects_project_instances_instance_backup_error_backup": "Bei der Erstellung des Backups {{ backup }} ist ein Fehler aufgetreten: {{message}}", "pci_projects_project_instances_instance_backup_warning_iops_message": "Das Backup betrifft nur Ihre Root-Festplatte (Betriebssystem). Für Daten auf NVMe-Geräten wird kein Backup erstellt. Bitte verwenden Sie hierfür Ihre eigenen Tools.", "pci_projects_project_instances_instance_backup_trusted_zone_extra_amount_charge_message": "Der angezeigte Preis entspricht dem Preis der Dienstleistung. Der Aufpreis für die Trusted Zone wird der monatlichen Gesamtabrechnung hinzugefügt.", diff --git a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_en_GB.json b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_en_GB.json index 0ae4f36036a7..251abd20c2a1 100644 --- a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_en_GB.json +++ b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_en_GB.json @@ -5,7 +5,7 @@ "pci_projects_project_instances_instance_backup_price": "Price: {{ price }} ex. VAT/month/GB", "pci_projects_project_instances_instance_backup_submit_label": "Confirm", "pci_projects_project_instances_instance_backup_cancel_label": "Cancel", - "pci_projects_project_instances_instance_backup_success_message": "Creating the {{ backup }} backup", + "pci_projects_project_instances_instance_backup_success_message": "Creating the {{ backup }} backup... To view the status and details of the operation, go to the ‘Instance Backup’ page. If the backup doesn’t appear right away, please refresh the page to update list.", "pci_projects_project_instances_instance_backup_error_backup": "An error has occurred creating the {{ backup }} backup: {{ message }}", "pci_projects_project_instances_instance_backup_warning_iops_message": "The backup only includes your root disk (operating system). None of the data stored on your NVMe devices will be backed up. Please use your own tools for this.", "pci_projects_project_instances_instance_backup_trusted_zone_extra_amount_charge_message": "The price displayed corresponds to the price of the service. The trust zone surcharge is added to the overall monthly bill.", diff --git a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_es_ES.json b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_es_ES.json index b3266ef31561..15f7f1a2409e 100644 --- a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_es_ES.json +++ b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_es_ES.json @@ -5,7 +5,7 @@ "pci_projects_project_instances_instance_backup_price": "Precio: {{ price }}/mes + IVA por GB", "pci_projects_project_instances_instance_backup_submit_label": "Confirmar", "pci_projects_project_instances_instance_backup_cancel_label": "Cancelar", - "pci_projects_project_instances_instance_backup_success_message": "El backup {{ backup }} se está creando...", + "pci_projects_project_instances_instance_backup_success_message": "Creando el backup {{ backup }}... Para consultar su estado y los detalles de la operación, acceda a la página «Instance Backup». Si el backup no aparece inmediatamente, recargue la página para actualizar la lista.", "pci_projects_project_instances_instance_backup_error_backup": "Se ha producido un error al crear el backup {{ backup }}: {{ message }}.", "pci_projects_project_instances_instance_backup_warning_iops_message": "Solo se realizará la copia de seguridad del disco raíz (sistema operativo). No se guardará ningún dato desde los periféricos NVMe. Para realizar copias de seguridad de estos datos deberá utilizar sus propias herramientas.", "pci_projects_project_instances_instance_backup_trusted_zone_extra_amount_charge_message": "El precio mostrado corresponde al precio del servicio. El recargo correspondiente a la zona de confianza (Trusted Zone) se añade a la facturación mensual global.", diff --git a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_fr_CA.json b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_fr_CA.json index 6bdf3e743e57..10b36f0ec95b 100644 --- a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_fr_CA.json +++ b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_fr_CA.json @@ -6,7 +6,7 @@ "pci_projects_project_instances_instance_backup_price": "Prix : {{ price }} HT/mois/Go", "pci_projects_project_instances_instance_backup_submit_label": "Confirmer", "pci_projects_project_instances_instance_backup_cancel_label": "Annuler", - "pci_projects_project_instances_instance_backup_success_message": "Le backup {{ backup }} est en cours de création", + "pci_projects_project_instances_instance_backup_success_message": "Le backup {{ backup }} est en cours de création. Pour visualiser son statut et les détails de l'opération, veuillez vous rendre sur la page 'Instance Backup'. Si le backup ne s'affiche pas immédiatement, n'hésitez pas à rafraîchir votre page pour mettre à jour la liste.", "pci_projects_project_instances_instance_backup_error_backup": "Une erreur est survenue lors de la création du backup {{ backup }} : {{ message }}", "pci_projects_project_instances_instance_backup_warning_iops_message": "La sauvegarde ne concerne que votre disque racine (système d'exploitation). Aucune donnée ne sera sauvegardée à partir de périphériques NVMe. Veuillez utiliser vos propres outils pour cela.", "pci_projects_project_instances_instance_backup_trusted_zone_extra_amount_charge_message": "Le prix affiché correspond au prix du service. La majoration liée à la zone de confiance est ajoutée à la facturation mensuelle globale." diff --git a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_fr_FR.json b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_fr_FR.json index 6bdf3e743e57..10b36f0ec95b 100644 --- a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_fr_FR.json +++ b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_fr_FR.json @@ -6,7 +6,7 @@ "pci_projects_project_instances_instance_backup_price": "Prix : {{ price }} HT/mois/Go", "pci_projects_project_instances_instance_backup_submit_label": "Confirmer", "pci_projects_project_instances_instance_backup_cancel_label": "Annuler", - "pci_projects_project_instances_instance_backup_success_message": "Le backup {{ backup }} est en cours de création", + "pci_projects_project_instances_instance_backup_success_message": "Le backup {{ backup }} est en cours de création. Pour visualiser son statut et les détails de l'opération, veuillez vous rendre sur la page 'Instance Backup'. Si le backup ne s'affiche pas immédiatement, n'hésitez pas à rafraîchir votre page pour mettre à jour la liste.", "pci_projects_project_instances_instance_backup_error_backup": "Une erreur est survenue lors de la création du backup {{ backup }} : {{ message }}", "pci_projects_project_instances_instance_backup_warning_iops_message": "La sauvegarde ne concerne que votre disque racine (système d'exploitation). Aucune donnée ne sera sauvegardée à partir de périphériques NVMe. Veuillez utiliser vos propres outils pour cela.", "pci_projects_project_instances_instance_backup_trusted_zone_extra_amount_charge_message": "Le prix affiché correspond au prix du service. La majoration liée à la zone de confiance est ajoutée à la facturation mensuelle globale." diff --git a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_it_IT.json b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_it_IT.json index 4f22c523b923..1cce7fe8a8f2 100644 --- a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_it_IT.json +++ b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_it_IT.json @@ -5,7 +5,7 @@ "pci_projects_project_instances_instance_backup_price": "Prezzo: {{price}} IVA/mese/GB", "pci_projects_project_instances_instance_backup_submit_label": "Conferma", "pci_projects_project_instances_instance_backup_cancel_label": "Annulla", - "pci_projects_project_instances_instance_backup_success_message": "Creazione del backup {{ backup }} in corso...", + "pci_projects_project_instances_instance_backup_success_message": "Creazione del backup {{ backup }} in corso... Per visualizzare il suo stato e i dettagli dell'operazione, accedi alla pagina \"Instance Backup\". Se il backup non compare immediatamente, fai il refresh della pagina per aggiornare la lista.", "pci_projects_project_instances_instance_backup_error_backup": "Si è verificato un errore durante la creazione del backup {{ backup }}: {{ message }}", "pci_projects_project_instances_instance_backup_warning_iops_message": "Il backup sarà relativo esclusivamente al disco di root (sistema operativo). Non verrà salvato nessun dato dalle periferiche NVMe. Per eseguire questa operazione, utilizza i tool a tua disposizione.", "pci_projects_project_instances_instance_backup_trusted_zone_extra_amount_charge_message": "il prezzo visualizzato corrisponde al prezzo del servizio. Il costo supplementare per la Trusted Zone viene aggiunto alla fatturazione mensile totale.", diff --git a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_pl_PL.json b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_pl_PL.json index 8b1a5849a6ed..1e5d29d6e02a 100644 --- a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_pl_PL.json +++ b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_pl_PL.json @@ -5,7 +5,7 @@ "pci_projects_project_instances_instance_backup_price": "Cena: {{ price }} netto/m-c/VM", "pci_projects_project_instances_instance_backup_submit_label": "Potwierdź", "pci_projects_project_instances_instance_backup_cancel_label": "Anuluj", - "pci_projects_project_instances_instance_backup_success_message": "Trwa tworzenie kopii instancji {{ backup }}.", + "pci_projects_project_instances_instance_backup_success_message": "Trwa tworzenie kopii instancji {{backup}}. Aby sprawdzić status i szczegóły operacji, odwiedź stronę „Instance Backup”. Jeśli kopia zapasowa nie wyświetla się natychmiast, odśwież stronę, aby zaktualizować listę.", "pci_projects_project_instances_instance_backup_error_backup": "Wystąpił błąd podczas tworzenia kopii zapasowej {{ backup }}: {{ message }}", "pci_projects_project_instances_instance_backup_warning_iops_message": "Zostanie wykonana tylko kopia zapasowa dysku (systemu operacyjnego). Nie zostanie wykonana żadna kopia zapasowa danych z urządzeń NVMe. Użyj do tego własnych narzędzi.", "pci_projects_project_instances_instance_backup_trusted_zone_extra_amount_charge_message": "Podana cena odpowiada cenie usługi. Dopłata za opcję Trusted Zone jest doliczana do kwoty miesięcznej faktury.", diff --git a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_pt_PT.json b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_pt_PT.json index fe2b774da765..48a0253e16a6 100644 --- a/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_pt_PT.json +++ b/packages/manager/modules/pci/src/projects/project/instances/instance/backup/translations/Messages_pt_PT.json @@ -5,7 +5,7 @@ "pci_projects_project_instances_instance_backup_price": "Preço: {{ price }}/mês por GB + IVA", "pci_projects_project_instances_instance_backup_submit_label": "Confirmar", "pci_projects_project_instances_instance_backup_cancel_label": "Anular", - "pci_projects_project_instances_instance_backup_success_message": "O backup {{ backup }}está em processo de criação", + "pci_projects_project_instances_instance_backup_success_message": "O backup {{ backup }} está em processo de criação. Para consultar o estado e os detalhes da operação, aceda à página 'Instance Backup'. Se o backup não for apresentado logo de imediato, tente atualizar a página para atualizar a lista.", "pci_projects_project_instances_instance_backup_error_backup": "Ocorreu um erro durante a criação do backup {{ backup }}: {{ message }}", "pci_projects_project_instances_instance_backup_warning_iops_message": "A cópia de segurança só inclui o seu disco de raiz (sistema operativo). Não será feito nenhum backup dos dados armazenados nos seus dispositivos NVMe. Utilize as suas próprias ferramentas para o fazer.", "pci_projects_project_instances_instance_backup_trusted_zone_extra_amount_charge_message": "O preço indicado corresponde ao preço do serviço. O custo adicional relativo ao Trusted Zone é adicionado à faturação mensal global.", diff --git a/packages/manager/modules/pci/src/projects/project/instances/instance/instance.html b/packages/manager/modules/pci/src/projects/project/instances/instance/instance.html index a506ccf82f92..dd9db76e6bfa 100644 --- a/packages/manager/modules/pci/src/projects/project/instances/instance/instance.html +++ b/packages/manager/modules/pci/src/projects/project/instances/instance/instance.html @@ -61,7 +61,7 @@ { - return get( - catalog, - `snapshot.monthly.postpaid.${instance.region}`, - get( + return this.CucPriceHelper.getPrices( + projectId, + catalogEndpoint, + ).then((catalog) => + instance.isLocalZone + ? catalog[`snapshot.consumption.${instance.region}`] ?? + catalog['snapshot.consumption.LZ'] + : get( catalog, - 'snapshot.monthly.postpaid', - get(catalog, 'snapshot.monthly', false), + `snapshot.monthly.postpaid.${instance.region}`, + get( + catalog, + 'snapshot.monthly.postpaid', + get(catalog, 'snapshot.monthly', false), + ), ), - ); - }, ); } diff --git a/packages/manager/modules/pci/src/projects/project/storages/instance-backups/instance-backups.controller.js b/packages/manager/modules/pci/src/projects/project/storages/instance-backups/instance-backups.controller.js index ba1907d8b401..07fda51a2c4c 100644 --- a/packages/manager/modules/pci/src/projects/project/storages/instance-backups/instance-backups.controller.js +++ b/packages/manager/modules/pci/src/projects/project/storages/instance-backups/instance-backups.controller.js @@ -2,7 +2,8 @@ import { getCriteria } from '../../project.utils'; export default class PciInstanceBackupsController { /* @ngInject */ - constructor(CucCloudMessage, ovhManagerRegionService) { + constructor($state, CucCloudMessage, ovhManagerRegionService) { + this.$state = $state; this.CucCloudMessage = CucCloudMessage; this.ovhManagerRegionService = ovhManagerRegionService; } @@ -24,4 +25,9 @@ export default class PciInstanceBackupsController { refreshMessages() { this.messages = this.messageHandler.getMessages(); } + + refreshList() { + const { name } = this.$state.current; + return this.$state.go(name, {}, { reload: name }); + } } diff --git a/packages/manager/modules/pci/src/projects/project/storages/instance-backups/instance-backups.html b/packages/manager/modules/pci/src/projects/project/storages/instance-backups/instance-backups.html index fcb67d9cadd0..09cf125761b1 100644 --- a/packages/manager/modules/pci/src/projects/project/storages/instance-backups/instance-backups.html +++ b/packages/manager/modules/pci/src/projects/project/storages/instance-backups/instance-backups.html @@ -136,6 +136,16 @@ data-translate="pci_projects_project_storages_instance-backups_add_label" > + diff --git a/packages/manager/modules/pci/src/projects/project/storages/instance-backups/instance-backups.service.js b/packages/manager/modules/pci/src/projects/project/storages/instance-backups/instance-backups.service.js index 7297d6aba3f8..593afbfc3a26 100644 --- a/packages/manager/modules/pci/src/projects/project/storages/instance-backups/instance-backups.service.js +++ b/packages/manager/modules/pci/src/projects/project/storages/instance-backups/instance-backups.service.js @@ -1,26 +1,20 @@ import filter from 'lodash/filter'; -import map from 'lodash/map'; import InstanceBackup from './instance-backup.class'; export default class PciProjectStorageInstanceBackupService { /* @ngInject */ - constructor($q, OvhApiCloudProject, OvhApiCloudProjectInstance) { + constructor($q, $http, OvhApiCloudProject, OvhApiCloudProjectInstance) { this.$q = $q; + this.$http = $http; this.OvhApiCloudProject = OvhApiCloudProject; this.OvhApiCloudProjectInstance = OvhApiCloudProjectInstance; } getAll(projectId) { - return this.OvhApiCloudProject.Snapshot() - .v6() - .query({ - serviceName: projectId, - }) - .$promise.then((instanceBackups) => - map( - instanceBackups, - (instanceBackup) => new InstanceBackup(instanceBackup), - ), + return this.$http + .get(`/cloud/project/${projectId}/snapshot`) + .then(({ data: instances }) => + instances.map((instance) => new InstanceBackup(instance)), ); } From 9fc61993e0f19d41bbdd60370f83cb3a2058e763 Mon Sep 17 00:00:00 2001 From: Pierre-Philippe Prevost Date: Thu, 10 Oct 2024 16:30:22 +0200 Subject: [PATCH 03/11] feat(pci.kubernetes): include upgrade policy wording ref: TAPC-329, TAPC-800 Signed-off-by: Pierre-Philippe Co-authored-by: CDS Translator Agent --- .../translations/add/Messages_de_DE.json | 7 +- .../translations/add/Messages_en_GB.json | 7 +- .../translations/add/Messages_es_ES.json | 7 +- .../translations/add/Messages_fr_CA.json | 5 + .../translations/add/Messages_fr_FR.json | 5 + .../translations/add/Messages_it_IT.json | 7 +- .../translations/add/Messages_pl_PL.json | 7 +- .../translations/add/Messages_pt_PT.json | 7 +- .../translations/versions/Messages_de_DE.json | 2 +- .../translations/versions/Messages_en_GB.json | 2 +- .../translations/versions/Messages_es_ES.json | 2 +- .../translations/versions/Messages_fr_CA.json | 2 +- .../translations/versions/Messages_fr_FR.json | 2 +- .../translations/versions/Messages_it_IT.json | 2 +- .../translations/versions/Messages_pl_PL.json | 2 +- .../translations/versions/Messages_pt_PT.json | 2 +- .../pci-kubernetes/src/api/data/kubernetes.ts | 1 + .../components/VersionSelector.component.tsx | 85 ------------ .../apps/pci-kubernetes/src/constants.ts | 4 +- .../pci-kubernetes/src/pages/new/New.page.tsx | 7 +- .../UpdatePolicySelector.component.spec.tsx | 87 ++++++++++++ .../steps/UpdatePolicySelector.component.tsx | 124 +++++++++++++++++ .../VersionAndUpdatePolicyStep.component.tsx | 81 +++++++++++ .../steps/VersionSelector.component.spec.tsx | 130 ++++++++++++++++++ .../new/steps/VersionSelector.component.tsx | 100 ++++++++++++++ .../pages/new/steps/VersionStep.component.tsx | 53 ------- .../src/pages/new/useCusterCreationStepper.ts | 6 +- .../upgrade-policy/UpgradePolicy.constant.tsx | 50 +++++++ .../apps/pci-kubernetes/src/types/index.ts | 6 + 29 files changed, 644 insertions(+), 158 deletions(-) delete mode 100644 packages/manager/apps/pci-kubernetes/src/components/VersionSelector.component.tsx create mode 100644 packages/manager/apps/pci-kubernetes/src/pages/new/steps/UpdatePolicySelector.component.spec.tsx create mode 100644 packages/manager/apps/pci-kubernetes/src/pages/new/steps/UpdatePolicySelector.component.tsx create mode 100644 packages/manager/apps/pci-kubernetes/src/pages/new/steps/VersionAndUpdatePolicyStep.component.tsx create mode 100644 packages/manager/apps/pci-kubernetes/src/pages/new/steps/VersionSelector.component.spec.tsx create mode 100644 packages/manager/apps/pci-kubernetes/src/pages/new/steps/VersionSelector.component.tsx delete mode 100644 packages/manager/apps/pci-kubernetes/src/pages/new/steps/VersionStep.component.tsx create mode 100644 packages/manager/apps/pci-kubernetes/src/pages/upgrade-policy/UpgradePolicy.constant.tsx diff --git a/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_de_DE.json b/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_de_DE.json index 5a24bdbd71dd..ace034f39f75 100644 --- a/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_de_DE.json +++ b/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_de_DE.json @@ -38,5 +38,10 @@ "kube_add_billing_auto_scaling_monthly_warning": "Bitte beachten Sie: Sie aktivieren gleichzeitig Autoscaling und die Monatspauschale für diesen Nodepool. Jede Erstellung von Nodes durch Autoscaling führt zur sofortigen anteiligen Abrechnung eines Nodes je nach verbleibender Zeit im laufenden Monat. Können Sie bereits absehen, dass Sie den Nodepool häufig reduzieren werden? Dann raten wir von dieser Kombination ab.", "kube_add_node_pool_name_input_pattern_validation_error": "Der Name muss aus mindestens zwei Zeichen bestehen, mit einem alphabetischen Zeichen beginnen und mit einem alphanumerischen Zeichen enden. Die einzigen zulässigen Sonderzeichen sind der Gedankenstrich und der Unterstrich.", "kube_add_billing_anti_affinity_coming_soon_message_title": "Monatliche Preise", - "kube_add_billing_anti_affinity_coming_soon_message_description": "Die monatlichen Preise werden mit der Einführung der Saving Plans in Kürze verfügbar sein." + "kube_add_billing_anti_affinity_coming_soon_message_description": "Die monatlichen Preise werden mit der Einführung der Saving Plans in Kürze verfügbar sein.", + "kubernetes_add_version_and_upgrade_policy_title": "Wählen Sie die Kubernetes-Nebenversion und die gewünschte Sicherheitsrichtlinie aus", + "kube_update_policy_picker_documentation_text": "Mehr Informationen zu den Sicherheitsrichtlinien von Managed Kubernetes Service.", + "kube_update_policy_picker_documentation_link": "Siehe Dokumentation", + "kubernetes_add_update_policy_title": "Wählen Sie die Sicherheitseinstellungen", + "kubernetes_select_version_title": "Version auswählen" } diff --git a/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_en_GB.json b/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_en_GB.json index 6e3a3e6ade69..b52d60a7c9e1 100644 --- a/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_en_GB.json +++ b/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_en_GB.json @@ -38,5 +38,10 @@ "kube_add_billing_auto_scaling_monthly_warning": "Warning: You can enable auto-scaling and monthly billing at the same time for this node pool. Each time you create a node via auto-scaling, you will be billed for one node immediately on a pro rata basis for the remaining time in the current month. We recommend avoiding this combination if you anticipate that your node pool will be reduced frequently.", "kube_add_node_pool_name_input_pattern_validation_error": "The name must be at least two characters, start with an alphabetical character, end with an alphanumeric character, and the only special characters allowed are dashes and underscores.", "kube_add_billing_anti_affinity_coming_soon_message_title": "Monthly prices", - "kube_add_billing_anti_affinity_coming_soon_message_description": "With the launch of Saving Plans, we will soon be able to bill you monthly." + "kube_add_billing_anti_affinity_coming_soon_message_description": "With the launch of Saving Plans, we will soon be able to bill you monthly.", + "kubernetes_add_version_and_upgrade_policy_title": "Select the minor version of Kubernetes and the security policy you want", + "kube_update_policy_picker_documentation_text": "Learn more about Managed Kubernetes Service security policies.", + "kube_update_policy_picker_documentation_link": "Consult the documentation", + "kubernetes_add_update_policy_title": "Select the security policy", + "kubernetes_select_version_title": "Select a version" } diff --git a/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_es_ES.json b/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_es_ES.json index 08ecab494300..4b647675a08f 100644 --- a/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_es_ES.json +++ b/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_es_ES.json @@ -38,5 +38,10 @@ "kube_add_billing_auto_scaling_monthly_warning": "Atención: Puede activar simultáneamente el autoscaling y la tarificación mensual para este pool de nodos. Al crear un nodo a través de la funcionalidad de autoscaling, este se facturará de forma inmediata teniendo en cuenta la parte proporcional correspondiente al tiempo restante del mes en curso. Le recomendamos que evite esta combinación si prevé que el tamaño de su pool de nodos se reduzca con frecuencia.", "kube_add_node_pool_name_input_pattern_validation_error": "El nombre debe contener al menos dos caracteres, comenzar por un carácter alfabético y terminar por un carácter alfanumérico. Los únicos caracteres especiales permitidos son el guion y la barra baja.", "kube_add_billing_anti_affinity_coming_soon_message_title": "Precios mensuales", - "kube_add_billing_anti_affinity_coming_soon_message_description": "Los precios mensuales estarán disponibles próximamente con la llegada de los Saving Plans." + "kube_add_billing_anti_affinity_coming_soon_message_description": "Los precios mensuales estarán disponibles próximamente con la llegada de los Saving Plans.", + "kubernetes_add_version_and_upgrade_policy_title": "Seleccione la versión menor de Kubernetes y la política de seguridad deseada", + "kube_update_policy_picker_documentation_text": "Más información sobre las políticas de seguridad del servicio Managed Kubernetes.", + "kube_update_policy_picker_documentation_link": "Consulte la documentación", + "kubernetes_add_update_policy_title": "Seleccione la política de seguridad", + "kubernetes_select_version_title": "Seleccione una versión" } diff --git a/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_fr_CA.json b/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_fr_CA.json index f252c4538590..0b649052d38b 100644 --- a/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_fr_CA.json +++ b/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_fr_CA.json @@ -13,6 +13,11 @@ "kubernetes_add_region_failed": "Une erreur est survenue lors de l'ajout de la région {{ name }} : {{ message }}", "kubernetes_add_region_title": "Sélectionnez une localisation", "kubernetes_add_version_title": "Sélectionnez la version mineure de Kubernetes souhaitée", + "kubernetes_add_version_and_upgrade_policy_title": "Sélectionnez la version mineure de Kubernetes et la politique de sécurité souhaitée", + "kube_update_policy_picker_documentation_text": "Pour en savoir plus sur les politiques de sécurité de Managed Kubernetes Service.", + "kube_update_policy_picker_documentation_link": "Consultez la documentation", + "kubernetes_add_update_policy_title": "Sélectionnez la politique de sécurité", + "kubernetes_select_version_title": "Sélectionnez une version", "kubernetes_add_name_title": "Nommez votre cluster", "kubernetes_add_name": "Nom", "kubernetes_add_cluster_name_input_pattern_validation_error": "Le nom doit commencer par un caractère alphabétique, se terminer par un caractère alphanumérique et les seuls caractères spéciaux autorisés sont les tirets et les underscores.", diff --git a/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_fr_FR.json b/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_fr_FR.json index f252c4538590..0b649052d38b 100644 --- a/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_fr_FR.json +++ b/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_fr_FR.json @@ -13,6 +13,11 @@ "kubernetes_add_region_failed": "Une erreur est survenue lors de l'ajout de la région {{ name }} : {{ message }}", "kubernetes_add_region_title": "Sélectionnez une localisation", "kubernetes_add_version_title": "Sélectionnez la version mineure de Kubernetes souhaitée", + "kubernetes_add_version_and_upgrade_policy_title": "Sélectionnez la version mineure de Kubernetes et la politique de sécurité souhaitée", + "kube_update_policy_picker_documentation_text": "Pour en savoir plus sur les politiques de sécurité de Managed Kubernetes Service.", + "kube_update_policy_picker_documentation_link": "Consultez la documentation", + "kubernetes_add_update_policy_title": "Sélectionnez la politique de sécurité", + "kubernetes_select_version_title": "Sélectionnez une version", "kubernetes_add_name_title": "Nommez votre cluster", "kubernetes_add_name": "Nom", "kubernetes_add_cluster_name_input_pattern_validation_error": "Le nom doit commencer par un caractère alphabétique, se terminer par un caractère alphanumérique et les seuls caractères spéciaux autorisés sont les tirets et les underscores.", diff --git a/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_it_IT.json b/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_it_IT.json index cd767032c5be..2550be33c734 100644 --- a/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_it_IT.json +++ b/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_it_IT.json @@ -38,5 +38,10 @@ "kube_add_billing_type_payment_method": "L’importo verrà addebitato sul metodo di pagamento predefinito.", "kube_add_billing_anti_affinity_title": "Fatturazione e anti-affinità", "kube_add_billing_anti_affinity_coming_soon_message_title": "Prezzi mensili", - "kube_add_billing_anti_affinity_coming_soon_message_description": "I prezzi mensili saranno disponibili a breve con l'arrivo dei Saving Plans." + "kube_add_billing_anti_affinity_coming_soon_message_description": "I prezzi mensili saranno disponibili a breve con l'arrivo dei Saving Plans.", + "kubernetes_add_version_and_upgrade_policy_title": "Seleziona la versione minor di Kubernetes e la politica di sicurezza desiderata", + "kube_update_policy_picker_documentation_text": "Per saperne di più sulle politiche di sicurezza del servizio Managed Kubernetes.", + "kube_update_policy_picker_documentation_link": "Consulta la documentazione", + "kubernetes_add_update_policy_title": "Seleziona la politica di sicurezza", + "kubernetes_select_version_title": "Seleziona una versione" } diff --git a/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_pl_PL.json b/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_pl_PL.json index 061fb3a00d37..795fe9843b2e 100644 --- a/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_pl_PL.json +++ b/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_pl_PL.json @@ -38,5 +38,10 @@ "kube_add_billing_auto_scaling_monthly_warning": "Uwaga: aktywujesz jednocześnie autoskalowanie i abonament miesięczny dla tej puli węzłów. Za każdym razem gdy węzeł zostanie utworzony przez autoskalowanie, zostanie natychmiast zafakturowany proporcjonalnie do czasu pozostałego w bieżącym miesiącu. Radzimy unikać tej kombinacji, jeśli przewidujesz, że rozmiar puli węzłów będzie często zmniejszany.", "kube_add_node_pool_name_input_pattern_validation_error": "Nazwa musi składać się z co najmniej dwóch znaków, zaczynać się od litery, kończyć się znakiem alfanumerycznym, przy czym jedynymi dozwolonymi znakami specjalnymi są myślniki i podkreślenia.", "kube_add_billing_anti_affinity_coming_soon_message_title": "Ceny miesięczne", - "kube_add_billing_anti_affinity_coming_soon_message_description": "Ceny miesięczne będą dostępne wkrótce, wraz z uruchomieniem Saving Plans." + "kube_add_billing_anti_affinity_coming_soon_message_description": "Ceny miesięczne będą dostępne wkrótce, wraz z uruchomieniem Saving Plans.", + "kubernetes_add_version_and_upgrade_policy_title": "Wybierz pomocniczą wersję Kubernetesa i wybraną politykę bezpieczeństwa", + "kube_update_policy_picker_documentation_text": "Dowiedz się więcej o zasadach bezpieczeństwa Managed Kubernetes Service.", + "kube_update_policy_picker_documentation_link": "Zapoznaj się z dokumentacją", + "kubernetes_add_update_policy_title": "Wybierz politykę bezpieczeństwa", + "kubernetes_select_version_title": "Wybierz wersję" } diff --git a/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_pt_PT.json b/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_pt_PT.json index ffee054da6aa..02c6196752e1 100644 --- a/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_pt_PT.json +++ b/packages/manager/apps/pci-kubernetes/public/translations/add/Messages_pt_PT.json @@ -38,5 +38,10 @@ "kube_add_billing_auto_scaling_monthly_warning": "Atenção: ativará simultaneamente o autoscaling e o tarifário mensal para este nodepool. Todas as criações de nós através do autoscaling implicarão a faturação imediata de um nó em pro rata do tempo restante no mês em curso. Recomendamos que evite esta combinação se antecipar que o tamanho do seu nodepool seja frequentemente reduzido.", "kube_add_node_pool_name_input_pattern_validation_error": "O nome deve ter pelo menos dois caracteres, começar com um carácter alfabético, acabar por um caráter alfanumérico e os únicos caracteres especiais autorizados são os traços e os underscores.", "kube_add_billing_anti_affinity_coming_soon_message_title": "Preços mensais", - "kube_add_billing_anti_affinity_coming_soon_message_description": "Os preços mensais estarão disponíveis em breve com a chegada dos Saving Plans." + "kube_add_billing_anti_affinity_coming_soon_message_description": "Os preços mensais estarão disponíveis em breve com a chegada dos Saving Plans.", + "kubernetes_add_version_and_upgrade_policy_title": "Selecione a versão menor de Kubernetes e a política de segurança desejada", + "kube_update_policy_picker_documentation_text": "Saber mais sobre as políticas de segurança do Managed Kubernetes Service.", + "kube_update_policy_picker_documentation_link": "Consulte a documentação", + "kubernetes_add_update_policy_title": "Selecione a política de segurança", + "kubernetes_select_version_title": "Selecione uma versão" } diff --git a/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_de_DE.json b/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_de_DE.json index 28d1ea407db5..703b3606ea56 100644 --- a/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_de_DE.json +++ b/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_de_DE.json @@ -1,4 +1,4 @@ { "pci_project_versions_list_version": "Version {{ version }}", - "pci_project_versions_recommended_version": "Empfohlene Version" + "pci_project_versions_recommended_version": "Empfohlen" } diff --git a/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_en_GB.json b/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_en_GB.json index c0edcba48acc..1974a63d0de2 100644 --- a/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_en_GB.json +++ b/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_en_GB.json @@ -1,4 +1,4 @@ { "pci_project_versions_list_version": "Version {{ version }}", - "pci_project_versions_recommended_version": "Recommended version" + "pci_project_versions_recommended_version": "Recommended" } diff --git a/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_es_ES.json b/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_es_ES.json index 86874f609dea..d8bebaf0ef01 100644 --- a/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_es_ES.json +++ b/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_es_ES.json @@ -1,4 +1,4 @@ { "pci_project_versions_list_version": "Versión {{ version }}", - "pci_project_versions_recommended_version": "Versión recomendada" + "pci_project_versions_recommended_version": "Recomendada" } diff --git a/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_fr_CA.json b/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_fr_CA.json index 6b53861990e9..5644323009ed 100644 --- a/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_fr_CA.json +++ b/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_fr_CA.json @@ -1,4 +1,4 @@ { "pci_project_versions_list_version": "Version {{ version }}", - "pci_project_versions_recommended_version": "Version recommandée" + "pci_project_versions_recommended_version": "Recommandée" } diff --git a/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_fr_FR.json b/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_fr_FR.json index 6b53861990e9..5644323009ed 100644 --- a/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_fr_FR.json +++ b/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_fr_FR.json @@ -1,4 +1,4 @@ { "pci_project_versions_list_version": "Version {{ version }}", - "pci_project_versions_recommended_version": "Version recommandée" + "pci_project_versions_recommended_version": "Recommandée" } diff --git a/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_it_IT.json b/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_it_IT.json index 526a3da0e1fb..112de80e75c1 100644 --- a/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_it_IT.json +++ b/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_it_IT.json @@ -1,4 +1,4 @@ { "pci_project_versions_list_version": "Versione {{ version }}", - "pci_project_versions_recommended_version": "Versione consigliata" + "pci_project_versions_recommended_version": "Consigliata" } diff --git a/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_pl_PL.json b/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_pl_PL.json index efbed1b3ba6e..6f1de631b1e1 100644 --- a/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_pl_PL.json +++ b/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_pl_PL.json @@ -1,4 +1,4 @@ { "pci_project_versions_list_version": "Wersja {{ version }}", - "pci_project_versions_recommended_version": "Zalecana wersja" + "pci_project_versions_recommended_version": "Zalecane" } diff --git a/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_pt_PT.json b/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_pt_PT.json index a5049d87406d..a1b601111490 100644 --- a/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_pt_PT.json +++ b/packages/manager/apps/pci-kubernetes/public/translations/versions/Messages_pt_PT.json @@ -1,4 +1,4 @@ { "pci_project_versions_list_version": "Versão {{ version }}", - "pci_project_versions_recommended_version": "Versão recomendada" + "pci_project_versions_recommended_version": "Recomendada" } diff --git a/packages/manager/apps/pci-kubernetes/src/api/data/kubernetes.ts b/packages/manager/apps/pci-kubernetes/src/api/data/kubernetes.ts index 0770aa4c9de8..3302ba0ce48d 100644 --- a/packages/manager/apps/pci-kubernetes/src/api/data/kubernetes.ts +++ b/packages/manager/apps/pci-kubernetes/src/api/data/kubernetes.ts @@ -22,6 +22,7 @@ export interface KubeClusterCreationParams { name: string; region: string; version: string; + updatePolicy: string; nodepool: { antiAffinity: boolean; autoscale: boolean; diff --git a/packages/manager/apps/pci-kubernetes/src/components/VersionSelector.component.tsx b/packages/manager/apps/pci-kubernetes/src/components/VersionSelector.component.tsx deleted file mode 100644 index 69bbe2fb2e1c..000000000000 --- a/packages/manager/apps/pci-kubernetes/src/components/VersionSelector.component.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { useState } from 'react'; -import clsx from 'clsx'; -import { - OsdsChip, - OsdsSpinner, - OsdsText, - OsdsTile, -} from '@ovhcloud/ods-components/react'; -import { - ODS_CHIP_SIZE, - ODS_SPINNER_SIZE, - ODS_TEXT_LEVEL, - ODS_TEXT_SIZE, -} from '@ovhcloud/ods-components'; -import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; -import { useTranslation } from 'react-i18next'; -import { useGetCloudSchema } from '@/api/hooks/useCloud'; - -export const tileClass = - 'cursor-pointer border-[--ods-color-blue-100] hover:bg-[--ods-color-blue-100] hover:border-[--ods-color-blue-600]'; - -export const selectedTileClass = - 'font-bold bg-[--ods-color-blue-100] border-[--ods-color-blue-600]'; - -export interface VersionSelectorProps { - onSelectVersion: (version: string) => void; -} - -export function VersionSelector({ - onSelectVersion, -}: Readonly) { - const { t } = useTranslation('versions'); - const { data: schema, isPending } = useGetCloudSchema(); - const [selectedVersion, setSelectedVersion] = useState(''); - const versions = schema?.models['cloud.kube.VersionEnum'].enum || []; - const lastVersion = [...versions].pop(); - - const selectVersion = (version: string) => { - if (version) { - setSelectedVersion(version); - onSelectVersion(version); - } - }; - - if (isPending) { - return ; - } - - return ( -
- {versions?.map((version) => ( - selectVersion(version)} - > - - {t('pci_project_versions_list_version', { version })} - {version === lastVersion && ( - - {t('pci_project_versions_recommended_version')} - - )} - - - ))} -
- ); -} diff --git a/packages/manager/apps/pci-kubernetes/src/constants.ts b/packages/manager/apps/pci-kubernetes/src/constants.ts index 1b18b0a6c918..db87fe18f583 100644 --- a/packages/manager/apps/pci-kubernetes/src/constants.ts +++ b/packages/manager/apps/pci-kubernetes/src/constants.ts @@ -61,9 +61,9 @@ export const PROCESSING_STATUS = [ export const KUBE_INSTALLING_STATUS = 'INSTALLING'; export const UPGRADE_POLICIES = [ - 'NEVER_UPDATE', - 'MINIMAL_DOWNTIME', 'ALWAYS_UPDATE', + 'MINIMAL_DOWNTIME', + 'NEVER_UPDATE', ]; export const UPDATE_STRATEGY = { diff --git a/packages/manager/apps/pci-kubernetes/src/pages/new/New.page.tsx b/packages/manager/apps/pci-kubernetes/src/pages/new/New.page.tsx index 20ae7f9ecf30..f7e49f698ddc 100644 --- a/packages/manager/apps/pci-kubernetes/src/pages/new/New.page.tsx +++ b/packages/manager/apps/pci-kubernetes/src/pages/new/New.page.tsx @@ -30,7 +30,7 @@ import { } from '@ovh-ux/manager-react-components'; import { useClusterCreationStepper } from './useCusterCreationStepper'; import { LocationStep } from './steps/LocationStep.component'; -import { VersionStep } from './steps/VersionStep.component'; +import { VersionAndUpdatePolicyStep } from './steps/VersionAndUpdatePolicyStep.component'; import { NetworkStep } from './steps/NetworkStep.component'; import { NodeTypeStep } from './steps/NodeTypeStep.component'; import { NodeSizeStep } from './steps/NodeSizeStep.component'; @@ -168,14 +168,14 @@ export default function NewPage() { - @@ -259,6 +259,7 @@ export default function NewPage() { name: stepper.form.clusterName, region: stepper.form.region?.name, version: stepper.form.version, + updatePolicy: stepper.form.updatePolicy, nodepool: { antiAffinity: stepper.form.antiAffinity, autoscale: stepper.form.scaling?.isAutoscale, diff --git a/packages/manager/apps/pci-kubernetes/src/pages/new/steps/UpdatePolicySelector.component.spec.tsx b/packages/manager/apps/pci-kubernetes/src/pages/new/steps/UpdatePolicySelector.component.spec.tsx new file mode 100644 index 000000000000..9a81314764da --- /dev/null +++ b/packages/manager/apps/pci-kubernetes/src/pages/new/steps/UpdatePolicySelector.component.spec.tsx @@ -0,0 +1,87 @@ +import { describe, it, vi, expect, beforeEach, Mock } from 'vitest'; +import { render, fireEvent, waitFor } from '@testing-library/react'; +import { + ShellContext, + ShellContextType, +} from '@ovh-ux/manager-react-shell-client'; +import { + UpdatePolicySelector, + selectedTileClass, +} from './UpdatePolicySelector.component'; + +import { UPGRADE_POLICIES } from '@/constants'; +import { UpdatePolicy } from '@/types'; + +let setPolicyMock: Mock; + +describe('UpgradePolicyTileSelector', () => { + beforeEach(() => { + setPolicyMock = vi.fn(); + }); + + // Mock ShellContext + const mockShellContextValue = { + environment: { + getUser: () => ({ ovhSubsidiary: 'en' }), + }, + } as ShellContextType; + + it('renders correctly ', () => { + const { container } = render( + + + , + ); + + expect(container).toBeInTheDocument(); + }); + + it('displays the correct number of policy tiles', () => { + const { getAllByRole } = render( + + + , + ); + + const tiles = getAllByRole('button'); + expect(tiles.length).toBe(UPGRADE_POLICIES.length); + }); + + it('calls setPolicy with the correct argument when a tile is clicked', async () => { + const { getByTestId } = render( + + + , + ); + + const tile = getByTestId(UpdatePolicy.MinimalDowntime); + fireEvent.click(tile); + + await waitFor(() => { + expect(setPolicyMock).toHaveBeenCalledWith(UpdatePolicy.MinimalDowntime); + }); + }); + + it('applies the correct class to the selected tile', () => { + const { getByTestId } = render( + + + , + ); + + const selectedTile = getByTestId(UpdatePolicy.AlwaysUpdate); + expect(selectedTile).toHaveClass(selectedTileClass); + }); +}); diff --git a/packages/manager/apps/pci-kubernetes/src/pages/new/steps/UpdatePolicySelector.component.tsx b/packages/manager/apps/pci-kubernetes/src/pages/new/steps/UpdatePolicySelector.component.tsx new file mode 100644 index 000000000000..026743740d3c --- /dev/null +++ b/packages/manager/apps/pci-kubernetes/src/pages/new/steps/UpdatePolicySelector.component.tsx @@ -0,0 +1,124 @@ +import { + OsdsFormField, + OsdsText, + OsdsTile, + OsdsLink, + OsdsIcon, + OsdsChip, +} from '@ovhcloud/ods-components/react'; +import { OdsHTMLAnchorElementTarget } from '@ovhcloud/ods-common-core'; +import { ShellContext } from '@ovh-ux/manager-react-shell-client'; +import { + ODS_CHIP_SIZE, + ODS_ICON_NAME, + ODS_ICON_SIZE, + ODS_TEXT_LEVEL, + ODS_TEXT_SIZE, +} from '@ovhcloud/ods-components'; +import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import clsx from 'clsx'; +import { useTranslation } from 'react-i18next'; +import { useContext } from 'react'; +import { UPGRADE_POLICIES } from '@/constants'; + +import { DOCUMENTATION_LINK } from '@/pages/upgrade-policy/UpgradePolicy.constant'; +import { UpdatePolicy } from '@/types'; + +interface UpdateSelectorProps { + onPolicyChange: (policy: UpdatePolicy) => void; + policy: UpdatePolicy; +} +export const tileClass = + 'cursor-pointer border-[--ods-color-blue-100] hover:bg-[--ods-color-blue-100] hover:border-[--ods-color-blue-600]'; + +export const selectedTileClass = + 'font-bold bg-[--ods-color-blue-100] border-[--ods-color-blue-600]'; + +export function UpdatePolicySelector({ + onPolicyChange, + policy: selectPolicy, +}: Readonly) { + const { t } = useTranslation(['add', 'service']); + const shell = useContext(ShellContext); + + return ( + <> + + + {t('kubernetes_add_update_policy_title', { ns: 'add' })} + + +
+ + {t('kube_update_policy_picker_documentation_text', { ns: 'add' })} + {' '} + + {t('kube_update_policy_picker_documentation_link', { ns: 'add' })} + + +
+ +
+ {UPGRADE_POLICIES.map((policy: UpdatePolicy) => ( + onPolicyChange(policy)} + > +
+
+ + {t(`service:kube_service_upgrade_policy_${policy}`)} + {/** add chip if update policy equal last version */} + + {policy === UpdatePolicy.AlwaysUpdate && ( + + {t('versions:pci_project_versions_recommended_version')} + + )} +
+ + + {t(`kube_service_upgrade_policy_description_${policy}`, { + ns: 'service', + })} + +
+
+ ))} +
+ + ); +} diff --git a/packages/manager/apps/pci-kubernetes/src/pages/new/steps/VersionAndUpdatePolicyStep.component.tsx b/packages/manager/apps/pci-kubernetes/src/pages/new/steps/VersionAndUpdatePolicyStep.component.tsx new file mode 100644 index 000000000000..74358cb15fc7 --- /dev/null +++ b/packages/manager/apps/pci-kubernetes/src/pages/new/steps/VersionAndUpdatePolicyStep.component.tsx @@ -0,0 +1,81 @@ +import { useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import clsx from 'clsx'; +import { OsdsButton, OsdsText, OsdsTile } from '@ovhcloud/ods-components/react'; +import { + ODS_BUTTON_SIZE, + ODS_TEXT_LEVEL, + ODS_TEXT_SIZE, +} from '@ovhcloud/ods-components'; +import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import { StepState } from '../useStep'; +import { VersionSelector } from './VersionSelector.component'; +import { UpdatePolicySelector } from './UpdatePolicySelector.component'; +import { UpdatePolicy } from '@/types'; + +export interface VersionStepProps { + onSubmit: (version: string, policy: string) => void; + step: StepState; +} + +export function VersionAndUpdatePolicyStep({ + onSubmit, + step, +}: Readonly) { + const { t } = useTranslation(['stepper', 'versions', 'service']); + const [version, setVersion] = useState(null); + const [policy, setPolicy] = useState(UpdatePolicy.AlwaysUpdate); + return ( + <> +
+ + +
+ + {step.isLocked && version && ( +
+ + + {t('pci_project_versions_list_version', { + version, + ns: 'versions', + })} + + + + + {t(`kube_service_upgrade_policy_${policy}`, { + ns: 'service', + })} + + +
+ )} + {!step.isLocked && ( + version && onSubmit(version, policy)} + > + {t('common_stepper_next_button_label', { ns: 'stepper' })} + + )} + + ); +} diff --git a/packages/manager/apps/pci-kubernetes/src/pages/new/steps/VersionSelector.component.spec.tsx b/packages/manager/apps/pci-kubernetes/src/pages/new/steps/VersionSelector.component.spec.tsx new file mode 100644 index 000000000000..32ea92cfb3d5 --- /dev/null +++ b/packages/manager/apps/pci-kubernetes/src/pages/new/steps/VersionSelector.component.spec.tsx @@ -0,0 +1,130 @@ +// versionSelector.test.ts +import { render, screen, fireEvent, waitFor } from '@testing-library/react'; +import { + QueryObserverBaseResult, + QueryObserverSuccessResult, +} from '@tanstack/react-query'; +import { describe, it, vi, expect, beforeEach, Mock } from 'vitest'; +import { useEffect, useState } from 'react'; +import { + OdsSelectValueChangeEventDetail, + OsdsSelect, +} from '@ovhcloud/ods-components'; +import { VersionSelector } from './VersionSelector.component'; +import { useGetCloudSchema } from '@/api/hooks/useCloud'; + +const TestComponent = () => { + const [version, setVersion] = useState(''); + + useEffect(() => { + // Simuler une mise à jour de la version après un certain délai + const timeout = setTimeout(() => { + setVersion('2.0.0'); + }, 1000); + + return () => clearTimeout(timeout); + }, []); + + return ( + + ); +}; + +vi.mock('@/api/hooks/useCloud', () => ({ + useGetCloudSchema: vi.fn(), +})); + +const mockUseGetCloudSchema = (useGetCloudSchema as unknown) as Mock; + +const initQuery = { + data: { + models: { + 'cloud.kube.VersionEnum': { + enum: ['v1.21.0', 'v1.22.0', 'v1.23.0'], + }, + }, + }, + isPending: false, + isFetching: false, + isError: false, + isSuccess: true, + status: 'success' as const, + error: (undefined as unknown) as Error, +} as QueryObserverBaseResult | QueryObserverSuccessResult; + +beforeEach(() => { + mockUseGetCloudSchema.mockReturnValue(initQuery); +}); + +describe('VersionSelector', () => { + it('should call onSelectVersion with the selected version', async () => { + const onSelectVersion = vi.fn(); + render( + , + ); + await waitFor(() => { + expect(onSelectVersion).toHaveBeenCalledWith('v1.23.0'); + }); + // + }); + it('renders without errors and selects last version by default', async () => { + render(); + expect(screen.getByTestId('version-selector-select')).toBeInTheDocument(); + const select = screen.getByTestId('version-selector-select'); + expect(select).toHaveValue('v1.23.0'); + }); + + it('selects a version based on the versionSelected prop', () => { + render( + , + ); + + const select = screen.getByTestId('version-selector-select'); + expect(select).toHaveValue('v1.22.0'); + }); + + // Test case to check if the onSelectVersion callback is called when a new version is selected + it('calls onSelectVersion callback when a new version is selected', async () => { + const onSelectVersionMock = vi.fn(); + render( + , + ); + + const select = (screen.getByTestId( + 'version-selector-select', + ) as unknown) as OsdsSelect; + select.odsValueChange.emit({ + value: 'v1.22.0', + } as OdsSelectValueChangeEventDetail); + + await waitFor(() => { + expect(onSelectVersionMock).toHaveBeenCalledWith('v1.22.0'); + }); + }); + + // Test case to check if a spinner is displayed when isPending is true + it('displays a spinner when isPending is true', () => { + mockUseGetCloudSchema.mockReturnValue({ + ...initQuery, + data: undefined, + isPending: true, + }); + render(); + + expect(screen.getByTestId('version-selector-spinner')).toBeInTheDocument(); + }); + + // Test case to check if there is no select element when there are no versions + it('does not render select element when versions array is empty', () => { + mockUseGetCloudSchema.mockReturnValue(initQuery); + + render(); + + expect( + screen.queryByTestId('version-selector-select'), + ).not.toBeInTheDocument(); + }); +}); diff --git a/packages/manager/apps/pci-kubernetes/src/pages/new/steps/VersionSelector.component.tsx b/packages/manager/apps/pci-kubernetes/src/pages/new/steps/VersionSelector.component.tsx new file mode 100644 index 000000000000..8b1bd3b98643 --- /dev/null +++ b/packages/manager/apps/pci-kubernetes/src/pages/new/steps/VersionSelector.component.tsx @@ -0,0 +1,100 @@ +import { useEffect, useMemo } from 'react'; +import { + OsdsSelectOption, + OsdsSpinner, + OsdsSelect, + OsdsChip, + OsdsText, + OsdsFormField, +} from '@ovhcloud/ods-components/react'; +import { + ODS_CHIP_SIZE, + ODS_SELECT_SIZE, + ODS_SPINNER_SIZE, +} from '@ovhcloud/ods-components'; +import { + ODS_THEME_COLOR_INTENT, + ODS_THEME_TYPOGRAPHY_LEVEL, +} from '@ovhcloud/ods-common-theming'; +import { useTranslation } from 'react-i18next'; +import { useGetCloudSchema } from '@/api/hooks/useCloud'; + +export interface VersionSelectorProps { + onSelectVersion: (version: string) => void; + versionSelected: string; +} + +export function VersionSelector({ + versionSelected, + onSelectVersion, +}: Readonly) { + const { t } = useTranslation(); + const { data: schema, isPending } = useGetCloudSchema(); + const versions = schema?.models['cloud.kube.VersionEnum'].enum || []; + + const reverseVersion = useMemo(() => [...versions].reverse(), [versions]); + const [lastVersion] = reverseVersion; + + useEffect(() => { + if (!isPending && !versionSelected) { + onSelectVersion(lastVersion); + } + }, [versionSelected, isPending]); + + if (isPending) { + return ( + + ); + } + + return ( +
+ {versionSelected && ( + + + {t('add:kubernetes_select_version_title')} + + { + if (typeof detail.value === 'string') { + onSelectVersion(detail.value); + } + }} + > + {reverseVersion.map((version) => ( + +
+ {`${t('versions:pci_project_versions_list_version', { + version, + })} `} + {version === lastVersion && ( + + {t('versions:pci_project_versions_recommended_version')} + + )} +
+
+ ))} +
+
+ )} +
+ ); +} diff --git a/packages/manager/apps/pci-kubernetes/src/pages/new/steps/VersionStep.component.tsx b/packages/manager/apps/pci-kubernetes/src/pages/new/steps/VersionStep.component.tsx deleted file mode 100644 index cd114d38b2cb..000000000000 --- a/packages/manager/apps/pci-kubernetes/src/pages/new/steps/VersionStep.component.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { OsdsButton, OsdsText, OsdsTile } from '@ovhcloud/ods-components/react'; -import { - ODS_BUTTON_SIZE, - ODS_TEXT_LEVEL, - ODS_TEXT_SIZE, -} from '@ovhcloud/ods-components'; -import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; -import clsx from 'clsx'; -import { StepState } from '../useStep'; -import { VersionSelector } from '@/components/VersionSelector.component'; - -export interface VersionStepProps { - onSubmit: (version: string) => void; - step: StepState; -} - -export function VersionStep({ onSubmit, step }: Readonly) { - const { t: tStepper } = useTranslation('stepper'); - const { t: tVersion } = useTranslation('versions'); - const [version, setVersion] = useState(''); - return ( - <> -
- -
- {step.isLocked && version && ( - - - {tVersion('pci_project_versions_list_version', { version })} - - - )} - {!step.isLocked && ( - version && onSubmit(version)} - > - {tStepper('common_stepper_next_button_label')} - - )} - - ); -} diff --git a/packages/manager/apps/pci-kubernetes/src/pages/new/useCusterCreationStepper.ts b/packages/manager/apps/pci-kubernetes/src/pages/new/useCusterCreationStepper.ts index 11c6f5f24816..db72f0d3d82d 100644 --- a/packages/manager/apps/pci-kubernetes/src/pages/new/useCusterCreationStepper.ts +++ b/packages/manager/apps/pci-kubernetes/src/pages/new/useCusterCreationStepper.ts @@ -3,10 +3,12 @@ import { KubeFlavor, TLocalisation } from '@ovh-ux/manager-pci-common'; import { useStep } from './useStep'; import { AutoscalingState } from '@/components/Autoscaling.component'; import { TNetworkFormState } from './steps/NetworkClusterStep.component'; +import { UpdatePolicy } from '@/types'; export type TClusterCreationForm = { region: TLocalisation; version: string; + updatePolicy: UpdatePolicy; network: TNetworkFormState; flavor: KubeFlavor; scaling: AutoscalingState; @@ -25,6 +27,7 @@ export function useClusterCreationStepper() { const [form, setForm] = useState({ region: null, version: '', + updatePolicy: null, network: null, flavor: null, scaling: null, @@ -78,10 +81,11 @@ export function useClusterCreationStepper() { clusterNameStep, ].forEach(stepReset); }, - submit: (version: string) => { + submit: (version: string, updatePolicy: UpdatePolicy) => { setForm((f) => ({ ...f, version, + updatePolicy, })); versionStep.check(); versionStep.lock(); diff --git a/packages/manager/apps/pci-kubernetes/src/pages/upgrade-policy/UpgradePolicy.constant.tsx b/packages/manager/apps/pci-kubernetes/src/pages/upgrade-policy/UpgradePolicy.constant.tsx new file mode 100644 index 000000000000..edfa7e082f1f --- /dev/null +++ b/packages/manager/apps/pci-kubernetes/src/pages/upgrade-policy/UpgradePolicy.constant.tsx @@ -0,0 +1,50 @@ +export const DOCUMENTATION_LINK = { + DEFAULT: + 'https://help.ovhcloud.com/csm/en-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0049649', + ASIA: + 'https://help.ovhcloud.com/csm/asia-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0049640', + AU: + 'https://help.ovhcloud.com/csm/en-au-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0049641', + CA: + 'https://help.ovhcloud.com/csm/en-ca-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0049644', + DE: + 'https://help.ovhcloud.com/csm/de-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0054909', + ES: + 'https://help.ovhcloud.com/csm/es-es-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0054906', + FR: + 'https://help.ovhcloud.com/csm/fr-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0054907', + GB: + 'https://help.ovhcloud.com/csm/en-gb-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0049655', + IE: + 'https://help.ovhcloud.com/csm/en-ie-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0049651', + IN: + 'https://help.ovhcloud.com/csm/asia-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0049640', + IT: + 'https://help.ovhcloud.com/csm/it-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0054910', + MA: + 'https://help.ovhcloud.com/csm/fr-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0054907', + NL: + 'https://help.ovhcloud.com/csm/en-nl-documentation-public-cloud?id=kb_browse_cat&kb_id=574a8325551974502d4c6e78b7421938', + PL: + 'https://help.ovhcloud.com/csm/pl-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0054905', + PT: + 'https://help.ovhcloud.com/csm/pt-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0054912', + QB: + 'https://help.ovhcloud.com/csm/fr-ca-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0054903', + SG: + 'https://help.ovhcloud.com/csm/en-sg-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0037177', + SN: + 'https://help.ovhcloud.com/csm/fr-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0054907', + TN: + 'https://help.ovhcloud.com/csm/fr-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0054907', + WE: + 'https://help.ovhcloud.com/csm/en-ie-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0049651', + WS: + 'https://help.ovhcloud.com/csm/es-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0054908', + WW: + 'https://help.ovhcloud.com/csm/en-public-cloud-kubernetes-change-security-update?id=kb_article_view&sysparm_article=KB0049649', +}; + +export default { + DOCUMENTATION_LINK, +}; diff --git a/packages/manager/apps/pci-kubernetes/src/types/index.ts b/packages/manager/apps/pci-kubernetes/src/types/index.ts index 779666b56518..6ccb9dcd10d6 100644 --- a/packages/manager/apps/pci-kubernetes/src/types/index.ts +++ b/packages/manager/apps/pci-kubernetes/src/types/index.ts @@ -40,3 +40,9 @@ export type TNetworkConfiguration = { privateNetworkRoutingAsDefault: boolean; defaultVrackGateway: string; }; + +export enum UpdatePolicy { + NeverUpdate = 'NEVER_UPDATE', + MinimalDowntime = 'MINIMAL_DOWNTIME', + AlwaysUpdate = 'ALWAYS_UPDATE', +} From fb553af39c9c9cc214ad292f6373b775fc795a70 Mon Sep 17 00:00:00 2001 From: Yoann Fievez Date: Thu, 10 Oct 2024 16:31:09 +0200 Subject: [PATCH 04/11] test(pci-gateway): add tests to increase coverage (#12158) ref: DTCORE-2347 Signed-off-by: Yoann Fievez --- .../manager/apps/pci-gateway/.eslintrc.cjs | 4 +- .../src/api/hooks/useCatalog.spec.tsx | 53 ++++++++ .../src/api/hooks/useInactiveRegions.spec.tsx | 44 ++++++ .../src/api/hooks/useNetworks.spec.tsx | 126 ++++++++++++++++++ .../src/api/hooks/useSubnets.spec.tsx | 41 ++++++ .../list/Actions.component.spec.tsx | 65 +++++++++ .../src/components/list/Actions.component.tsx | 8 +- .../components/list/PrivateIPs.component.tsx | 2 +- .../PrivateNetworkButton.component.spec.tsx | 49 +++++++ .../list/PrivateNetworkButton.component.tsx | 3 +- .../src/hooks/useDatagridColumn.spec.tsx | 102 ++++++++++++++ .../src/hooks/useDatagridColumn.tsx | 6 +- .../manager/apps/pci-gateway/src/layout.ts | 7 - .../src/pages/add/AddGateway.page.tsx | 4 +- .../src/pages/add/LocationStep.tsx | 4 +- .../pci-gateway/src/pages/add/NetworkStep.tsx | 18 +-- .../src/pages/add/SubnetModal.spec.tsx | 98 ++++++++++++++ .../pci-gateway/src/pages/add/SubnetModal.tsx | 4 +- .../src/pages/delete/DeleteGateway.page.tsx | 2 +- .../src/pages/edit/EditGateway.page.spec.tsx | 91 +++++++++++++ .../src/pages/edit/EditGateway.page.tsx | 13 +- .../src/pages/list/List.page.spec.tsx | 59 ++++++++ .../pci-gateway/src/pages/list/List.page.tsx | 14 +- .../pci-gateway/src/pages/list/ListGuard.tsx | 2 +- .../pages/onboarding/OnBoarding.page.spec.tsx | 50 +++++++ .../src/pages/onboarding/OnBoardingGuard.tsx | 2 +- .../manager/apps/pci-gateway/vitest.config.js | 2 + 27 files changed, 825 insertions(+), 48 deletions(-) create mode 100644 packages/manager/apps/pci-gateway/src/api/hooks/useCatalog.spec.tsx create mode 100644 packages/manager/apps/pci-gateway/src/api/hooks/useInactiveRegions.spec.tsx create mode 100644 packages/manager/apps/pci-gateway/src/api/hooks/useNetworks.spec.tsx create mode 100644 packages/manager/apps/pci-gateway/src/api/hooks/useSubnets.spec.tsx create mode 100644 packages/manager/apps/pci-gateway/src/components/list/Actions.component.spec.tsx create mode 100644 packages/manager/apps/pci-gateway/src/components/list/PrivateNetworkButton.component.spec.tsx create mode 100644 packages/manager/apps/pci-gateway/src/hooks/useDatagridColumn.spec.tsx delete mode 100644 packages/manager/apps/pci-gateway/src/layout.ts create mode 100644 packages/manager/apps/pci-gateway/src/pages/add/SubnetModal.spec.tsx create mode 100644 packages/manager/apps/pci-gateway/src/pages/edit/EditGateway.page.spec.tsx create mode 100644 packages/manager/apps/pci-gateway/src/pages/list/List.page.spec.tsx create mode 100644 packages/manager/apps/pci-gateway/src/pages/onboarding/OnBoarding.page.spec.tsx diff --git a/packages/manager/apps/pci-gateway/.eslintrc.cjs b/packages/manager/apps/pci-gateway/.eslintrc.cjs index 98b36a5ae973..0bf6400e914d 100644 --- a/packages/manager/apps/pci-gateway/.eslintrc.cjs +++ b/packages/manager/apps/pci-gateway/.eslintrc.cjs @@ -15,7 +15,9 @@ module.exports = { rules: { 'import/extensions': 'off', '@typescript-eslint/no-non-null-assertion': 'off', - 'arrow-body-style': ["error", "as-needed"], + 'arrow-body-style': ['error', 'as-needed'], 'prefer-const': 'error', + 'react/jsx-curly-brace-presence': ['error', { props: 'never', children: 'never' }], + 'react/jsx-boolean-value': ['error', 'never'], }, }; diff --git a/packages/manager/apps/pci-gateway/src/api/hooks/useCatalog.spec.tsx b/packages/manager/apps/pci-gateway/src/api/hooks/useCatalog.spec.tsx new file mode 100644 index 000000000000..16360fd49d32 --- /dev/null +++ b/packages/manager/apps/pci-gateway/src/api/hooks/useCatalog.spec.tsx @@ -0,0 +1,53 @@ +import { describe, it, vi } from 'vitest'; +import { renderHook, waitFor } from '@testing-library/react'; +import * as useMeModule from '@ovh-ux/manager-react-components'; +import { IMe } from '@ovh-ux/manager-react-components'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { getCatalog, TCatalog } from '@ovh-ux/manager-pci-common'; +import { useCatalog } from './useCatalog'; + +vi.mock('@ovh-ux/manager-pci-common', () => ({ + getCatalog: vi.fn().mockResolvedValue({}), + getCatalogUrl: vi.fn().mockReturnValue('catalogUrl'), +})); + +const client = new QueryClient(); +const wrapper = ({ children }) => ( + {children} +); + +describe('useCatalog', () => { + it('useCatalog returns catalog when user is present', async ({ expect }) => { + const mockCatalog = ({ id: 'testCatalog' } as unknown) as TCatalog; + const useMeSpy = vi.spyOn(useMeModule, 'useMe'); + const iMe: IMe = { + ovhSubsidiary: 'subsidiary', + currency: { + code: 'USD', + }, + }; + useMeSpy.mockReturnValue({ me: iMe }); + vi.mocked(getCatalog).mockResolvedValue(mockCatalog); + + const { result } = renderHook(() => useCatalog(), { wrapper }); + waitFor(() => { + expect(result.current.data).toEqual(mockCatalog); + }); + }); + + it('useCatalog returns error when fetching catalog fails', async ({ + expect, + }) => { + const mockError = new Error('Failed to fetch catalog'); + const useMeSpy = vi.spyOn(useMeModule, 'useMe'); + + useMeSpy.mockReturnValue({ me: { ovhSubsidiary: 'subsidiary' } as IMe }); + vi.mocked(getCatalog).mockRejectedValue(mockError); + + const { result } = renderHook(() => useCatalog(), { wrapper }); + + waitFor(() => { + expect(result.current.error).toEqual(mockError); + }); + }); +}); diff --git a/packages/manager/apps/pci-gateway/src/api/hooks/useInactiveRegions.spec.tsx b/packages/manager/apps/pci-gateway/src/api/hooks/useInactiveRegions.spec.tsx new file mode 100644 index 000000000000..8b9bf693e804 --- /dev/null +++ b/packages/manager/apps/pci-gateway/src/api/hooks/useInactiveRegions.spec.tsx @@ -0,0 +1,44 @@ +import { describe, it, vi } from 'vitest'; +import { renderHook, waitFor } from '@testing-library/react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { useInactiveRegions } from './useInactiveRegions'; +import { getInactiveRegions, TInactiveRegion } from '@/api/data/regions'; + +const client = new QueryClient(); +const wrapper = ({ children }) => ( + {children} +); + +vi.mock('@/api/data/regions', () => ({ + getInactiveRegions: vi.fn().mockResolvedValue([]), + getInactiveRegionsUrl: vi.fn().mockReturnValue('inactiveRegionsUrl'), +})); + +describe('useInactiveRegions', () => { + it('useInactiveRegions returns inactive regions when project id is present', async () => { + const mockInactiveRegions = ([ + { id: 'region1' }, + { id: 'region2' }, + ] as unknown) as TInactiveRegion[]; + + vi.mocked(getInactiveRegions).mockResolvedValue(mockInactiveRegions); + + const { result } = renderHook(() => useInactiveRegions('projectId'), { + wrapper, + }); + await waitFor(() => + expect(result.current.data).toEqual(mockInactiveRegions), + ); + }); + + it('useInactiveRegions returns error when fetching inactive regions fails', () => { + const mockError = new Error('Failed to fetch inactive regions'); + + vi.mocked(getInactiveRegions).mockRejectedValue(mockError); + + const { result } = renderHook(() => useInactiveRegions('projectId'), { + wrapper, + }); + waitFor(() => expect(result.current.error).toEqual(mockError)); + }); +}); diff --git a/packages/manager/apps/pci-gateway/src/api/hooks/useNetworks.spec.tsx b/packages/manager/apps/pci-gateway/src/api/hooks/useNetworks.spec.tsx new file mode 100644 index 000000000000..489f48eeeab0 --- /dev/null +++ b/packages/manager/apps/pci-gateway/src/api/hooks/useNetworks.spec.tsx @@ -0,0 +1,126 @@ +import { act, renderHook, waitFor } from '@testing-library/react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { describe, it, vi } from 'vitest'; +import { + TCreateNetworkWithGatewayParam, + useCreateNetworkWithGateway, + useNetworks, + usePrivateNetworks, +} from './useNetworks'; +import { + createNetworkWithGateway, + getNetworks, + getPrivateNetworks, + TNetwork, + TNewNetworkWithGateway, +} from '@/api/data/networks'; + +vi.mock('@/api/data/networks', () => ({ + getNetworks: vi.fn(), + getPrivateNetworks: vi.fn(), + getNetworksUrl: vi.fn(), + createNetworkWithGateway: vi.fn(), +})); + +const wrapper = ({ children }) => ( + + {children} + +); + +describe('useNetworks', () => { + it('returns data when projectId and regionName are provided', async () => { + vi.mocked(getNetworks).mockResolvedValueOnce([ + { id: '1', name: 'test' }, + ] as TNetwork[]); + const { result } = renderHook(() => useNetworks('test', 'test'), { + wrapper, + }); + await waitFor(() => + expect(result.current.data).toEqual([{ id: '1', name: 'test' }]), + ); + expect(getNetworks).toHaveBeenCalledWith('test', 'test'); + }); +}); + +describe('usePrivateNetworks', () => { + it('returns data when projectId and regionName are provided', async () => { + vi.mocked(getPrivateNetworks).mockResolvedValueOnce([ + { id: '1', name: 'test' }, + ] as TNetwork[]); + const { result } = renderHook(() => usePrivateNetworks('test', 'test'), { + wrapper, + }); + waitFor(() => + expect(result.current.data).toEqual([{ id: '1', name: 'test' }]), + ); + expect(getPrivateNetworks).toHaveBeenCalledWith('test', 'test'); + }); +}); + +describe('useCreateNetworkWithGateway', () => { + it('calls createNetworkWithGateway on mutation', async ({ expect }) => { + const params: TCreateNetworkWithGatewayParam = { + projectId: 'test', + regionName: 'test', + onError: vi.fn(), + onSuccess: vi.fn(), + }; + const { result } = renderHook(() => useCreateNetworkWithGateway(params), { + wrapper, + }); + const newNetwork = ({ + name: 'test', + description: 'test', + } as unknown) as TNewNetworkWithGateway; + vi.mocked(createNetworkWithGateway).mockResolvedValueOnce(newNetwork); + await act(() => result.current.createNetworkWithGateway(newNetwork)); + expect(createNetworkWithGateway).toHaveBeenCalledWith( + params.projectId, + params.regionName, + newNetwork, + ); + }); + + it('calls onSuccess when mutation is successful', async ({ expect }) => { + const onSuccess = vi.fn(); + const params: TCreateNetworkWithGatewayParam = { + projectId: 'test', + regionName: 'test', + onError: vi.fn(), + onSuccess, + }; + const { result } = renderHook(() => useCreateNetworkWithGateway(params), { + wrapper, + }); + const newNetwork = ({ + name: 'test', + description: 'test', + } as unknown) as TNewNetworkWithGateway; + vi.mocked(createNetworkWithGateway).mockResolvedValueOnce(newNetwork); + await act(() => result.current.createNetworkWithGateway(newNetwork)); + expect(onSuccess).toHaveBeenCalled(); + }); + + it('calls onError when mutation fails', async ({ expect }) => { + const onError = vi.fn(); + const params: TCreateNetworkWithGatewayParam = { + projectId: 'test', + regionName: 'test', + onError, + onSuccess: vi.fn(), + }; + const { result } = renderHook(() => useCreateNetworkWithGateway(params), { + wrapper, + }); + const newNetwork = ({ + name: 'test', + description: 'test', + } as unknown) as TNewNetworkWithGateway; + vi.mocked(createNetworkWithGateway).mockRejectedValueOnce( + new Error('error'), + ); + await act(() => result.current.createNetworkWithGateway(newNetwork)); + expect(onError).toHaveBeenCalled(); + }); +}); diff --git a/packages/manager/apps/pci-gateway/src/api/hooks/useSubnets.spec.tsx b/packages/manager/apps/pci-gateway/src/api/hooks/useSubnets.spec.tsx new file mode 100644 index 000000000000..8e5a975b337c --- /dev/null +++ b/packages/manager/apps/pci-gateway/src/api/hooks/useSubnets.spec.tsx @@ -0,0 +1,41 @@ +import { renderHook, waitFor } from '@testing-library/react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { describe, it, vi } from 'vitest'; +import { useSubnets } from './useSubnets'; +import { getSubnets, getSubnetsUrl, TSubnet } from '@/api/data/subnets'; + +vi.mock('@/api/data/subnets', () => ({ + getSubnets: vi.fn(), + getSubnetsUrl: vi.fn(), +})); + +const wrapper = ({ children }) => ( + + {children} + +); + +describe('useSubnets', () => { + it('returns empty array when networkId is "new"', async () => { + vi.mocked(getSubnetsUrl).mockReturnValue('mocked_subnetUrl'); + const { result } = renderHook(() => useSubnets('test', 'test', 'new'), { + wrapper, + }); + await waitFor(() => result.current.isSuccess); + expect(result.current.data).toEqual([]); + }); + + it('calls getSubnets when networkId is not "new"', async () => { + vi.mocked(getSubnetsUrl).mockReturnValue('mocked_subnetUrl'); + vi.mocked(getSubnets).mockResolvedValueOnce(([ + { id: '1', name: 'test' }, + ] as unknown) as TSubnet[]); + const { result } = renderHook(() => useSubnets('test', 'test', '1'), { + wrapper, + }); + await waitFor(() => + expect(result.current.data).toEqual([{ id: '1', name: 'test' }]), + ); + expect(getSubnets).toHaveBeenCalledWith('test', 'test', '1'); + }); +}); diff --git a/packages/manager/apps/pci-gateway/src/components/list/Actions.component.spec.tsx b/packages/manager/apps/pci-gateway/src/components/list/Actions.component.spec.tsx new file mode 100644 index 000000000000..8f1358a2eac2 --- /dev/null +++ b/packages/manager/apps/pci-gateway/src/components/list/Actions.component.spec.tsx @@ -0,0 +1,65 @@ +import { describe, it, vi } from 'vitest'; +import { render } from '@testing-library/react'; +import { + ShellContext, + ShellContextType, +} from '@ovh-ux/manager-react-shell-client'; +import { useHref } from 'react-router-dom'; +import Actions from './Actions.component'; +import { Gateway } from '@/interface'; + +vi.mock('react-router-dom'); + +const shellContext = { + shell: { + navigation: { + getURL: vi.fn().mockResolvedValue('mocked_url'), + }, + }, +}; + +const wrapper = ({ children }) => ( + + {children} + +); + +describe('Actions', () => { + it('renders without crashing', () => { + const { getByTestId } = render( + , + { wrapper }, + ); + const button = getByTestId('actions-hrefEdit'); + expect(button).toBeInTheDocument(); + }); + + it('navigates to correct URL on edit button click', async () => { + vi.mocked(useHref).mockReturnValue('hrefEdit'); + const { getByTestId } = render( + , + { wrapper }, + ); + const button = getByTestId('actions-hrefEdit'); + expect(button).toHaveAttribute('href', 'hrefEdit'); + }); + + it('navigates to correct URL on delete button click', async () => { + vi.mocked(useHref).mockReturnValue('hrefRemove'); + const { getByTestId } = render( + , + { wrapper }, + ); + const button = getByTestId('actions-hrefRemove'); + expect(button).toHaveAttribute('href', 'hrefRemove'); + }); +}); diff --git a/packages/manager/apps/pci-gateway/src/components/list/Actions.component.tsx b/packages/manager/apps/pci-gateway/src/components/list/Actions.component.tsx index 1393e97f3267..4e94f7ca795c 100644 --- a/packages/manager/apps/pci-gateway/src/components/list/Actions.component.tsx +++ b/packages/manager/apps/pci-gateway/src/components/list/Actions.component.tsx @@ -40,7 +40,7 @@ export default function Actions({ return ( {t('pci_projects_project_public_gateway_modify')} @@ -76,13 +77,14 @@ export default function Actions({ size={ODS_BUTTON_SIZE.sm} variant={ODS_BUTTON_VARIANT.ghost} color={ODS_THEME_COLOR_INTENT.primary} + data-testid="actions-hrefRemove" href={hrefRemove} > {t('pci_projects_project_public_gateway_delete')} diff --git a/packages/manager/apps/pci-gateway/src/components/list/PrivateIPs.component.tsx b/packages/manager/apps/pci-gateway/src/components/list/PrivateIPs.component.tsx index 432aa8e7804c..c819289c98bd 100644 --- a/packages/manager/apps/pci-gateway/src/components/list/PrivateIPs.component.tsx +++ b/packages/manager/apps/pci-gateway/src/components/list/PrivateIPs.component.tsx @@ -19,7 +19,7 @@ export default function PrivateIPs({ >
    {interfaces.map((item) => ( -
  • +
  • {item.ip}
  • ))} diff --git a/packages/manager/apps/pci-gateway/src/components/list/PrivateNetworkButton.component.spec.tsx b/packages/manager/apps/pci-gateway/src/components/list/PrivateNetworkButton.component.spec.tsx new file mode 100644 index 000000000000..8b6c714b9320 --- /dev/null +++ b/packages/manager/apps/pci-gateway/src/components/list/PrivateNetworkButton.component.spec.tsx @@ -0,0 +1,49 @@ +import { describe, it, vi } from 'vitest'; +import { act, fireEvent, render, waitFor } from '@testing-library/react'; +import { + ShellContext, + ShellContextType, +} from '@ovh-ux/manager-react-shell-client'; +import { PrivateNetworkButton } from './PrivateNetworkButton.component'; + +const shellContext = { + shell: { + navigation: { + getURL: vi.fn().mockResolvedValue('mocked_url'), + }, + }, +}; + +const wrapper = ({ children }) => ( + + {children} + +); + +describe('PrivateNetworkButton', () => { + it('renders without crashing', ({ expect }) => { + const { getByTestId } = render(, { + wrapper, + }); + const button = getByTestId('privateNetworkButton-link'); + expect(button).toBeInTheDocument(); + }); + + it('navigates to correct URL on click', async ({ expect }) => { + const { getByTestId } = render(, { + wrapper, + }); + const button = getByTestId('privateNetworkButton-link'); + + act(() => { + fireEvent.click(button); + }); + await waitFor(() => { + expect(shellContext.shell.navigation.getURL).toHaveBeenCalledWith( + 'public-cloud', + '#/pci/projects/test/private-networks', + {}, + ); + }); + }); +}); diff --git a/packages/manager/apps/pci-gateway/src/components/list/PrivateNetworkButton.component.tsx b/packages/manager/apps/pci-gateway/src/components/list/PrivateNetworkButton.component.tsx index 376611bf160e..662df9455c40 100644 --- a/packages/manager/apps/pci-gateway/src/components/list/PrivateNetworkButton.component.tsx +++ b/packages/manager/apps/pci-gateway/src/components/list/PrivateNetworkButton.component.tsx @@ -36,6 +36,7 @@ export const PrivateNetworkButton = ({ @@ -43,7 +44,7 @@ export const PrivateNetworkButton = ({ size={ODS_THEME_TYPOGRAPHY_SIZE._500} level={ODS_TEXT_LEVEL.button} color={ODS_THEME_COLOR_INTENT.primary} - slot={'start'} + slot="start" > {t('pci_projects_project_public_gateway_go_to_private_networks')} diff --git a/packages/manager/apps/pci-gateway/src/hooks/useDatagridColumn.spec.tsx b/packages/manager/apps/pci-gateway/src/hooks/useDatagridColumn.spec.tsx new file mode 100644 index 000000000000..518276b3d6cf --- /dev/null +++ b/packages/manager/apps/pci-gateway/src/hooks/useDatagridColumn.spec.tsx @@ -0,0 +1,102 @@ +import { renderHook } from '@testing-library/react'; +import { describe, it } from 'vitest'; +import { useDatagridColumn } from './useDatagridColumn'; +import { Gateway, Interface } from '@/interface'; + +describe('useDatagridColumn', () => { + it('renders name cell correctly', () => { + const { result } = renderHook(() => + useDatagridColumn('projectId', 'privateNetworkUrl'), + ); + const nameCell = result.current[0].cell({ + name: 'testName', + id: 'testId', + } as Gateway); + expect(nameCell.props.children[0].props.children).toBe('testName'); + expect(nameCell.props.children[1].props.children).toBe('testId'); + }); + + it('renders region cell correctly', () => { + const { result } = renderHook(() => + useDatagridColumn('projectId', 'privateNetworkUrl'), + ); + const regionCell = result.current[1].cell({ + region: 'testRegion', + } as Gateway); + expect(regionCell.props.children).toBe('testRegion'); + }); + + it('renders networksConnected cell correctly', () => { + const { result } = renderHook(() => + useDatagridColumn('projectId', 'privateNetworkUrl'), + ); + const networksConnectedCell = result.current[2].cell({ + connectedNetworkCount: 2, + } as Gateway); + expect(networksConnectedCell.props.children).toBe(2); + }); + + it('renders formattedIps cell correctly', () => { + const { result } = renderHook(() => + useDatagridColumn('projectId', 'privateNetworkUrl'), + ); + const formattedIpsCell = result.current[3].cell({ + formattedIps: 'testIps', + } as Gateway); + expect(formattedIpsCell.props.children).toBe('testIps'); + }); + + it('renders flavour cell correctly', () => { + const { result } = renderHook(() => + useDatagridColumn('projectId', 'privateNetworkUrl'), + ); + const flavourCell = result.current[4].cell({ + model: 'testModel', + } as Gateway); + expect(flavourCell.props.children).toBe('testModel'); + }); + + it('renders status cell correctly', () => { + const { result } = renderHook(() => + useDatagridColumn('projectId', 'privateNetworkUrl'), + ); + const statusCell = result.current[5].cell({ + status: 'testStatus', + } as Gateway); + expect(statusCell.props.children).toBe('testStatus'); + }); + + it('renders privateIPs cell correctly', () => { + const { result } = renderHook(() => + useDatagridColumn('projectId', 'privateNetworkUrl'), + ); + const interfaces: Interface[] = [ + { + id: 'test-id', + ip: '192.168.1.1', + subnetId: 'test-subnet-id', + networkId: 'test-network-id', + }, + { + id: 'test-id2', + ip: '192.168.1.2', + subnetId: 'test-subnet-id-2', + networkId: 'test-network-id-2', + }, + ]; + const privateIPsCell = result.current[6].cell({ + interfaces, + } as Gateway); + expect(privateIPsCell.props.interfaces).toBe(interfaces); + }); + + it('renders actions cell correctly', () => { + const { result } = renderHook(() => + useDatagridColumn('projectId', 'privateNetworkUrl'), + ); + const actionsCell = result.current[7].cell({ id: 'testId' } as Gateway); + expect(actionsCell.props.children.props.gateway).toStrictEqual({ + id: 'testId', + }); + }); +}); diff --git a/packages/manager/apps/pci-gateway/src/hooks/useDatagridColumn.tsx b/packages/manager/apps/pci-gateway/src/hooks/useDatagridColumn.tsx index 6480880d790a..ecdce797ee0b 100644 --- a/packages/manager/apps/pci-gateway/src/hooks/useDatagridColumn.tsx +++ b/packages/manager/apps/pci-gateway/src/hooks/useDatagridColumn.tsx @@ -27,7 +27,7 @@ export const useDatagridColumn = ( level={ODS_THEME_TYPOGRAPHY_LEVEL.body} size={ODS_THEME_TYPOGRAPHY_SIZE._500} color={ODS_THEME_COLOR_INTENT.text} - className={'block'} + className="block" > {props.name} @@ -35,7 +35,7 @@ export const useDatagridColumn = ( level={ODS_THEME_TYPOGRAPHY_LEVEL.body} size={ODS_THEME_TYPOGRAPHY_SIZE._400} color={ODS_THEME_COLOR_INTENT.text} - className={'block'} + className="block" > {props.id} @@ -95,7 +95,7 @@ export const useDatagridColumn = (
), - label: t(''), + label: '', }, ]; return columns; diff --git a/packages/manager/apps/pci-gateway/src/layout.ts b/packages/manager/apps/pci-gateway/src/layout.ts deleted file mode 100644 index 6f81e3311b47..000000000000 --- a/packages/manager/apps/pci-gateway/src/layout.ts +++ /dev/null @@ -1,7 +0,0 @@ -export enum BreakPoints { - XS = 0, - SM = 540, - MD = 720, - LG = 960, - XL = 1140, -} diff --git a/packages/manager/apps/pci-gateway/src/pages/add/AddGateway.page.tsx b/packages/manager/apps/pci-gateway/src/pages/add/AddGateway.page.tsx index 38efaaad808c..29f0adcf0f40 100644 --- a/packages/manager/apps/pci-gateway/src/pages/add/AddGateway.page.tsx +++ b/packages/manager/apps/pci-gateway/src/pages/add/AddGateway.page.tsx @@ -109,7 +109,7 @@ export default function AddGatewayPage(): JSX.Element { /> {tEdit('pci_projects_project_public_gateway_edit_go_back')} -
+
{tAdd('pci_projects_project_public_gateways_add_title')} -
+
diff --git a/packages/manager/apps/pci-gateway/src/pages/add/LocationStep.tsx b/packages/manager/apps/pci-gateway/src/pages/add/LocationStep.tsx index c72fa38d4845..0d4fad4b6552 100644 --- a/packages/manager/apps/pci-gateway/src/pages/add/LocationStep.tsx +++ b/packages/manager/apps/pci-gateway/src/pages/add/LocationStep.tsx @@ -116,9 +116,7 @@ export const LocationStep = () => { { )} {
- + { { store.updateForm.network( event.detail.value as string, @@ -360,7 +360,7 @@ export const NetworkStep = (): JSX.Element => { )} {store.form.newNetwork.name && store.form.newNetwork.subnet && ( - + {store.form.newNetwork.name} )} @@ -379,10 +379,10 @@ export const NetworkStep = (): JSX.Element => { { setState({ ...state, @@ -400,12 +400,12 @@ export const NetworkStep = (): JSX.Element => { {!isCreating ? (
{store.form.network?.id && isSubnetsLoading && ( - + )} {(!store.form.network?.id || !isSubnetsLoading) && ( {
) : (

- + ({ + useNewGatewayStore: vi.fn(), +})); + +describe('SubnetModal', () => { + it('calls onClose when cancel button is clicked', () => { + const onClose = vi.fn(); + vi.mocked(useNewGatewayStore).mockReturnValue({ + form: { + newNetwork: { + name: '', + subnet: '', + }, + }, + updateForm: { + newNetwork: vi.fn(), + network: vi.fn(), + }, + }); + + const { getByText } = render(); + act(() => { + fireEvent.click( + getByText( + 'pci_projects_project_public_gateways_add_modal_cancel_label', + ), + ); + }); + expect(onClose).toHaveBeenCalled(); + }); + + it('updates network when submit button is clicked and form is valid', () => { + const onClose = vi.fn(); + const updateNetwork = vi.fn(); + vi.mocked(useNewGatewayStore).mockReturnValue({ + form: { + newNetwork: { + name: 'test', + subnet: 'test', + }, + network: { + subnetId: 'subnetId', + }, + }, + updateForm: { + newNetwork: vi.fn(), + network: updateNetwork, + }, + }); + + const { getByText } = render(); + act(() => { + fireEvent.click( + getByText( + 'pci_projects_project_public_gateways_add_modal_submit_label', + ), + ); + }); + expect(updateNetwork).toHaveBeenCalledWith('new', 'subnetId'); + }); + + it('does not update network when submit button is clicked and form is invalid', async () => { + const onClose = vi.fn(); + const updateNetwork = vi.fn(); + vi.mocked(useNewGatewayStore).mockReturnValue({ + form: { + newNetwork: { + name: '', + subnet: '', + }, + network: { + subnetId: '', + }, + }, + updateForm: { + newNetwork: vi.fn(), + network: updateNetwork, + }, + }); + + const { getByText } = render(); + await act(() => { + fireEvent.click( + getByText( + 'pci_projects_project_public_gateways_add_modal_submit_label', + ), + ); + }); + waitFor(() => { + expect(updateNetwork).toHaveBeenCalled(); + }); + }); +}); diff --git a/packages/manager/apps/pci-gateway/src/pages/add/SubnetModal.tsx b/packages/manager/apps/pci-gateway/src/pages/add/SubnetModal.tsx index b4f8c32476d3..5c9b6fe378dd 100644 --- a/packages/manager/apps/pci-gateway/src/pages/add/SubnetModal.tsx +++ b/packages/manager/apps/pci-gateway/src/pages/add/SubnetModal.tsx @@ -67,7 +67,7 @@ export const SubnetModal = ({ placeholder={tAdd( 'pci_projects_project_public_gateways_add_modal_add_private_network_field_placeholder', )} - inline={true} + inline onOdsValueChange={(event) => { store.updateForm.newNetwork( event.detail.value, @@ -104,7 +104,7 @@ export const SubnetModal = ({ { store.updateForm.newNetwork( store.form.newNetwork.name, diff --git a/packages/manager/apps/pci-gateway/src/pages/delete/DeleteGateway.page.tsx b/packages/manager/apps/pci-gateway/src/pages/delete/DeleteGateway.page.tsx index 20e5cac693d2..52aa991153ec 100644 --- a/packages/manager/apps/pci-gateway/src/pages/delete/DeleteGateway.page.tsx +++ b/packages/manager/apps/pci-gateway/src/pages/delete/DeleteGateway.page.tsx @@ -116,7 +116,7 @@ export default function DeleteGateway() { level={ODS_THEME_TYPOGRAPHY_LEVEL.body} color={ODS_THEME_COLOR_INTENT.text} size={ODS_TEXT_SIZE._400} - className={'block mt-6'} + className="block mt-6" > {tDelete( 'pci_projects_project_public_gateway_delete_confirmation', diff --git a/packages/manager/apps/pci-gateway/src/pages/edit/EditGateway.page.spec.tsx b/packages/manager/apps/pci-gateway/src/pages/edit/EditGateway.page.spec.tsx new file mode 100644 index 000000000000..653ee956acb8 --- /dev/null +++ b/packages/manager/apps/pci-gateway/src/pages/edit/EditGateway.page.spec.tsx @@ -0,0 +1,91 @@ +import { describe, it, vi } from 'vitest'; +import { render, waitFor } from '@testing-library/react'; +import { + QueryClient, + QueryClientProvider, + UseMutationResult, + UseQueryResult, +} from '@tanstack/react-query'; +import { + ShellContext, + ShellContextType, +} from '@ovh-ux/manager-react-shell-client'; +import * as pciCommonModule from '@ovh-ux/manager-pci-common'; +import { TProject } from '@ovh-ux/manager-pci-common'; +import EditGatewayPage from './EditGateway.page'; +import * as useGatewayModule from '@/api/hooks/useGateways'; +import { TGateway } from '@/api/data/gateways'; + +type UseEditGatewayReturnType = UseMutationResult< + TGateway, + Error, + { name: string; model: string }, + unknown +> & { + updateGateway: () => void; +}; + +const mockedUseNavigate = vi.fn(); +const mockGatewayUpdate = vi.fn(); + +vi.mock('react-router-dom', () => ({ + useHref: () => 'mocked_url', + useSearchParams: () => [ + new URLSearchParams({ + gatewayId: 'gateway-id', + region: 'region-gateway', + }), + ], + useParams: () => ({ + gatewayId: '123', + projectId: '123', + }), + useNavigate: () => mockedUseNavigate, +})); + +const shellContext = { + environment: { + getUser: vi.fn(), + }, + shell: { + navigation: { + getURL: vi.fn().mockResolvedValue('mocked_url'), + }, + ux: { + hidePreloader: vi.fn(), + }, + }, +}; + +const queryClient = new QueryClient(); +const wrapper = ({ children }) => ( + + + {children} + + +); + +describe('EditGatewayPage', () => { + it('renders without crashing', () => { + vi.spyOn(pciCommonModule, 'useProject').mockResolvedValue({ + data: { + project_id: '123', + planCode: 'project.discovery', + description: 'description', + }, + } as UseQueryResult); + vi.spyOn(useGatewayModule, 'useEditGateway').mockReturnValue(({ + updateGateway: mockGatewayUpdate, + isPending: false, + } as unknown) as UseEditGatewayReturnType); + const { getByTestId } = render(, { + wrapper, + }); + waitFor(() => { + expect(getByTestId('gatewayEdit-spinner')).toBeInTheDocument(); + }); + }); +}); diff --git a/packages/manager/apps/pci-gateway/src/pages/edit/EditGateway.page.tsx b/packages/manager/apps/pci-gateway/src/pages/edit/EditGateway.page.tsx index 60ac8402a176..ad876df9fe09 100644 --- a/packages/manager/apps/pci-gateway/src/pages/edit/EditGateway.page.tsx +++ b/packages/manager/apps/pci-gateway/src/pages/edit/EditGateway.page.tsx @@ -149,24 +149,25 @@ export default function EditGatewayPage(): JSX.Element { {isGatewayLoading ? ( ) : ( <> {isGatewayUpdating && ( )} { setState((prev) => ({ ...prev, diff --git a/packages/manager/apps/pci-gateway/src/pages/list/List.page.spec.tsx b/packages/manager/apps/pci-gateway/src/pages/list/List.page.spec.tsx new file mode 100644 index 000000000000..c10034efbdea --- /dev/null +++ b/packages/manager/apps/pci-gateway/src/pages/list/List.page.spec.tsx @@ -0,0 +1,59 @@ +import { describe, it, vi } from 'vitest'; +import { render } from '@testing-library/react'; +import { + QueryClient, + QueryClientProvider, + UseQueryResult, +} from '@tanstack/react-query'; +import { useHref, useParams } from 'react-router-dom'; +import { + ShellContext, + ShellContextType, +} from '@ovh-ux/manager-react-shell-client'; +import * as pciCommonModule from '@ovh-ux/manager-pci-common'; +import { TProject } from '@ovh-ux/manager-pci-common'; +import ListingPage from './List.page'; + +vi.mock('react-router-dom'); + +const shellContext = { + environment: { + getUser: vi.fn(), + }, + shell: { + navigation: { + getURL: vi.fn(), + }, + }, +}; + +const queryClient = new QueryClient(); +const wrapper = ({ children }) => ( + + + {children} + + +); +describe('ListingPage', () => { + it('ListingPage renders without crashing', () => { + vi.spyOn(pciCommonModule, 'useProject').mockResolvedValue({ + data: { + project_id: '123', + planCode: 'project.discovery', + description: 'description', + }, + } as UseQueryResult); + const { environment, shell } = shellContext; + environment.getUser.mockResolvedValue({ + ovhSubsidiary: 'foo', + }); + shell.navigation.getURL.mockResolvedValue('https://www.ovh.com'); + vi.mocked(useParams).mockReturnValue({ projectId: '123' }); + vi.mocked(useHref).mockReturnValue('mocked_href'); + const { container } = render(, { wrapper }); + expect(container).toBeDefined(); + }); +}); diff --git a/packages/manager/apps/pci-gateway/src/pages/list/List.page.tsx b/packages/manager/apps/pci-gateway/src/pages/list/List.page.tsx index 05b56c2d85ee..1b65993ed5cd 100644 --- a/packages/manager/apps/pci-gateway/src/pages/list/List.page.tsx +++ b/packages/manager/apps/pci-gateway/src/pages/list/List.page.tsx @@ -131,7 +131,7 @@ export default function ListingPage() { color={ODS_THEME_COLOR_INTENT.text} level={ODS_THEME_TYPOGRAPHY_LEVEL.body} size={ODS_THEME_TYPOGRAPHY_SIZE._400} - className={'mt-3'} + className="mt-3" >

  • {t('pci_projects_project_public_gateways_intro_part_2')}
  • @@ -145,7 +145,7 @@ export default function ListingPage() {
    -
    +
    {t('pci_projects_project_public_gateway_create')}
    { setPagination({ @@ -195,7 +195,7 @@ export default function ListingPage() { {tFilter('common_criteria_adder_filter_label')} @@ -250,7 +250,7 @@ export default function ListingPage() {
    {isLoading && (
    - +
    )} @@ -262,7 +262,7 @@ export default function ListingPage() { totalItems={aggregatedGateways?.totalRows || 0} pagination={pagination} onPaginationChange={setPagination} - className={'overflow-x-visible'} + className="overflow-x-visible" />
    )} diff --git a/packages/manager/apps/pci-gateway/src/pages/list/ListGuard.tsx b/packages/manager/apps/pci-gateway/src/pages/list/ListGuard.tsx index dde7462f348e..ae5ffbaaeaa4 100644 --- a/packages/manager/apps/pci-gateway/src/pages/list/ListGuard.tsx +++ b/packages/manager/apps/pci-gateway/src/pages/list/ListGuard.tsx @@ -19,7 +19,7 @@ export default function ListGuard({ if (isPending || isFetching) { return ( diff --git a/packages/manager/apps/pci-gateway/src/pages/onboarding/OnBoarding.page.spec.tsx b/packages/manager/apps/pci-gateway/src/pages/onboarding/OnBoarding.page.spec.tsx new file mode 100644 index 000000000000..c6ea4f157cad --- /dev/null +++ b/packages/manager/apps/pci-gateway/src/pages/onboarding/OnBoarding.page.spec.tsx @@ -0,0 +1,50 @@ +import { it, vi } from 'vitest'; +import { render } from '@testing-library/react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { + ShellContext, + ShellContextType, +} from '@ovh-ux/manager-react-shell-client'; +import { useParams, useRouteLoaderData } from 'react-router-dom'; +import OnBoardingPage from './OnBoarding.page'; + +vi.mock('react-router-dom'); + +const shellContext = { + environment: { + getUser: vi.fn(), + }, + shell: { + navigation: { + getURL: vi.fn(), + }, + }, +}; + +const queryClient = new QueryClient(); +const wrapper = ({ children }) => ( + + + {children} + + +); + +describe('OnBoardingPage', () => { + it('OnBoardingPage renders without crashing', () => { + const { environment, shell } = shellContext; + environment.getUser.mockResolvedValue({ + ovhSubsidiary: 'foo', + }); + shell.navigation.getURL.mockResolvedValue('https://www.ovh.com'); + vi.mocked(useParams).mockReturnValue({ projectId: '123' }); + vi.mocked(useRouteLoaderData).mockReturnValue({ + project_id: '123', + planCode: 'project.discovery', + }); + const { container } = render(, { wrapper }); + expect(container).toBeDefined(); + }); +}); diff --git a/packages/manager/apps/pci-gateway/src/pages/onboarding/OnBoardingGuard.tsx b/packages/manager/apps/pci-gateway/src/pages/onboarding/OnBoardingGuard.tsx index 33199e8f8897..21b6d37a9f42 100644 --- a/packages/manager/apps/pci-gateway/src/pages/onboarding/OnBoardingGuard.tsx +++ b/packages/manager/apps/pci-gateway/src/pages/onboarding/OnBoardingGuard.tsx @@ -17,7 +17,7 @@ export default function OnBoardingGuard({ if (isPending) { return ( diff --git a/packages/manager/apps/pci-gateway/vitest.config.js b/packages/manager/apps/pci-gateway/vitest.config.js index 72abd68fdc36..2f696d675b25 100644 --- a/packages/manager/apps/pci-gateway/vitest.config.js +++ b/packages/manager/apps/pci-gateway/vitest.config.js @@ -17,11 +17,13 @@ export default defineConfig({ 'src/vite-*.ts', 'src/App.tsx', 'src/core/ShellRoutingSync.tsx', + 'src/core/HidePreloader.tsx', 'src/i18n.ts', 'src/main.tsx', 'src/routes.tsx', 'src/constants.ts', 'src/**/*.constants.ts', + 'src/queryClient.ts', ], }, }, From 1654b09eae0656318a126e64e1f22065c3d80df7 Mon Sep 17 00:00:00 2001 From: Eric <35898232+Eric-ciccotti@users.noreply.github.com> Date: Thu, 10 Oct 2024 16:32:46 +0200 Subject: [PATCH 05/11] feat(pci-rancher): add Id (#13369) ref: TAPC-983 Signed-off-by: Eric Ciccotti Co-authored-by: CDS Translator Agent --- .../public/translations/dashboard/Messages_de_DE.json | 2 +- .../public/translations/dashboard/Messages_en_GB.json | 2 +- .../public/translations/dashboard/Messages_es_ES.json | 2 +- .../public/translations/dashboard/Messages_fr_CA.json | 2 +- .../public/translations/dashboard/Messages_fr_FR.json | 2 +- .../public/translations/dashboard/Messages_it_IT.json | 2 +- .../public/translations/dashboard/Messages_pl_PL.json | 2 +- .../public/translations/dashboard/Messages_pt_PT.json | 2 +- .../Dashboard/RancherDetail/RancherDetail.component.tsx | 7 ++++++- 9 files changed, 14 insertions(+), 9 deletions(-) diff --git a/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_de_DE.json b/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_de_DE.json index 1839e8eb064a..3877b25777c3 100644 --- a/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_de_DE.json +++ b/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_de_DE.json @@ -7,7 +7,7 @@ "description": "Name", "rancher_version": "Rancher-Version", "consumption": "Verbrauch", - "service_level": "Dienst", + "service_level": "Angebot", "count_cpu_orchestrated": "Anzahl der orchestrierten vCPU", "security_and_access": "Zugang und Sicherheit", "rancher_ui_access": "Zugriff auf das Rancher-Interface", diff --git a/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_en_GB.json b/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_en_GB.json index 5c800f3f13fc..8c03727a5334 100644 --- a/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_en_GB.json +++ b/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_en_GB.json @@ -7,7 +7,7 @@ "description": "Name", "rancher_version": "Rancher version", "consumption": "Usage", - "service_level": "Service", + "service_level": "Offer", "count_cpu_orchestrated": "Number of vCPUs orchestrated", "security_and_access": "Access and security", "rancher_ui_access": "Go to the Rancher interface", diff --git a/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_es_ES.json b/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_es_ES.json index c7bb0ca5d301..9675f5397fd0 100644 --- a/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_es_ES.json +++ b/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_es_ES.json @@ -7,7 +7,7 @@ "description": "Apellido", "rancher_version": "Versión de Rancher", "consumption": "Consumo", - "service_level": "Servicio", + "service_level": "Producto", "count_cpu_orchestrated": "Número de vCPU orquestadas", "security_and_access": "Acceso y seguridad", "rancher_ui_access": "Acceso a la interfaz Rancher", diff --git a/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_fr_CA.json b/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_fr_CA.json index a200539b78d6..8e120e42aa6e 100644 --- a/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_fr_CA.json +++ b/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_fr_CA.json @@ -7,7 +7,7 @@ "description": "Nom", "rancher_version": "Version de Rancher", "consumption": "Consommation", - "service_level": "Service", + "service_level": "Offre", "count_cpu_orchestrated": "Nombre de vCPUs orchestrés", "security_and_access": "Accès et sécurité", "rancher_ui_access": "Accès à l'interface Rancher", diff --git a/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_fr_FR.json b/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_fr_FR.json index a200539b78d6..8e120e42aa6e 100644 --- a/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_fr_FR.json +++ b/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_fr_FR.json @@ -7,7 +7,7 @@ "description": "Nom", "rancher_version": "Version de Rancher", "consumption": "Consommation", - "service_level": "Service", + "service_level": "Offre", "count_cpu_orchestrated": "Nombre de vCPUs orchestrés", "security_and_access": "Accès et sécurité", "rancher_ui_access": "Accès à l'interface Rancher", diff --git a/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_it_IT.json b/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_it_IT.json index bb6f274ecc1c..e3fb91539389 100644 --- a/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_it_IT.json +++ b/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_it_IT.json @@ -7,7 +7,7 @@ "description": "Nome", "rancher_version": "Versione di Rancher", "consumption": "Consumo", - "service_level": "Servizio", + "service_level": "Offerta", "count_cpu_orchestrated": "Numero di vCPU orchestrate", "security_and_access": "Accesso e sicurezza", "rancher_ui_access": "Accesso all'interfaccia Rancher", diff --git a/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_pl_PL.json b/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_pl_PL.json index 27d19a5b1da0..3635b322c07b 100644 --- a/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_pl_PL.json +++ b/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_pl_PL.json @@ -7,7 +7,7 @@ "description": "Nazwa", "rancher_version": "Wersja Ranchera", "consumption": "Zużycie", - "service_level": "Usługa", + "service_level": "Oferta", "count_cpu_orchestrated": "Liczba orkiestrowanych vCPU", "security_and_access": "Dostęp i bezpieczeństwo", "rancher_ui_access": "Dostęp do interfejsu Rancher", diff --git a/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_pt_PT.json b/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_pt_PT.json index bf75c6fe2579..7a2d87b372b7 100644 --- a/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_pt_PT.json +++ b/packages/manager/apps/pci-rancher/public/translations/dashboard/Messages_pt_PT.json @@ -7,7 +7,7 @@ "description": "Nome", "rancher_version": "Versão do Rancher", "consumption": "Consumo", - "service_level": "Serviço", + "service_level": "Oferta", "count_cpu_orchestrated": "Número de vCPU orquestrados", "security_and_access": "Acesso e segurança", "rancher_ui_access": "Acesso à interface Rancher", diff --git a/packages/manager/apps/pci-rancher/src/components/layout-helpers/Dashboard/RancherDetail/RancherDetail.component.tsx b/packages/manager/apps/pci-rancher/src/components/layout-helpers/Dashboard/RancherDetail/RancherDetail.component.tsx index 46dbb5fad2ed..8182c28a1eac 100644 --- a/packages/manager/apps/pci-rancher/src/components/layout-helpers/Dashboard/RancherDetail/RancherDetail.component.tsx +++ b/packages/manager/apps/pci-rancher/src/components/layout-helpers/Dashboard/RancherDetail/RancherDetail.component.tsx @@ -172,7 +172,12 @@ const RancherDetail = ({ isDisabled={!isReadyStatus} /> - + + + {t('copy')} + {t('error')} + + {version} From 786efc5249611d040b00ec7c0a6d3ab87dddf438 Mon Sep 17 00:00:00 2001 From: Eric <35898232+Eric-ciccotti@users.noreply.github.com> Date: Thu, 10 Oct 2024 16:33:17 +0200 Subject: [PATCH 06/11] feat(pci-rancher): add aria-label (#13257) ref: TAPC-1628 Signed-off-by: Eric Ciccotti --- .../apps/pci-rancher/src/components/Pricing/RancherPlanTile.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/manager/apps/pci-rancher/src/components/Pricing/RancherPlanTile.tsx b/packages/manager/apps/pci-rancher/src/components/Pricing/RancherPlanTile.tsx index 0397bc223819..1d5cbc042660 100644 --- a/packages/manager/apps/pci-rancher/src/components/Pricing/RancherPlanTile.tsx +++ b/packages/manager/apps/pci-rancher/src/components/Pricing/RancherPlanTile.tsx @@ -31,6 +31,7 @@ const RancherPlanTile: React.FC = ({ return (
  • setSelectedPlan(plan)} className={clsx( 'cursor-pointer border-[--ods-color-blue-100] hover:bg-[--ods-color-blue-075] hover:border-[--ods-color-blue-600]', From b1aa16b3c1d7bda406135c6f6baacc0fd4afe947 Mon Sep 17 00:00:00 2001 From: Omar Date: Thu, 10 Oct 2024 16:34:50 +0200 Subject: [PATCH 07/11] fix(pci-private-network): re-render issue on language change (#12641) ref: PRB0041352 Signed-off-by: Omar ALKABOUSS MOUSSANA --- .../src/pages/new/steps/LocalizationStep.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/manager/apps/pci-private-network/src/pages/new/steps/LocalizationStep.tsx b/packages/manager/apps/pci-private-network/src/pages/new/steps/LocalizationStep.tsx index 30a8daf2f2aa..9b8da3115e61 100644 --- a/packages/manager/apps/pci-private-network/src/pages/new/steps/LocalizationStep.tsx +++ b/packages/manager/apps/pci-private-network/src/pages/new/steps/LocalizationStep.tsx @@ -33,7 +33,7 @@ export default function LocalizationStep(): JSX.Element { const { t } = useTranslation('new'); const { t: tCommon } = useTranslation('common'); const { t: tRegion } = useTranslation('region'); - const { t: tRegions } = useTranslation('regions'); + const { t: tRegions, i18n } = useTranslation('regions'); const { data: regions, @@ -41,7 +41,6 @@ export default function LocalizationStep(): JSX.Element { } = useProjectAvailableRegions(store.project?.id); const [mappedRegions, setMappedRegions] = useState([]); - const [state, setState] = useState<{ selectedContinent: string }>({ selectedContinent: undefined, }); @@ -112,7 +111,7 @@ export default function LocalizationStep(): JSX.Element { setMappedRegions(result); } - }, [regions]); + }, [regions, i18n.language]); return ( Date: Thu, 10 Oct 2024 16:36:27 +0200 Subject: [PATCH 08/11] fix(pci-databases-analytics): add missing certificate in dashboard (#13512) ref: DATATR-1537 Signed-off-by: Arthur Bullet Co-Authored-by: CDS Translator Agent --- .../service/dashboard/Messages_de_DE.json | 5 +- .../service/dashboard/Messages_en_GB.json | 5 +- .../service/dashboard/Messages_es_ES.json | 5 +- .../service/dashboard/Messages_fr_CA.json | 3 + .../service/dashboard/Messages_fr_FR.json | 3 + .../service/dashboard/Messages_it_IT.json | 5 +- .../service/dashboard/Messages_pl_PL.json | 5 +- .../service/dashboard/Messages_pt_PT.json | 5 +- .../ConnectionDetails.component.tsx | 74 +++++++++++++++++-- 9 files changed, 99 insertions(+), 11 deletions(-) diff --git a/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_de_DE.json b/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_de_DE.json index fa5f216f9f92..35112302b3e3 100644 --- a/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_de_DE.json +++ b/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_de_DE.json @@ -30,5 +30,8 @@ "serviceIdLabel": "Dienst-ID", "serviceIdCopyToast": "Die Dienst-ID wurde kopiert.", "billingLink": "Abrechnung verwalten", - "supportLink": "Support kontaktieren" + "supportLink": "Support kontaktieren", + "connectionDetailsCertificateLabel": "Zertifikat", + "connectionDetailsCertificateCopyToast": "Das CA-Zertifikat wurde in die Zwischenablage kopiert.", + "connectionDetailsCertificateDownloadToast": "Das CA-Zertifikat wurde hochgeladen." } diff --git a/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_en_GB.json b/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_en_GB.json index 381e2fb365b3..c17689b50319 100644 --- a/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_en_GB.json +++ b/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_en_GB.json @@ -30,5 +30,8 @@ "serviceIdLabel": "Service ID", "serviceIdCopyToast": "The service ID has been copied", "billingLink": "Manage billing", - "supportLink": "Contact support" + "supportLink": "Contact support", + "connectionDetailsCertificateLabel": "Certificate", + "connectionDetailsCertificateCopyToast": "The CA certificate has been copied to your clipboard", + "connectionDetailsCertificateDownloadToast": "The CA certificate has been uploaded" } diff --git a/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_es_ES.json b/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_es_ES.json index ea4225b832dc..5ad546989d78 100644 --- a/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_es_ES.json +++ b/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_es_ES.json @@ -30,5 +30,8 @@ "serviceIdLabel": "ID del servicio", "serviceIdCopyToast": "Se ha copiado el ID del servicio", "billingLink": "Gestionar la facturación", - "supportLink": "Contactar con el soporte" + "supportLink": "Contactar con el soporte", + "connectionDetailsCertificateLabel": "Certificado", + "connectionDetailsCertificateCopyToast": "El certificado CA se ha copiado en el portapapeles.", + "connectionDetailsCertificateDownloadToast": "Se ha cargado el certificado CA." } diff --git a/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_fr_CA.json b/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_fr_CA.json index af2765b7ad7f..02afca80ad54 100644 --- a/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_fr_CA.json +++ b/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_fr_CA.json @@ -16,6 +16,9 @@ "connectionDetailsTableSSLMode": "obligatoire", "connectionDetailsHostCopyToast": "L'url de l'hote a été copiée", "connectionDetailsURICopyToast": "L'URI a été copiée", + "connectionDetailsCertificateLabel": "Certificat", + "connectionDetailsCertificateCopyToast": "Le certificat CA a été copié dans votre presse papier", + "connectionDetailsCertificateDownloadToast": "Le certificat CA a été téléchargé", "maintenanceTitle": "Maintenance", "noMaintenanceDescription": "Aucune maintenance n'est prévue sur votre service.", "oneMaintenanceDescription1": "{{number}} maintenance", diff --git a/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_fr_FR.json b/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_fr_FR.json index af2765b7ad7f..02afca80ad54 100644 --- a/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_fr_FR.json +++ b/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_fr_FR.json @@ -16,6 +16,9 @@ "connectionDetailsTableSSLMode": "obligatoire", "connectionDetailsHostCopyToast": "L'url de l'hote a été copiée", "connectionDetailsURICopyToast": "L'URI a été copiée", + "connectionDetailsCertificateLabel": "Certificat", + "connectionDetailsCertificateCopyToast": "Le certificat CA a été copié dans votre presse papier", + "connectionDetailsCertificateDownloadToast": "Le certificat CA a été téléchargé", "maintenanceTitle": "Maintenance", "noMaintenanceDescription": "Aucune maintenance n'est prévue sur votre service.", "oneMaintenanceDescription1": "{{number}} maintenance", diff --git a/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_it_IT.json b/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_it_IT.json index 6bfe6af1139d..af3923825cb9 100644 --- a/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_it_IT.json +++ b/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_it_IT.json @@ -30,5 +30,8 @@ "serviceIdLabel": "ID del servizio", "serviceIdCopyToast": "L'ID del servizio è stato copiato", "billingLink": "Gestisci la fatturazione", - "supportLink": "Contattare il supporto" + "supportLink": "Contattare il supporto", + "connectionDetailsCertificateLabel": "Certificato", + "connectionDetailsCertificateCopyToast": "Il certificato CA è stato copiato negli appunti", + "connectionDetailsCertificateDownloadToast": "Il certificato CA è stato scaricato" } diff --git a/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_pl_PL.json b/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_pl_PL.json index 786a0f78e632..f1a17339bdda 100644 --- a/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_pl_PL.json +++ b/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_pl_PL.json @@ -30,5 +30,8 @@ "serviceIdLabel": "Identyfikator usługi", "serviceIdCopyToast": "Identyfikator usługi został skopiowany", "billingLink": "Zarządzaj płatnościami", - "supportLink": "Skontaktuj się z pomocą techniczną" + "supportLink": "Skontaktuj się z pomocą techniczną", + "connectionDetailsCertificateLabel": "Certyfikat", + "connectionDetailsCertificateCopyToast": "Certyfikat CA został skopiowany do schowka", + "connectionDetailsCertificateDownloadToast": "Certyfikat CA został pobrany" } diff --git a/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_pt_PT.json b/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_pt_PT.json index f535cefa221f..c8ded2abd805 100644 --- a/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_pt_PT.json +++ b/packages/manager/apps/pci-databases-analytics/public/translations/pci-databases-analytics/services/service/dashboard/Messages_pt_PT.json @@ -30,5 +30,8 @@ "serviceIdLabel": "ID do serviço", "serviceIdCopyToast": "O ID do serviço foi copiado", "billingLink": "Gerir a faturação", - "supportLink": "Contactar o Apoio ao Cliente" + "supportLink": "Contactar o Apoio ao Cliente", + "connectionDetailsCertificateLabel": "Certificado", + "connectionDetailsCertificateCopyToast": "O certificado CA foi copiado para a área de transferência", + "connectionDetailsCertificateDownloadToast": "O certificado CA foi descarregado" } diff --git a/packages/manager/apps/pci-databases-analytics/src/pages/services/[serviceId]/dashboard/_components/ConnectionDetails.component.tsx b/packages/manager/apps/pci-databases-analytics/src/pages/services/[serviceId]/dashboard/_components/ConnectionDetails.component.tsx index fb938383acad..8ca79f3c7c50 100644 --- a/packages/manager/apps/pci-databases-analytics/src/pages/services/[serviceId]/dashboard/_components/ConnectionDetails.component.tsx +++ b/packages/manager/apps/pci-databases-analytics/src/pages/services/[serviceId]/dashboard/_components/ConnectionDetails.component.tsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { Files } from 'lucide-react'; +import { Download, Files } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import { Button } from '@/components/ui/button'; import { @@ -12,12 +12,28 @@ import { import { Table, TableBody, TableCell, TableRow } from '@/components/ui/table'; import * as database from '@/types/cloud/project/database'; import { useToast } from '@/components/ui/use-toast'; +import { useServiceData } from '../../Service.context'; +import { useGetCertificate } from '@/hooks/api/database/certificate/useGetCertificate.hook'; +import useDownload from '@/hooks/useDownload'; interface ConnectionDetailsProps { endpoints: database.service.Endpoint[]; } const ConnectionDetails = ({ endpoints }: ConnectionDetailsProps) => { + const { service, projectId } = useServiceData(); + + const certificateQuery = useGetCertificate( + projectId, + service.engine, + service.id, + { + enabled: + service.capabilities.certificates?.read === + database.service.capability.StateEnum.enabled, + }, + ); + const [selectedEndpoint, setSelectedEndpoint] = useState< database.service.Endpoint >(endpoints[0]); @@ -25,6 +41,7 @@ const ConnectionDetails = ({ endpoints }: ConnectionDetailsProps) => { 'pci-databases-analytics/services/service/dashboard', ); const toast = useToast(); + const { download } = useDownload(); return (
    {endpoints.length > 1 && ( @@ -60,13 +77,13 @@ const ConnectionDetails = ({ endpoints }: ConnectionDetailsProps) => {

    {selectedEndpoint.domain}

    - + + +
    + + + )}
  • From 813b00faab74262170d2fb23941700249259fcc9 Mon Sep 17 00:00:00 2001 From: Tsiorifamonjena Date: Thu, 10 Oct 2024 16:43:22 +0200 Subject: [PATCH 09/11] feat(pci-private-network): add link to string 'En savoir plus ici' on vlan config step (#13304) ref: TAPC-735 Signed-off-by: tsiorifamonjena 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 | 3 +- .../translations/common/Messages_fr_FR.json | 3 +- .../translations/common/Messages_it_IT.json | 3 +- .../translations/common/Messages_pl_PL.json | 3 +- .../translations/common/Messages_pt_PT.json | 3 +- .../translations/new/Messages_de_DE.json | 2 +- .../translations/new/Messages_en_GB.json | 2 +- .../translations/new/Messages_es_ES.json | 2 +- .../translations/new/Messages_fr_CA.json | 2 +- .../translations/new/Messages_fr_FR.json | 2 +- .../translations/new/Messages_it_IT.json | 2 +- .../translations/new/Messages_pl_PL.json | 2 +- .../translations/new/Messages_pt_PT.json | 2 +- .../apps/pci-private-network/src/constants.ts | 32 +++++++++++++++++++ .../src/pages/new/steps/ConfigurationStep.tsx | 17 +++++++--- 18 files changed, 69 insertions(+), 20 deletions(-) diff --git a/packages/manager/apps/pci-private-network/public/translations/common/Messages_de_DE.json b/packages/manager/apps/pci-private-network/public/translations/common/Messages_de_DE.json index 95ffbeb35afd..78852b326410 100644 --- a/packages/manager/apps/pci-private-network/public/translations/common/Messages_de_DE.json +++ b/packages/manager/apps/pci-private-network/public/translations/common/Messages_de_DE.json @@ -89,5 +89,6 @@ "common_dual_list_target_move_all": "Alles löschen", "common_dual_list_target_search": "In den Zieldaten suchen", "common_file_dropAreaSingle": "Eine Datei per Drag and Drop ablegen oder", - "common_file_notSingleError": "Es kann nur eine Datei hinzugefügt werden" + "common_file_notSingleError": "Es kann nur eine Datei hinzugefügt werden", + "common_find_out_more_here": "Weitere Informationen hier" } diff --git a/packages/manager/apps/pci-private-network/public/translations/common/Messages_en_GB.json b/packages/manager/apps/pci-private-network/public/translations/common/Messages_en_GB.json index d98f7d7ab9db..f4201a8d37c2 100644 --- a/packages/manager/apps/pci-private-network/public/translations/common/Messages_en_GB.json +++ b/packages/manager/apps/pci-private-network/public/translations/common/Messages_en_GB.json @@ -89,5 +89,6 @@ "common_dual_list_target_move_all": "Delete all", "common_dual_list_target_search": "Search target content", "common_file_dropAreaSingle": "Drag and drop a file or", - "common_file_notSingleError": "You can only add one file" + "common_file_notSingleError": "You can only add one file", + "common_find_out_more_here": "Find out more here." } diff --git a/packages/manager/apps/pci-private-network/public/translations/common/Messages_es_ES.json b/packages/manager/apps/pci-private-network/public/translations/common/Messages_es_ES.json index eee0d7037c40..dadc5187cdd6 100644 --- a/packages/manager/apps/pci-private-network/public/translations/common/Messages_es_ES.json +++ b/packages/manager/apps/pci-private-network/public/translations/common/Messages_es_ES.json @@ -89,5 +89,6 @@ "common_dual_list_target_move_all": "Eliminar todo", "common_dual_list_target_search": "Buscar en el contenido de destino", "common_file_dropAreaSingle": "Arrastre y suelte un archivo o", - "common_file_notSingleError": "Solo es posible añadir un archivo" + "common_file_notSingleError": "Solo es posible añadir un archivo", + "common_find_out_more_here": "Más información aquí" } diff --git a/packages/manager/apps/pci-private-network/public/translations/common/Messages_fr_CA.json b/packages/manager/apps/pci-private-network/public/translations/common/Messages_fr_CA.json index 3bcaf24ff182..6b831e90a6dd 100644 --- a/packages/manager/apps/pci-private-network/public/translations/common/Messages_fr_CA.json +++ b/packages/manager/apps/pci-private-network/public/translations/common/Messages_fr_CA.json @@ -89,5 +89,6 @@ "common_password_bad_password": "Mot de passe incorrect.", "common_password_weak_password": "Mot de passe faible.", "common_password_good_password": "Mot de passe correct.", - "common_password_strong_password": "Mot de passe fort." + "common_password_strong_password": "Mot de passe fort.", + "common_find_out_more_here": "En savoir plus ici" } diff --git a/packages/manager/apps/pci-private-network/public/translations/common/Messages_fr_FR.json b/packages/manager/apps/pci-private-network/public/translations/common/Messages_fr_FR.json index 3bcaf24ff182..6b831e90a6dd 100644 --- a/packages/manager/apps/pci-private-network/public/translations/common/Messages_fr_FR.json +++ b/packages/manager/apps/pci-private-network/public/translations/common/Messages_fr_FR.json @@ -89,5 +89,6 @@ "common_password_bad_password": "Mot de passe incorrect.", "common_password_weak_password": "Mot de passe faible.", "common_password_good_password": "Mot de passe correct.", - "common_password_strong_password": "Mot de passe fort." + "common_password_strong_password": "Mot de passe fort.", + "common_find_out_more_here": "En savoir plus ici" } diff --git a/packages/manager/apps/pci-private-network/public/translations/common/Messages_it_IT.json b/packages/manager/apps/pci-private-network/public/translations/common/Messages_it_IT.json index 6cfd5230041b..d50ab40a926a 100644 --- a/packages/manager/apps/pci-private-network/public/translations/common/Messages_it_IT.json +++ b/packages/manager/apps/pci-private-network/public/translations/common/Messages_it_IT.json @@ -89,5 +89,6 @@ "common_dual_list_target_move_all": "Elimina tutto", "common_dual_list_target_search": "Cerca nel contenuto di destinazione", "common_file_dropAreaSingle": "Trascina e rilascia un file o", - "common_file_notSingleError": "Puoi aggiungere un solo file" + "common_file_notSingleError": "Puoi aggiungere un solo file", + "common_find_out_more_here": "Per maggiori informazioni, clicca qui." } diff --git a/packages/manager/apps/pci-private-network/public/translations/common/Messages_pl_PL.json b/packages/manager/apps/pci-private-network/public/translations/common/Messages_pl_PL.json index cee5750c53b8..5a36c40d5f84 100644 --- a/packages/manager/apps/pci-private-network/public/translations/common/Messages_pl_PL.json +++ b/packages/manager/apps/pci-private-network/public/translations/common/Messages_pl_PL.json @@ -89,5 +89,6 @@ "common_dual_list_target_move_all": "Usuń wszystko", "common_dual_list_target_search": "Szukaj w treści docelowej", "common_file_dropAreaSingle": "Przeciągnij/upuść plik lub", - "common_file_notSingleError": "Możesz dodać tylko jeden plik" + "common_file_notSingleError": "Możesz dodać tylko jeden plik", + "common_find_out_more_here": "Więcej informacji znajdziesz tutaj." } diff --git a/packages/manager/apps/pci-private-network/public/translations/common/Messages_pt_PT.json b/packages/manager/apps/pci-private-network/public/translations/common/Messages_pt_PT.json index 6b465e678a1d..6fb89544416f 100644 --- a/packages/manager/apps/pci-private-network/public/translations/common/Messages_pt_PT.json +++ b/packages/manager/apps/pci-private-network/public/translations/common/Messages_pt_PT.json @@ -89,5 +89,6 @@ "common_dual_list_target_move_all": "Eliminar tudo", "common_dual_list_target_search": "Procurar no conteúdo de destino", "common_file_dropAreaSingle": "Arraste e solte um ficheiro ou", - "common_file_notSingleError": "Só um ficheiro pode ser adicionado" + "common_file_notSingleError": "Só um ficheiro pode ser adicionado", + "common_find_out_more_here": "Saiba mais aqui" } diff --git a/packages/manager/apps/pci-private-network/public/translations/new/Messages_de_DE.json b/packages/manager/apps/pci-private-network/public/translations/new/Messages_de_DE.json index 5bf68dcd196a..04d306dbadac 100644 --- a/packages/manager/apps/pci-private-network/public/translations/new/Messages_de_DE.json +++ b/packages/manager/apps/pci-private-network/public/translations/new/Messages_de_DE.json @@ -17,7 +17,7 @@ "pci_projects_project_network_private_create_public_gateway_decription_2": "Erlauben Sie den Instanzen dieses privaten Netzwerks, gesichert auf das Internet zuzugreifen. Wenn diese Option gewählt wird, verwendet sie die bestehende oder erstellt eine Gateway-Instanz. Bitte beachten Sie, dass hierfür zusätzliche Kosten anfallen können. Die Details hierzu finden Sie unten auf der Seite mit der Zusammenfassung.", "pci_projects_project_network_private_create_public_gateway_footer": "Möglicherweise ist diese Option nicht in der ausgewählten Region verfügbar. Mehr Informationen zur Verfügbarkeit der Produkte pro Region finden Sie hier.", "pci_projects_project_network_private_create_layer_2_options": "Netzwerk-Optionen von Layer 2:", - "pci_projects_project_network_private_create_vlan_tip": "Tipp: Eventuell muss für Ihre Hybrid Cloud dieselbe VLAN-Kennung verwendet werden, wie für Ihren Dedicated Server oder Ihre Hosted Private Cloud. Erfahren Sie hier mehr.", + "pci_projects_project_network_private_create_vlan_tip": "Tipp: Eventuell muss für Ihre Hybrid Cloud dieselbe VLAN-Kennung verwendet werden, wie für Ihren Dedicated Server oder Ihre Hosted Private Cloud. ", "pci_projects_project_network_private_create_dhcp_address_distribution_options": "Verteilungsoptionen für DHCP-Adressen:", "pci_projects_project_network_private_create_enable_dhcp": "DHCP für dieses private Netzwerk aktivieren", "pci_projects_project_network_private_create_announce_first_address": "Die erste Adresse eines CIDR als Standard-Gateway anzeigen (DHCP-Option 3)", diff --git a/packages/manager/apps/pci-private-network/public/translations/new/Messages_en_GB.json b/packages/manager/apps/pci-private-network/public/translations/new/Messages_en_GB.json index 935d7b02da3d..666bf348d66d 100644 --- a/packages/manager/apps/pci-private-network/public/translations/new/Messages_en_GB.json +++ b/packages/manager/apps/pci-private-network/public/translations/new/Messages_en_GB.json @@ -17,7 +17,7 @@ "pci_projects_project_network_private_create_public_gateway_decription_2": "Allow instances of this private network to access the internet securely. Selecting this option will use the existing Gateway instance, or create one if required. Please note that this may incur an additional cost (details will be available below in the summary page).", "pci_projects_project_network_private_create_public_gateway_footer": "This option may not be available in the selected region. To learn more about product availability by region, click here.", "pci_projects_project_network_private_create_layer_2_options": "Layer 2 network options:", - "pci_projects_project_network_private_create_vlan_tip": "Tip: You may need to use the same VLAN ID on your dedicated server or Hosted Private Cloud for your hybrid cloud usage. Find out more here.", + "pci_projects_project_network_private_create_vlan_tip": "Tip: You may need to use the same VLAN ID on your dedicated server or Hosted Private Cloud for your hybrid cloud usage. ", "pci_projects_project_network_private_create_dhcp_address_distribution_options": "DHCP address distribution options:", "pci_projects_project_network_private_create_enable_dhcp": "Enable DHCP for this private network", "pci_projects_project_network_private_create_announce_first_address": "Declare the first address of a CIDR given as the default gateway (DHCP option 3)", diff --git a/packages/manager/apps/pci-private-network/public/translations/new/Messages_es_ES.json b/packages/manager/apps/pci-private-network/public/translations/new/Messages_es_ES.json index 1814878f9cf0..0ec75e61d160 100644 --- a/packages/manager/apps/pci-private-network/public/translations/new/Messages_es_ES.json +++ b/packages/manager/apps/pci-private-network/public/translations/new/Messages_es_ES.json @@ -17,7 +17,7 @@ "pci_projects_project_network_private_create_public_gateway_decription_2": "Autorice a las instancias de esta red privada a acceder a internet de forma segura. Al seleccionar esta opción, se utilizará la instancia Gateway existente o se creará una en caso necesario. Tenga en cuenta que esta opción puede generar gastos adicionales (ver la página de resumen para más información).", "pci_projects_project_network_private_create_public_gateway_footer": "Es posible que esta opción no esté disponible en la región seleccionada. Para más información sobre la disponibilidad de las soluciones por región, haga clic aquí.", "pci_projects_project_network_private_create_layer_2_options": "Opciones de red de la capa 2 (L2):", - "pci_projects_project_network_private_create_vlan_tip": "Consejo: para un uso de cloud híbrido, es posible que tenga que utilizar el mismo ID de VLAN en su servidor dedicado o Hosted Private Cloud. Más información aquí.", + "pci_projects_project_network_private_create_vlan_tip": "Consejo: para un uso de cloud híbrido, es posible que tenga que utilizar el mismo ID de VLAN en su servidor dedicado o Hosted Private Cloud. ", "pci_projects_project_network_private_create_dhcp_address_distribution_options": "Opciones de distribución de direcciones DHCP:", "pci_projects_project_network_private_create_enable_dhcp": "Activar DHCP para esta red privada", "pci_projects_project_network_private_create_announce_first_address": "Anunciar la primera dirección de un CIDR determinado como puerta de enlace predeterminada (DHCP opción 3)", diff --git a/packages/manager/apps/pci-private-network/public/translations/new/Messages_fr_CA.json b/packages/manager/apps/pci-private-network/public/translations/new/Messages_fr_CA.json index 696930497d44..bed92c969f72 100644 --- a/packages/manager/apps/pci-private-network/public/translations/new/Messages_fr_CA.json +++ b/packages/manager/apps/pci-private-network/public/translations/new/Messages_fr_CA.json @@ -17,7 +17,7 @@ "pci_projects_project_network_private_create_public_gateway_decription_2": "Autorisez les instances de ce réseau privé à accéder à Internet de manière sécurisée. La sélection de cette option utilisera l’instance Gateway existante ou en créera une le cas échéant. Veuillez noter que cela peut entraîner des frais supplémentaires (des détails seront disponibles ci-dessous, dans la page de résumé).", "pci_projects_project_network_private_create_public_gateway_footer": "Cette option peut ne pas être disponible dans la région sélectionnée. Pour en savoir plus sur la disponibilité des produits par région, cliquez ici.", "pci_projects_project_network_private_create_layer_2_options": "Options réseau du layer 2 :", - "pci_projects_project_network_private_create_vlan_tip": "Astuce : vous devrez peut-être utiliser le même identifiant de VLAN sur votre serveur dédié ou votre Hosted Private Cloud pour vos usages de cloud hybride. En savoir plus ici.", + "pci_projects_project_network_private_create_vlan_tip": "Astuce : vous devrez peut-être utiliser le même identifiant de VLAN sur votre serveur dédié ou votre Hosted Private Cloud pour vos usages de cloud hybride. ", "pci_projects_project_network_private_create_dhcp_address_distribution_options": "Options de distribution des adresses DHCP:", "pci_projects_project_network_private_create_enable_dhcp": "Activer DHCP pour ce réseau privé", "pci_projects_project_network_private_create_announce_first_address": "Annoncer la première adresse d'un CIDR donné comme passerelle par défaut (DHCP option 3)", diff --git a/packages/manager/apps/pci-private-network/public/translations/new/Messages_fr_FR.json b/packages/manager/apps/pci-private-network/public/translations/new/Messages_fr_FR.json index 696930497d44..bed92c969f72 100644 --- a/packages/manager/apps/pci-private-network/public/translations/new/Messages_fr_FR.json +++ b/packages/manager/apps/pci-private-network/public/translations/new/Messages_fr_FR.json @@ -17,7 +17,7 @@ "pci_projects_project_network_private_create_public_gateway_decription_2": "Autorisez les instances de ce réseau privé à accéder à Internet de manière sécurisée. La sélection de cette option utilisera l’instance Gateway existante ou en créera une le cas échéant. Veuillez noter que cela peut entraîner des frais supplémentaires (des détails seront disponibles ci-dessous, dans la page de résumé).", "pci_projects_project_network_private_create_public_gateway_footer": "Cette option peut ne pas être disponible dans la région sélectionnée. Pour en savoir plus sur la disponibilité des produits par région, cliquez ici.", "pci_projects_project_network_private_create_layer_2_options": "Options réseau du layer 2 :", - "pci_projects_project_network_private_create_vlan_tip": "Astuce : vous devrez peut-être utiliser le même identifiant de VLAN sur votre serveur dédié ou votre Hosted Private Cloud pour vos usages de cloud hybride. En savoir plus ici.", + "pci_projects_project_network_private_create_vlan_tip": "Astuce : vous devrez peut-être utiliser le même identifiant de VLAN sur votre serveur dédié ou votre Hosted Private Cloud pour vos usages de cloud hybride. ", "pci_projects_project_network_private_create_dhcp_address_distribution_options": "Options de distribution des adresses DHCP:", "pci_projects_project_network_private_create_enable_dhcp": "Activer DHCP pour ce réseau privé", "pci_projects_project_network_private_create_announce_first_address": "Annoncer la première adresse d'un CIDR donné comme passerelle par défaut (DHCP option 3)", diff --git a/packages/manager/apps/pci-private-network/public/translations/new/Messages_it_IT.json b/packages/manager/apps/pci-private-network/public/translations/new/Messages_it_IT.json index acaa961765bb..94a9acb9b9a7 100644 --- a/packages/manager/apps/pci-private-network/public/translations/new/Messages_it_IT.json +++ b/packages/manager/apps/pci-private-network/public/translations/new/Messages_it_IT.json @@ -17,7 +17,7 @@ "pci_projects_project_network_private_create_public_gateway_decription_2": "Autorizza le istanze di questa rete privata ad accedere a Internet in modo sicuro. Selezionare questa opzione comporta l’utilizzo dell'istanza Gateway esistente o la creazione di una nuova, se necessario. Ti ricordiamo che questa azione potrebbe comportare spese aggiuntive (maggiori dettagli disponibili qui sotto, nella pagina di riepilogo).", "pci_projects_project_network_private_create_public_gateway_footer": "Questa opzione potrebbe non essere disponibile nella Region selezionata. Per maggiori informazioni sulla disponibilità dei servizi per Region, clicca qui.", "pci_projects_project_network_private_create_layer_2_options": "Opzioni di rete del layer 2:", - "pci_projects_project_network_private_create_vlan_tip": "Suggerimento: per i tuoi utilizzi di Cloud ibrido, potrebbe essere necessario usare lo stesso VLAN ID sul server dedicato o Hosted Private Cloud. Per maggiori informazioni, clicca qui.", + "pci_projects_project_network_private_create_vlan_tip": "Suggerimento: per i tuoi utilizzi di Cloud ibrido, potrebbe essere necessario usare lo stesso VLAN ID sul server dedicato o Hosted Private Cloud. ", "pci_projects_project_network_private_create_dhcp_address_distribution_options": "Opzioni DHCP di distribuzione degli indirizzi:", "pci_projects_project_network_private_create_enable_dhcp": "Attivare DHCP per questa rete privata", "pci_projects_project_network_private_create_announce_first_address": "Annunciare il primo indirizzo di un CIDR come gateway predefinito (DHCP opzione 3)", diff --git a/packages/manager/apps/pci-private-network/public/translations/new/Messages_pl_PL.json b/packages/manager/apps/pci-private-network/public/translations/new/Messages_pl_PL.json index ae06e7c73c87..c1a4fac55ee6 100644 --- a/packages/manager/apps/pci-private-network/public/translations/new/Messages_pl_PL.json +++ b/packages/manager/apps/pci-private-network/public/translations/new/Messages_pl_PL.json @@ -17,7 +17,7 @@ "pci_projects_project_network_private_create_public_gateway_decription_2": "Zezwól instancjom tej prywatnej sieci na bezpieczny dostęp do Internetu. Wybranie tej opcji spowoduje użycie istniejącej instancji Gateway lub utworzenie instancji, jeśli zajdzie taka potrzeba. Pamiętaj, że może się to wiązać z dodatkowymi kosztami (szczegółowe informacje będą dostępne poniżej, na stronie z podsumowaniem).", "pci_projects_project_network_private_create_public_gateway_footer": "Ta opcja może nie być dostępna w wybranym regionie. Aby uzyskać więcej informacji na temat dostępności produktów dla każdego regionu, kliknij tutaj.", "pci_projects_project_network_private_create_layer_2_options": "Opcje sieciowe warstwy 2:", - "pci_projects_project_network_private_create_vlan_tip": "Wskazówka: w przypadku korzystania z chmury hybrydowej może być konieczne użycie tego samego identyfikatora VLAN na serwerze dedykowanym lub Hosted Private Cloud. Więcej informacji znajdziesz tutaj.", + "pci_projects_project_network_private_create_vlan_tip": "Wskazówka: w przypadku korzystania z chmury hybrydowej może być konieczne użycie tego samego identyfikatora VLAN na serwerze dedykowanym lub Hosted Private Cloud. ", "pci_projects_project_network_private_create_dhcp_address_distribution_options": "Opcje dystrybucji adresów DHCP:", "pci_projects_project_network_private_create_enable_dhcp": "Włącz DHCP dla tej prywatnej sieci", "pci_projects_project_network_private_create_announce_first_address": "Ustaw pierwszy adres danego CIDR jako bramę domyślną (DHCP opcja 3)", diff --git a/packages/manager/apps/pci-private-network/public/translations/new/Messages_pt_PT.json b/packages/manager/apps/pci-private-network/public/translations/new/Messages_pt_PT.json index 2f10dd6d867a..ef43e1c55373 100644 --- a/packages/manager/apps/pci-private-network/public/translations/new/Messages_pt_PT.json +++ b/packages/manager/apps/pci-private-network/public/translations/new/Messages_pt_PT.json @@ -17,7 +17,7 @@ "pci_projects_project_network_private_create_public_gateway_decription_2": "Autorize as instâncias desta rede privada a aceder à Internet de forma segura. A escolha desta opção utilizará a instância Gateway existente ou criará uma se necessário. Tenha em conta que isto pode implicar custos adicionais (estarão disponíveis mais pormenores na página de resumo).", "pci_projects_project_network_private_create_public_gateway_footer": "Esta opção pode não estar disponível na região selecionada. Para saber mais sobre a disponibilidade dos produtos por região, clique aqui.", "pci_projects_project_network_private_create_layer_2_options": "Opções de rede do layer 2:", - "pci_projects_project_network_private_create_vlan_tip": "Dica: para as utilizações de cloud híbrida, poderá ter de utilizar o mesmo identificador de VLAN no seu servidor dedicado ou no seu Hosted Private Cloud. Saiba mais aqui.", + "pci_projects_project_network_private_create_vlan_tip": "Dica: para as utilizações de cloud híbrida, poderá ter de utilizar o mesmo identificador de VLAN no seu servidor dedicado ou no seu Hosted Private Cloud. ", "pci_projects_project_network_private_create_dhcp_address_distribution_options": "Opções de distribuição dos endereços DHCP:", "pci_projects_project_network_private_create_enable_dhcp": "Ativar DHCP para esta rede privada", "pci_projects_project_network_private_create_announce_first_address": "Anunciar o primeiro endereço de um CIDR dado como gateway predefinido (DHCP opção 3)", diff --git a/packages/manager/apps/pci-private-network/src/constants.ts b/packages/manager/apps/pci-private-network/src/constants.ts index 84082f938529..81aa6e9bd2d1 100644 --- a/packages/manager/apps/pci-private-network/src/constants.ts +++ b/packages/manager/apps/pci-private-network/src/constants.ts @@ -95,6 +95,38 @@ export const GUIDE_LINKS = { WS: `${HELP_ROOT}es${REGION_AVAILABILITY_URL}`, WE: `${HELP_ROOT}en${REGION_AVAILABILITY_URL}`, }, + VLAN: { + ASIA: + 'https://help.ovhcloud.com/csm/asia-dedicated-servers-multiple-vlans?id=kb_article_view&sysparm_article=KB0043360', + AU: + 'https://help.ovhcloud.com/csm/en-au-dedicated-servers-multiple-vlans?id=kb_article_view&sysparm_article=KB0043715', + DEFAULT: + 'https://help.ovhcloud.com/csm/en-ie-dedicated-servers-multiple-vlans?id=kb_article_view&sysparm_article=KB0043720', + DE: + 'https://help.ovhcloud.com/csm/de-dedicated-servers-multiple-vlans?id=kb_article_view&sysparm_article=KB0043362', + CA: + 'https://help.ovhcloud.com/csm/en-ca-dedicated-servers-multiple-vlans?id=kb_article_view&sysparm_article=KB0043367', + ES: + 'https://help.ovhcloud.com/csm/es-es-dedicated-servers-multiple-vlans?id=kb_article_view&sysparm_article=KB0043366', + FR: + 'https://help.ovhcloud.com/csm/fr-dedicated-servers-multiple-vlans?id=kb_article_view&sysparm_article=KB0043369', + GB: + 'https://help.ovhcloud.com/csm/en-gb-dedicated-servers-multiple-vlans?id=kb_article_view&sysparm_article=KB0030378', + IT: + 'https://help.ovhcloud.com/csm/it-dedicated-servers-multiple-vlans?id=kb_article_view&sysparm_article=KB0043371', + PT: + 'https://help.ovhcloud.com/csm/pt-dedicated-servers-multiple-vlans?id=kb_article_view&sysparm_article=KB0043374', + PL: + 'https://help.ovhcloud.com/csm/pl-dedicated-servers-multiple-vlans?id=kb_article_view&sysparm_article=KB0043372', + QC: + 'https://help.ovhcloud.com/csm/fr-ca-dedicated-servers-multiple-vlans?id=kb_article_view&sysparm_article=KB0043370', + SG: + 'https://help.ovhcloud.com/csm/en-sg-dedicated-servers-multiple-vlans?id=kb_article_view&sysparm_article=KB0043365', + WS: + 'https://help.ovhcloud.com/csm/en-dedicated-servers-multiple-vlans?id=kb_article_view&sysparm_article=KB0043368', + US: + 'https://support.us.ovhcloud.com/hc/en-us/articles/25276312027027-Creating-Multiple-vLANs-in-a-vRack', + }, }; export const LOCAL_ZONE_INFO_URL = { diff --git a/packages/manager/apps/pci-private-network/src/pages/new/steps/ConfigurationStep.tsx b/packages/manager/apps/pci-private-network/src/pages/new/steps/ConfigurationStep.tsx index 15f99bd9f640..d88a319b6846 100644 --- a/packages/manager/apps/pci-private-network/src/pages/new/steps/ConfigurationStep.tsx +++ b/packages/manager/apps/pci-private-network/src/pages/new/steps/ConfigurationStep.tsx @@ -1,8 +1,10 @@ import { StepComponent, useNotifications, + Links, + LinkType, } from '@ovh-ux/manager-react-components'; - +import { OdsHTMLAnchorElementTarget } from '@ovhcloud/ods-common-core'; import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; import { useTranslation } from 'react-i18next'; @@ -112,6 +114,9 @@ export default function ConfigurationStep({ GUIDE_LINKS.REGION_AVAILABILITY[ovhSubsidiary] || GUIDE_LINKS.REGION_AVAILABILITY.DEFAULT; + const VLAN_GUIDE_URL = + GUIDE_LINKS.VLAN[ovhSubsidiary] || GUIDE_LINKS.VLAN.DEFAULT; + // To check isGatewayAvailableInRegion const { data: productAvailability } = useProductAvailability( projectId, @@ -409,9 +414,13 @@ export default function ConfigurationStep({ level={ODS_TEXT_LEVEL.body} size={ODS_TEXT_SIZE._400} > - {t( - 'new:pci_projects_project_network_private_create_vlan_tip', - )} + {t('pci_projects_project_network_private_create_vlan_tip')} +
From 8a8890be764293566c1e0bc363a0c9f0b3f564a8 Mon Sep 17 00:00:00 2001 From: Pierre-Philippe Prevost Date: Thu, 10 Oct 2024 16:45:19 +0200 Subject: [PATCH 10/11] fix(pci-rancher): fix dash and date (#13026) ref: TAPC-1615 Signed-off-by: Pierre-Philippe Co-authored-by: CDS Translator Agent --- .../manager/apps/pci-rancher/package.json | 1 + .../Table/NumberCell/NumberCell.component.tsx | 17 ++++++++++ .../TableContainer.component.tsx | 3 +- .../RancherDetail/RancherDetail.component.tsx | 32 +++++++++++++++---- 4 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 packages/manager/apps/pci-rancher/src/components/Table/NumberCell/NumberCell.component.tsx diff --git a/packages/manager/apps/pci-rancher/package.json b/packages/manager/apps/pci-rancher/package.json index 3a80a8b9c911..45fab509ef6e 100644 --- a/packages/manager/apps/pci-rancher/package.json +++ b/packages/manager/apps/pci-rancher/package.json @@ -27,6 +27,7 @@ "@ovh-ux/manager-react-components": "^1.38.0", "@ovh-ux/manager-react-core-application": "^0.10.2", "@ovh-ux/manager-react-shell-client": "^0.7.2", + "@ovh-ux/manager-core-utils": "*", "@ovh-ux/request-tagger": "^0.3.0", "@ovh-ux/shell": "^3.8.0", "@ovhcloud/ods-common-core": "17.2.2", diff --git a/packages/manager/apps/pci-rancher/src/components/Table/NumberCell/NumberCell.component.tsx b/packages/manager/apps/pci-rancher/src/components/Table/NumberCell/NumberCell.component.tsx new file mode 100644 index 000000000000..c627d6512725 --- /dev/null +++ b/packages/manager/apps/pci-rancher/src/components/Table/NumberCell/NumberCell.component.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import { OsdsText } from '@ovhcloud/ods-components/react'; +import { Cell } from '@tanstack/react-table'; +import { RancherService } from '@/types/api.type'; +import '../Table.scss'; + +interface DisplayCellInterface { + cell: Cell; +} + +function DisplayCellNumber({ cell }: Readonly) { + const number = cell.renderValue(); + return {number}; +} + +export default DisplayCellNumber; diff --git a/packages/manager/apps/pci-rancher/src/components/Table/TableContainer/TableContainer.component.tsx b/packages/manager/apps/pci-rancher/src/components/Table/TableContainer/TableContainer.component.tsx index 0d4f7aaf6546..f10a8bbfa256 100644 --- a/packages/manager/apps/pci-rancher/src/components/Table/TableContainer/TableContainer.component.tsx +++ b/packages/manager/apps/pci-rancher/src/components/Table/TableContainer/TableContainer.component.tsx @@ -22,6 +22,7 @@ import DisplayCellText from '../TextCell/TextCell.component'; import '../Table.scss'; import { deleteRancherServiceQueryKey } from '@/data/api/services'; import StatusChip from '../../StatusChip/StatusChip.component'; +import DisplayCellNumber from '../NumberCell/NumberCell.component'; export default function TableContainer({ data, @@ -71,7 +72,7 @@ export default function TableContainer({ id: 'numberOfCpu', header: t('numberOfCpu'), accessorFn: (row) => row.currentState.usage?.orchestratedVcpus, - cell: DisplayCellText, + cell: DisplayCellNumber, }, { id: 'status', diff --git a/packages/manager/apps/pci-rancher/src/components/layout-helpers/Dashboard/RancherDetail/RancherDetail.component.tsx b/packages/manager/apps/pci-rancher/src/components/layout-helpers/Dashboard/RancherDetail/RancherDetail.component.tsx index 8182c28a1eac..2d52c2d7191c 100644 --- a/packages/manager/apps/pci-rancher/src/components/layout-helpers/Dashboard/RancherDetail/RancherDetail.component.tsx +++ b/packages/manager/apps/pci-rancher/src/components/layout-helpers/Dashboard/RancherDetail/RancherDetail.component.tsx @@ -1,4 +1,6 @@ import { format } from 'date-fns'; +import * as locales from 'date-fns/locale'; +import { getDateFnsLocale } from '@ovh-ux/manager-core-utils'; import { CommonTitle, @@ -22,7 +24,7 @@ import { OsdsText, OsdsTile, } from '@ovhcloud/ods-components/react'; -import React, { useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { useHref } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; @@ -59,7 +61,11 @@ const RancherDetail = ({ updateOfferErrorMessage, versions, }: RancherDetailProps) => { - const { t } = useTranslation(['dashboard', 'updateSoftware', 'listing']); + const { t, i18n } = useTranslation([ + 'dashboard', + 'updateSoftware', + 'listing', + ]); const trackAction = useTrackingAction(); const hrefEdit = useHref('./edit'); const hrefUpdateSoftware = useHref('./update-software'); @@ -120,12 +126,24 @@ const RancherDetail = ({ const onAccessRancherUrl = () => trackAction(TrackingPageView.DetailRancher, TrackingEvent.accessUi); - const shouldDisplayUpdateSoftware = getLatestVersionAvailable(rancher, versions) && isReadyStatus && !updateSoftwareResponseType; + const userLocale = getDateFnsLocale(i18n.language); + + const displayDate = useCallback( + (value: string) => + format(new Date(dateUsage), value, { + locale: + userLocale in locales + ? locales[userLocale as keyof typeof locales] + : locales.fr, + }), + [userLocale, locales, dateUsage], + ); + const isEligibleForUpgrade = plan === RancherPlanName.OVHCLOUD_EDITION; return ( @@ -248,14 +266,14 @@ const RancherDetail = ({ - {rancher.currentState.usage?.orchestratedVcpus || '-'} + {rancher.currentState.usage?.orchestratedVcpus} - {dateUsage && ( + {displayDate && (
{t('last_update_date', { - date: format(dateUsage, 'yyyy_MM_dd'), - hour: format(dateUsage, 'HH:mm:ss'), + date: displayDate('PPPP'), + hour: displayDate('HH:mm:ss'), })}
From 0ec7fc0a18489f45d73ccaf684b2cdcf97fda6a9 Mon Sep 17 00:00:00 2001 From: tsiorifamonjena Date: Fri, 11 Oct 2024 11:40:43 +0200 Subject: [PATCH 11/11] fix(pci-private-network): fixing transaltion on config page ref: TAPC-735 Signed-off-by: tsiorifamonjena --- .../src/pages/new/steps/ConfigurationStep.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/manager/apps/pci-private-network/src/pages/new/steps/ConfigurationStep.tsx b/packages/manager/apps/pci-private-network/src/pages/new/steps/ConfigurationStep.tsx index d88a319b6846..3a8dfaea4d88 100644 --- a/packages/manager/apps/pci-private-network/src/pages/new/steps/ConfigurationStep.tsx +++ b/packages/manager/apps/pci-private-network/src/pages/new/steps/ConfigurationStep.tsx @@ -414,7 +414,9 @@ export default function ConfigurationStep({ level={ODS_TEXT_LEVEL.body} size={ODS_TEXT_SIZE._400} > - {t('pci_projects_project_network_private_create_vlan_tip')} + {t( + 'new:pci_projects_project_network_private_create_vlan_tip', + )}