From d389075fe993d122e9166e2b10476f848be60467 Mon Sep 17 00:00:00 2001 From: "Thibault Barske (Tibs)" Date: Fri, 18 Oct 2024 10:22:51 +0200 Subject: [PATCH 01/43] feat(hycu): add product HYCU for OVHCloud (#13244) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ref: MANAGER-14488 Signed-off-by: Thibault Barske Co-authored-by: David Arsène --- yarn.lock | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/yarn.lock b/yarn.lock index 98800e0a3df0..47ad890e91c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -938,12 +938,12 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.7.tgz#9a5226f92f0c5c8ead550b750f5608e766c8ce85" integrity sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw== -"@babel/parser@^7.25.4", "@babel/parser@^7.25.7": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.8.tgz#f6aaf38e80c36129460c1657c0762db584c9d5e2" - integrity sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ== +"@babel/parser@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.7.tgz#99b927720f4ddbfeb8cd195a363ed4532f87c590" + integrity sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw== dependencies: - "@babel/types" "^7.25.8" + "@babel/types" "^7.25.7" "@babel/parser@^7.7.0": version "7.10.3" @@ -9925,7 +9925,9 @@ resolved "https://registry.npmjs.org/@vitest/spy/-/spy-1.3.1.tgz#814245d46d011b99edd1c7528f5725c64e85a88b" integrity sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig== dependencies: - tinyspy "^2.2.0" + "@vitest/pretty-format" "2.1.2" + magic-string "^0.30.11" + pathe "^1.1.2" "@vitest/spy@1.4.0": version "1.4.0" @@ -21133,7 +21135,7 @@ magic-string@^0.30.0, magic-string@^0.30.1, magic-string@^0.30.5, magic-string@^ dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" -magic-string@^0.30.10: +magic-string@^0.30.10, magic-string@^0.30.11: version "0.30.11" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.11.tgz#301a6f93b3e8c2cb13ac1a7a673492c0dfd12954" integrity sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A== From 7674150f2fca3f2fe233698671f57630bcfe9537 Mon Sep 17 00:00:00 2001 From: Nicode Date: Fri, 18 Oct 2024 11:28:54 +0200 Subject: [PATCH 02/43] feat(veeam-backup): add new product veeam-backup (#12611) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ref: MANAGER-14740 Signed-off-by: Nicolas Pierre-charles Co-authored-by: David Arsène --- yarn.lock | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/yarn.lock b/yarn.lock index 47ad890e91c0..4815b3d6a803 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9929,6 +9929,13 @@ magic-string "^0.30.11" pathe "^1.1.2" +"@vitest/spy@1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-1.3.1.tgz#814245d46d011b99edd1c7528f5725c64e85a88b" + integrity sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig== + dependencies: + tinyspy "^2.2.0" + "@vitest/spy@1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-1.4.0.tgz#cf953c93ae54885e801cbe6b408a547ae613f26c" From c19d1f2b2f0ea5c41b9c91f4f3c8bad46f440c47 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Thu, 17 Oct 2024 22:02:22 +0200 Subject: [PATCH 03/43] feat(hycu): fix listing wording ref: MANAGER-15691 Signed-off-by: Thibault Barske --- .../src/hooks/service/usePackLabel.spec.ts | 47 ------------------- .../hycu/src/hooks/service/usePackLabel.ts | 11 ----- .../hycu/src/pages/listing/Listing.page.tsx | 17 ++----- 3 files changed, 5 insertions(+), 70 deletions(-) delete mode 100644 packages/manager/apps/hycu/src/hooks/service/usePackLabel.spec.ts delete mode 100644 packages/manager/apps/hycu/src/hooks/service/usePackLabel.ts diff --git a/packages/manager/apps/hycu/src/hooks/service/usePackLabel.spec.ts b/packages/manager/apps/hycu/src/hooks/service/usePackLabel.spec.ts deleted file mode 100644 index bcee312401b5..000000000000 --- a/packages/manager/apps/hycu/src/hooks/service/usePackLabel.spec.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { describe, expect, it, test, vi } from 'vitest'; -import { usePackTypeLabel } from './usePackLabel'; - -vi.mock('react-i18next', () => ({ - useTranslation: () => ({ - t: (translationKey: string) => `${translationKey}_translated`, - i18n: { - // eslint-disable-next-line @typescript-eslint/no-empty-function - changeLanguage: () => new Promise(() => {}), - }, - }), -})); - -describe('get service key type translation ', () => { - const useCases: { - type: string; - label: string; - }[] = [ - { - type: 'hycu-cloud-vm-pack-25', - label: '25 VMs', - }, - { - type: 'hycu-cloud-vm-pack-250', - label: '250 VMs', - }, - ]; - test.each(useCases)( - 'should return the right translation key for $type', - ({ type, label }) => { - // given type and translationKey - // when - const result = usePackTypeLabel(type); - // then - expect(result).toBe(label); - }, - ); - it('should return type if unexpected value', () => { - // given - const type = 'hycu-cloud-vm-pack-123'; - // when - const result = usePackTypeLabel(type); - - // then - expect(result).toBe('hycu_cloud_vm_pack_unknown_translated'); - }); -}); diff --git a/packages/manager/apps/hycu/src/hooks/service/usePackLabel.ts b/packages/manager/apps/hycu/src/hooks/service/usePackLabel.ts deleted file mode 100644 index 617f8386e151..000000000000 --- a/packages/manager/apps/hycu/src/hooks/service/usePackLabel.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { useTranslation } from 'react-i18next'; -import { packTypeLabel } from '@/constants'; - -export const usePackTypeLabel = (packType: string) => { - const { t } = useTranslation('common'); - - return ( - packTypeLabel[packType as keyof typeof packTypeLabel] ?? - t('hycu_cloud_vm_pack_unknown') - ); -}; diff --git a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx index 454c63a6f3bb..6d29ba59cc2c 100644 --- a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx +++ b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx @@ -31,16 +31,9 @@ import HYCU_CONFIG from '@/hycu.config'; import { IHycuDetails } from '@/type/hycu.details.interface'; import { urls, subRoutes } from '@/routes/routes.constant'; -import { usePackTypeLabel } from '@/hooks/service/usePackLabel'; import HycuActionMenu from './menu/HycuActionMenu.component'; import { getStatusColor } from '@/utils/statusColor'; -const dateFormat: Intl.DateTimeFormatOptions = { - day: '2-digit', - month: '2-digit', - year: 'numeric', -}; - /* ========= datagrid cells ========= */ const DatagridIdCell = (hycuDetail: IHycuDetails) => { const navigate = useNavigate(); @@ -87,13 +80,13 @@ const DatagridCommercialNameCell = (hycuDetail: IHycuDetails) => { resourceName: hycuDetail.serviceName, }); - const productName = usePackTypeLabel( - serviceDetails?.data.resource.product.name, - ); - return ( - {isLoading ? : productName} + {isLoading ? ( + + ) : ( + serviceDetails?.data.resource.product.description + )} ); }; From b898339660b784308a37f4e0ef3db8f873c5e277 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Thu, 17 Oct 2024 21:49:31 +0200 Subject: [PATCH 04/43] feat(hycu): change onboarding wording ref: MANAGER-15691 Signed-off-by: Thibault Barske --- .../public/translations/hycu/onboarding/Messages_fr_FR.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_fr_FR.json index 150d27c36cf5..8be7e255cb5b 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_fr_FR.json @@ -2,10 +2,10 @@ "orderButtonLabel": "Commencer", "moreInfoButtonLabel": "En savoir plus", "hycu_onboarding_category_tutorial": "Tutoriel", - "hycu_onboarding_guide1_title": "Guides et documentations", - "hycu_onboarding_guide1_description": "Découvrez nos guides et documentations détaillés pour vous accompagner dans votre projet.", + "hycu_onboarding_guide1_title": "Guides et documentation", + "hycu_onboarding_guide1_description": "Découvrez nos guides et notre documentation détaillée pour vous accompagner dans votre projet.", "hycu_onboarding_guide2_title": "Nutanix on OVHcloud", - "hycu_onboarding_guide2_description": "Découvrez notre plateforme hyperconvergée (HCI) évolutive et prête à l'emploi en quelques heures. Disponible en offre packagée ou offre BYOL (Bring Your Own Licence), elle associe les licences logicielles de la Nutanix Cloud Platform (NCP) et les infrastructures Hosted Private Cloud d'OVHcloud dédiées et qualifiées Nutanix.", + "hycu_onboarding_guide2_description": "La solution Nutanix on OVHcloud associe les licences de la Nutanix Cloud Platform (NCP) et les infrastructures Hosted Private Cloud d'OVHcloud dédiées et qualifiées Nutanix, pour pré-déployer un environnement hyperconvergé (HCI) Nutanix prêt à l'emploi.", "hycu_onboarding_guide3_title": "Plan de Reprise d'Activité (PRA)", "hycu_onboarding_guide3_description": "Appuyez-vous sur le service HYCU for OVHcloud pour une reprise d'activité contrôlée et performante, avec un coût maîtrisé et sans surprise." } From 2f320547a022b1961902c0a2ec630c7d038aff1c Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Fri, 18 Oct 2024 15:11:18 +0200 Subject: [PATCH 05/43] feat(hycu): add hycu dashboard ref: MANAGER-14499 Signed-off-by: Thibault Barske --- packages/manager/apps/hycu/.gitignore | 1 + packages/manager/apps/hycu/package.json | 7 +- .../dashboard/Messages_fr_FR.json | 7 - .../translations/hycu/Messages_fr_FR.json | 6 +- .../hycu/dashboard/Messages_fr_FR.json | 25 +++ .../hycu/listing/Messages_fr_FR.json | 4 - .../components/Loading/Loading.component.tsx | 1 + .../manager/apps/hycu/src/data/api/hycu.ts | 15 +- .../apps/hycu/src/hooks/api/license.ts | 15 ++ .../hooks/shell/useNavigationGetUrl.spec.tsx | 44 +++++ .../src/hooks/shell/useNavigationGetUrl.ts | 21 +++ packages/manager/apps/hycu/src/mocks/index.ts | 1 + .../src/mocks/licenseHycu/licenseHycu.data.ts | 2 +- .../hycu/src/mocks/licenseHycu/licenseHycu.ts | 22 ++- .../serviceLicenseHycu.data.ts | 95 +++++++++++ .../serviceLicenseHycu/serviceLicenseHycu.ts | 25 +++ .../pages/dashboard/Dashboard.page.spec.tsx | 31 ++++ .../src/pages/dashboard/Dashboard.page.tsx | 39 +++-- .../BillingInformationsTile.spec.tsx | 32 ++++ .../BillingInformationsTile.tsx | 128 +++++++++++++++ .../DashboardGeneralInformation.page.tsx | 20 ++- .../GeneralInformationsTile.spec.tsx | 99 ++++++++++++ .../GeneralInformationsTile.tsx | 150 ++++++++++++++++++ .../ShortcutsTile/ShortcutsTile.spec.tsx | 65 ++++++++ .../ShortcutsTile/ShortcutsTile.tsx | 65 ++++++++ .../hycu/src/pages/dashboard/tab2/index.tsx | 7 - .../hycu/src/pages/listing/Listing.page.tsx | 4 +- .../hycu/src/pages/listing/Listing.spec.tsx | 6 +- .../manager/apps/hycu/src/routes/routes.tsx | 11 -- .../apps/hycu/src/utils/statusColor.ts | 1 + .../apps/hycu/src/utils/tests/TestApp.tsx | 4 +- .../apps/hycu/src/utils/tests/init.i18n.ts | 31 ++-- .../hycu/src/utils/tests/renderTestApp.tsx | 37 +++-- packages/manager/apps/hycu/vitest.config.js | 3 + yarn.lock | 41 ++++- 35 files changed, 975 insertions(+), 90 deletions(-) delete mode 100644 packages/manager/apps/hycu/public/translations/dashboard/Messages_fr_FR.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json create mode 100644 packages/manager/apps/hycu/src/hooks/api/license.ts create mode 100644 packages/manager/apps/hycu/src/hooks/shell/useNavigationGetUrl.spec.tsx create mode 100644 packages/manager/apps/hycu/src/hooks/shell/useNavigationGetUrl.ts create mode 100644 packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.data.ts create mode 100644 packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.ts create mode 100644 packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.spec.tsx create mode 100644 packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.spec.tsx create mode 100644 packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx create mode 100644 packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx create mode 100644 packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx create mode 100644 packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx create mode 100644 packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx delete mode 100644 packages/manager/apps/hycu/src/pages/dashboard/tab2/index.tsx diff --git a/packages/manager/apps/hycu/.gitignore b/packages/manager/apps/hycu/.gitignore index e06831cfdeb4..0b4d91f6ad34 100644 --- a/packages/manager/apps/hycu/.gitignore +++ b/packages/manager/apps/hycu/.gitignore @@ -1,2 +1,3 @@ e2e/reports e2e/coverage +coverage diff --git a/packages/manager/apps/hycu/package.json b/packages/manager/apps/hycu/package.json index c18a149abdfe..6d7d2fcdab32 100644 --- a/packages/manager/apps/hycu/package.json +++ b/packages/manager/apps/hycu/package.json @@ -16,7 +16,8 @@ "start": "lerna exec --stream --scope='@ovh-ux/manager-hycu-app' --include-dependencies -- npm run build --if-present", "start:dev": "lerna exec --stream --scope='@ovh-ux/manager-hycu-app' --include-dependencies -- npm run dev --if-present", "start:watch": "lerna exec --stream --parallel --scope='@ovh-ux/manager-hycu-app' --include-dependencies -- npm run dev:watch --if-present", - "test": "vitest run" + "test": "vitest run", + "test:coverage": "vitest run --coverage" }, "dependencies": { "@ovh-ux/manager-config": "^8.0.0", @@ -48,15 +49,17 @@ "@ovh-ux/manager-vite-config": "^0.8.2", "@testing-library/jest-dom": "^6.5.0", "@testing-library/react": "^16.0.1", + "@testing-library/react-hooks": "^8.0.1", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.13", "@vitejs/plugin-react": "^4.3.2", + "@vitest/coverage-v8": "^2.1.3", "element-internals-polyfill": "^1.3.12", "eslint-plugin-prettier": "^5.2.1", "msw": "2.1.7", "typescript": "^5.1.6", "vite": "^5.2.13", - "vitest": "^2.1.2" + "vitest": "^2.1.3" }, "regions": [ "CA", diff --git a/packages/manager/apps/hycu/public/translations/dashboard/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/dashboard/Messages_fr_FR.json deleted file mode 100644 index f42a27b3366a..000000000000 --- a/packages/manager/apps/hycu/public/translations/dashboard/Messages_fr_FR.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "title": "Dashboard page", - "error_service": "No services info", - "general_informations": "Informations générales", - "tab2": "Tab 2", - "back_link": "Retour à la liste" -} diff --git a/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json index 36d8b913e6d9..a9a3a8b8dee5 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json @@ -2,5 +2,9 @@ "hycu_crumb": "HYCU", "tabs_2": "Tabs 2", "hycu_description": "Simplifiez vos sauvegardes, plans de reprise après sinistre et migrations de votre infrastructure Nutanix. Ce service vous propose différents packs de licences HYCU Hybrid Cloud pour protéger vos charges de travail Nutanix.", - "hycu_cloud_vm_pack_unknown": "Pack inconnu" + "hycu_cloud_vm_pack_unknown": "Pack inconnu", + "hycu_status_activated": "Active", + "hycu_status_toActivate": "À activer", + "hycu_status_pending": "En cours d'activation", + "hycu_status_error": "Erreur d'activation" } diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json new file mode 100644 index 000000000000..4f6227f18791 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json @@ -0,0 +1,25 @@ +{ + "hycu_dashboard_generals_informations_title": "Informations générales", + "hycu_dashboard_label_name": "Nom", + "hycu_dashboard_label_status": "Statut", + "hycu_dashboard_label_pack_type": "Type de pack", + "hycu_dashboard_label_controller_id": "Controller ID", + "hycu_dashboard_label_license_key": "Clé de licence", + "hycu_dashboard_shortcuts_title": "Raccourcis", + "hycu_dashboard_link_activate": "Activer la licence", + "hycu_dashboard_link_reactivate": "Regénérer la licence", + "hycu_dashboard_link_terminated": "Résilier la licence", + "hycu_dashboard_link_change_pack_type": "Modifier le type de pack", + "hycu_dashboard_field_label_contacts": "Contacts", + "hycu_dashboard_contact_type_administrator": "Administrateur", + "hycu_dashboard_contact_type_technical": "Technique", + "hycu_dashboard_contact_type_billing": "Facturation", + "hycu_dashboard_action_billing_terminate": "Résilier", + "hycu_dashboard_field_label_manage_contacts": "Gérer les contacts", + "hycu_dashboard_label_renew": "Renouvellement automatique", + "hycu_dashboard_subscription_title": "Abonnement", + "hycu_dashboard_field_label_date_creation": "Date de création", + "hycu_dashboard_download_license_file": "Télécharger la license", + "hycu_dashboard_back_link": "Retour à la liste", + "hycu_dashboard_wait_for_activation": "En attente d'activation" +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_fr_FR.json index ea668aab4db9..0a8af73eb2b5 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_fr_FR.json @@ -1,8 +1,4 @@ { - "hycu_status_activated": "Active", - "hycu_status_toActivate": "À activer", - "hycu_status_pending": "En cours d'activation", - "hycu_status_error": "Erreur d'activation", "hycu_cloud_vm_pack_unknown": "Pack inconnu", "hycu_name": "Nom", "hycu_controller_id": "Controller ID", diff --git a/packages/manager/apps/hycu/src/components/Loading/Loading.component.tsx b/packages/manager/apps/hycu/src/components/Loading/Loading.component.tsx index bb74a4fa8e15..8623d319f92b 100644 --- a/packages/manager/apps/hycu/src/components/Loading/Loading.component.tsx +++ b/packages/manager/apps/hycu/src/components/Loading/Loading.component.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { OsdsSpinner } from '@ovhcloud/ods-components/react'; +/* v8 ignore start */ export default function Loading() { return (
diff --git a/packages/manager/apps/hycu/src/data/api/hycu.ts b/packages/manager/apps/hycu/src/data/api/hycu.ts index 7068dc242d81..b7ebf0617df5 100644 --- a/packages/manager/apps/hycu/src/data/api/hycu.ts +++ b/packages/manager/apps/hycu/src/data/api/hycu.ts @@ -1,8 +1,10 @@ +import { AxiosResponse } from 'axios'; import { fetchIcebergV6, apiClient } from '@ovh-ux/manager-core-api'; +import { IHycuDetails } from '@/type/hycu.details.interface'; export type GetlicenseHycuListParams = { /** Filter resources on IAM tags */ - iamTags: any; + iamTags: string; }; export const getlicenseHycuListQueryKey = ['get/license/hycu']; @@ -10,7 +12,7 @@ export const getlicenseHycuListQueryKey = ['get/license/hycu']; /** * Manage HYCU licenses : Get list of owned HYCU licenses */ -export const getlicenseHycuList = async ( +export const getlicenseHycuList = ( params: GetlicenseHycuListParams, ): Promise => apiClient.v6.get('/license/hycu', { data: params }); @@ -19,16 +21,13 @@ export type GetlicenseHycuServiceParams = { serviceName?: string; }; -export const getlicenseHycuServiceQueryKey = ( - params: GetlicenseHycuServiceParams, -) => [`get/license/hycu/${params.serviceName}`]; - /** * Manage HYCU licenses : Get HYCU license info */ -export const getlicenseHycuService = async ( +export const getlicenseHycuService = ( params: GetlicenseHycuServiceParams, -): Promise => apiClient.v6.get(`/license/hycu/${params.serviceName}`); +): Promise> => + apiClient.v6.get(`/license/hycu/${params.serviceName}`); /** * Get listing with iceberg V6 diff --git a/packages/manager/apps/hycu/src/hooks/api/license.ts b/packages/manager/apps/hycu/src/hooks/api/license.ts new file mode 100644 index 000000000000..3c7854b22c14 --- /dev/null +++ b/packages/manager/apps/hycu/src/hooks/api/license.ts @@ -0,0 +1,15 @@ +import { AxiosResponse } from 'axios'; +import { DefinedInitialDataOptions, useQuery } from '@tanstack/react-query'; +import { getlicenseHycuService } from '@/data/api/hycu'; +import { IHycuDetails } from '@/type/hycu.details.interface'; + +export const useDetailsLicenseHYCU = ( + serviceName: string, + options?: DefinedInitialDataOptions>, +) => { + return useQuery({ + queryKey: ['license/hycu', 'get', serviceName], + queryFn: () => getlicenseHycuService({ serviceName }), + ...(options ?? {}), + }); +}; diff --git a/packages/manager/apps/hycu/src/hooks/shell/useNavigationGetUrl.spec.tsx b/packages/manager/apps/hycu/src/hooks/shell/useNavigationGetUrl.spec.tsx new file mode 100644 index 000000000000..8d17bd356869 --- /dev/null +++ b/packages/manager/apps/hycu/src/hooks/shell/useNavigationGetUrl.spec.tsx @@ -0,0 +1,44 @@ +import { ShellContext } from '@ovh-ux/manager-react-shell-client'; +import { vitest } from 'vitest'; +import { ParamValueType } from '@ovh-ux/url-builder'; +import React, { PropsWithChildren, useState } from 'react'; +import { renderHook, waitFor } from '@testing-library/react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { useNavigationGetUrl } from './useNavigationGetUrl'; + +const mockGetURL = vitest.fn(); + +const Wrapper = ({ children }: PropsWithChildren) => { + const [queryClient] = useState(new QueryClient()); + const [mockContextValue] = useState({ + shell: { navigation: { getURL: mockGetURL } }, + }); + return ( + + {children} + + ); +}; + +describe('useNavigationGetUrl', () => { + it('should call navigation.getURL with correct linkParams', async () => { + const linkParams: [string, string, Record] = [ + 'param1', + 'param2', + { key: 'value' }, + ]; + mockGetURL.mockResolvedValue('mockedUrl'); + + const { result } = renderHook( + () => useNavigationGetUrl(linkParams, { retry: false }), + { + wrapper: Wrapper, + }, + ); + + await waitFor(() => result.current.isSuccess); + + await waitFor(() => expect(mockGetURL).toHaveBeenCalledWith(...linkParams)); + expect(result.current.data).toBe('mockedUrl'); + }); +}); diff --git a/packages/manager/apps/hycu/src/hooks/shell/useNavigationGetUrl.ts b/packages/manager/apps/hycu/src/hooks/shell/useNavigationGetUrl.ts new file mode 100644 index 000000000000..77cf71a49b0e --- /dev/null +++ b/packages/manager/apps/hycu/src/hooks/shell/useNavigationGetUrl.ts @@ -0,0 +1,21 @@ +import { ParamValueType } from '@ovh-ux/url-builder'; +import { ShellContext } from '@ovh-ux/manager-react-shell-client'; +import { DefinedInitialDataOptions, useQuery } from '@tanstack/react-query'; +import { useContext } from 'react'; + +export const useNavigationGetUrl = ( + linkParams: [string, string, Record], + options?: Partial>, +) => { + const { + shell: { navigation }, + } = useContext(ShellContext); + + return useQuery({ + queryKey: ['shell', 'getUrl', linkParams], + queryFn: () => navigation.getURL(...linkParams), + refetchOnReconnect: false, + refetchOnWindowFocus: false, + ...(options ?? {}), + }); +}; diff --git a/packages/manager/apps/hycu/src/mocks/index.ts b/packages/manager/apps/hycu/src/mocks/index.ts index 202f88045626..1d92b2f2ffea 100644 --- a/packages/manager/apps/hycu/src/mocks/index.ts +++ b/packages/manager/apps/hycu/src/mocks/index.ts @@ -1 +1,2 @@ export * from './licenseHycu/licenseHycu'; +export * from './serviceLicenseHycu/serviceLicenseHycu'; diff --git a/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.data.ts b/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.data.ts index 260accd6ab47..998a3e14e3fb 100644 --- a/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.data.ts +++ b/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.data.ts @@ -21,7 +21,7 @@ export const licensesHycu: IHycuDetails[] = [ }, comment: '', serviceName: 'c1b7cb4f-6b63-45da-9a8a-f731f1a67b2c', - controllerId: '', + controllerId: 'test-id', licenseStatus: LicenseStatus.ACTIVATED, expirationDate: '0001-01-01T00:00:00Z', }, diff --git a/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts b/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts index 664d5fb4e95f..9d12981a842b 100644 --- a/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts +++ b/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts @@ -1,14 +1,17 @@ +import { LicenseStatus } from '@/type/hycu.details.interface'; import { Handler } from '../../../../../../../playwright-helpers'; import { licensesHycu } from './licenseHycu.data'; export type GetLicenseHycuMocksParams = { isGetLicenseHycuKo?: boolean; nbLicenseHycu?: number; + licenseStatus?: LicenseStatus; }; export const getLicenseHycuMocks = ({ isGetLicenseHycuKo, nbLicenseHycu = Number.POSITIVE_INFINITY, + licenseStatus = LicenseStatus.TO_ACTIVATE, }: GetLicenseHycuMocksParams): Handler[] => { return [ { @@ -17,7 +20,24 @@ export const getLicenseHycuMocks = ({ ? { message: 'Backup error', } - : licensesHycu.slice(0, nbLicenseHycu), + : licensesHycu + .slice(0, nbLicenseHycu) + .map((license) => ({ ...license, licenseStatus })), + status: isGetLicenseHycuKo ? 500 : 200, + api: 'v6', + }, + { + url: 'license/hycu/:serviceName', + response: isGetLicenseHycuKo + ? { + message: 'Backup error', + } + : { + ...licensesHycu[0], + licenseStatus, + controllerId: + licenseStatus !== LicenseStatus.TO_ACTIVATE ? 'test-id' : '', + }, status: isGetLicenseHycuKo ? 500 : 200, api: 'v6', }, diff --git a/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.data.ts b/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.data.ts new file mode 100644 index 000000000000..40aa4f70141d --- /dev/null +++ b/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.data.ts @@ -0,0 +1,95 @@ +import { CurrencyCode, ServiceDetails } from '@ovh-ux/manager-react-components'; + +export const licensesHycuService: ServiceDetails = { + route: { + path: '/license/hycu/{serviceName}', + url: '/license/hycu/425802fa-fb70-4b2a-9d5b-ec4de86bb40c', + vars: [ + { + key: 'serviceName', + value: '425802fa-fb70-4b2a-9d5b-ec4de86bb40c', + }, + ], + }, + billing: { + nextBillingDate: '2024-11-03T15:24:23Z', + expirationDate: '2024-11-03T15:24:23Z', + plan: { + code: 'hycu-vms-pack-25', + invoiceName: 'HYCU Hybrid Cloud - 25 VMs', + }, + pricing: { + capacities: 'renew', + description: 'rental for 1 month', + interval: 1, + duration: 'P1M', + minimumQuantity: 1, + maximumQuantity: null, + minimumRepeat: 1, + maximumRepeat: null, + price: { + currencyCode: CurrencyCode.EUR, + text: '157.50 €', + value: 157.5, + priceInUcents: 0, + }, + priceInUcents: 15750000000, + pricingMode: 'default', + pricingType: 'rental', + engagementConfiguration: null, + }, + group: null, + lifecycle: { + current: { + pendingActions: [], + terminationDate: null, + creationDate: '2024-10-03T15:24:23Z', + state: 'active', + }, + capacities: { + actions: ['earlyRenewal', 'terminateAtExpirationDate'], + }, + }, + renew: { + current: { + mode: 'automatic', + nextDate: '2024-11-03T15:24:23Z', + period: 'P1M', + }, + capacities: { + mode: ['automatic', 'manual'], + }, + }, + engagement: null, + engagementRequest: null, + }, + resource: { + displayName: '425802fa-fb70-4b2a-9d5b-ec4de86bb40c', + name: '425802fa-fb70-4b2a-9d5b-ec4de86bb40c', + state: 'active', + product: { + name: 'hycu-cloud-vm-pack-25', + description: 'HYCU Hybrid Cloud - 25 VMs', + }, + resellingProvider: null, + }, + serviceId: 128622602, + parentServiceId: null, + customer: { + contacts: [ + { + customerCode: 'ls148374-ovh', + type: 'administrator', + }, + { + customerCode: 'ls148374-ovh', + type: 'technical', + }, + { + customerCode: 'ls148374-ovh', + type: 'billing', + }, + ], + }, + tags: [], +}; diff --git a/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.ts b/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.ts new file mode 100644 index 000000000000..8168d84c5468 --- /dev/null +++ b/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.ts @@ -0,0 +1,25 @@ +import { LicenseStatus } from '@/type/hycu.details.interface'; +import { Handler } from '../../../../../../../playwright-helpers'; +import { licensesHycuService } from './serviceLicenseHycu.data'; + +export type GetServiceLicenseHycuMocksParams = { + isGetServiceLicenseHycuKo?: boolean; + licenseStatus?: LicenseStatus; +}; + +export const getServiceLicenseHycuMocks = ({ + isGetServiceLicenseHycuKo, +}: GetServiceLicenseHycuMocksParams): Handler[] => { + return [ + { + url: 'services/:id', + response: isGetServiceLicenseHycuKo + ? { + message: 'Backup error', + } + : licensesHycuService, + status: isGetServiceLicenseHycuKo ? 500 : 200, + api: 'v6', + }, + ]; +}; diff --git a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.spec.tsx new file mode 100644 index 000000000000..5bab4a2ccd8d --- /dev/null +++ b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.spec.tsx @@ -0,0 +1,31 @@ +import { screen, waitFor } from '@testing-library/react'; +import { renderTestApp } from '@/utils/tests/renderTestApp'; +import '@testing-library/jest-dom'; + +describe('License Hycu Dashboard route test suite', () => { + it('should show informations of services', async () => { + await renderTestApp('/fake-id'); + + await waitFor( + () => + expect( + screen.getAllByText('425802fa-fb70-4b2a-9d5b-ec4de86bb40c')[0], + ).toBeVisible(), + { timeout: 30_000 }, + ); + + expect(screen.queryByAltText('OOPS')).not.toBeInTheDocument(); + }); + + it('should show error if api services fail', async () => { + await renderTestApp('/fake-id', { + getServicesKo: true, + isGetLicenseHycuKo: true, + isGetServiceLicenseHycuKo: true, + }); + + await waitFor(() => expect(screen.getByAltText('OOPS')).toBeVisible(), { + timeout: 30_000, + }); + }); +}); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx index 665a301e9a95..4f718e86902f 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx @@ -5,8 +5,8 @@ import { NavLink, useLocation, useNavigate, - useParams, useResolvedPath, + useParams, } from 'react-router-dom'; import { OsdsTabs, @@ -14,9 +14,14 @@ import { OsdsTabBarItem, } from '@ovhcloud/ods-components/react'; -import { BaseLayout } from '@ovh-ux/manager-react-components'; +import { + BaseLayout, + useServiceDetails, +} from '@ovh-ux/manager-react-components'; import Breadcrumb from '@/components/Breadcrumb/Breadcrumb.component'; +import Errors from '@/components/Error/Error'; +import { urls } from '@/routes/routes.constant'; export type DashboardTabItemProps = { name: string; @@ -29,22 +34,22 @@ export type DashboardLayoutProps = { }; export default function DashboardPage() { + const { serviceName } = useParams(); const [panel, setActivePanel] = useState(''); const location = useLocation(); const navigate = useNavigate(); - const { t } = useTranslation('dashboard'); + const { t } = useTranslation('hycu/dashboard'); + + const { data: serviceDetails, error } = useServiceDetails({ + resourceName: serviceName, + }); const tabsList = [ { name: 'general_informations', - title: 'Informations générales', + title: t('hycu_dashboard_generals_informations_title'), to: useResolvedPath('').pathname, }, - { - name: 'Tab 2', - title: 'Tab 2', - to: useResolvedPath('Tab2').pathname, - }, ] as const; useEffect(() => { @@ -58,14 +63,26 @@ export default function DashboardPage() { }, [location.pathname]); const header = { - title: t('title'), + title: serviceDetails?.data.resource.displayName, + description: serviceName, }; + if (error) { + return ( + } header={header}> + + + ); + } + return ( } header={header} - description="Description du hycu" + backLinkLabel={t('hycu_dashboard_back_link')} + onClickReturn={() => { + navigate(urls.listing); + }} tabs={ diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.spec.tsx new file mode 100644 index 000000000000..b5562fb9a1ac --- /dev/null +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.spec.tsx @@ -0,0 +1,32 @@ +import { screen, waitFor } from '@testing-library/react'; +import { renderTestApp } from '@/utils/tests/renderTestApp'; +import '@testing-library/jest-dom'; +import { labels } from '@/utils/tests/init.i18n'; + +describe('License Hycu billing information tile for dashboard test suite', () => { + it('should show informations of services', async () => { + await renderTestApp('/fake-id'); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_subscription_title, + )[0], + ).toBeVisible(), + { timeout: 30_000 }, + ); + + expect( + screen.getByText(labels.dashboard.hycu_dashboard_label_renew), + ).toBeVisible(); + expect( + screen.getByText(labels.dashboard.hycu_dashboard_field_label_contacts), + ).toBeVisible(); + expect( + screen.getByText( + labels.dashboard.hycu_dashboard_field_label_date_creation, + ), + ).toBeVisible(); + }); +}); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx new file mode 100644 index 000000000000..cef4561d3014 --- /dev/null +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx @@ -0,0 +1,128 @@ +import { + DashboardTile, + DateFormat, + Description, + Renew, + useFormattedDate, + useServiceDetails, +} from '@ovh-ux/manager-react-components'; +import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import { ODS_ICON_NAME, ODS_ICON_SIZE } from '@ovhcloud/ods-components'; +import { + OsdsIcon, + OsdsLink, + OsdsSkeleton, +} from '@ovhcloud/ods-components/react'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { useNavigationGetUrl } from '@/hooks/shell/useNavigationGetUrl'; + +const BillingInformationsTile = ({ serviceName }: { serviceName: string }) => { + const { t } = useTranslation('hycu/dashboard'); + + const { data: serviceDetails, isLoading } = useServiceDetails({ + resourceName: serviceName, + }); + + const renewDate = useFormattedDate({ + dateString: (serviceDetails?.data.billing.renew as Renew)?.current.nextDate, + format: DateFormat.display, + }); + + const creationDate = useFormattedDate({ + dateString: serviceDetails?.data.billing.lifecycle.current.creationDate, + format: DateFormat.display, + }); + + const { + data: contactUrl, + isLoading: isContactUrlLoading, + } = useNavigationGetUrl([ + 'dedicated', + '#/contacts/services', + { serviceName }, + ]); + + return ( + + ) : ( + {renewDate} + ), + }, + { + id: 'contact', + label: t('hycu_dashboard_field_label_contacts'), + value: ( +
+
+ {isLoading + ? Array.from({ length: 3 }).map((_, index) => ( + + )) + : serviceDetails?.data.customer.contacts.map((contact) => ( + {`${ + contact.customerCode + } ${t( + `hycu_dashboard_contact_type_${contact.type}`, + )}`} + ))} +
+ +
+ + {t('hycu_dashboard_field_label_manage_contacts')} + + + + +
+
+ ), + }, + { + id: 'date_creation', + label: t('hycu_dashboard_field_label_date_creation'), + value: isLoading ? ( + + ) : ( + {creationDate} + ), + }, + { + id: 'link_terminated', + value: ( + + {t('hycu_dashboard_link_terminated')} + + + + + ), + }, + ]} + >
+ ); +}; + +export default BillingInformationsTile; diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/DashboardGeneralInformation.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/DashboardGeneralInformation.page.tsx index a785e6d2ff0f..09627a1c37c2 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/DashboardGeneralInformation.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/DashboardGeneralInformation.page.tsx @@ -1,7 +1,25 @@ import React from 'react'; +import { useParams } from 'react-router-dom'; +import BillingInformationsTile from './BillingInformations/BillingInformationsTile'; +import GeneralInformationsTile from './GeneralInformationsTiles/GeneralInformationsTile'; +import ShortcutsTile from './ShortcutsTile/ShortcutsTile'; function GeneralInfos() { - return
Information Générales Tab
; + const { serviceName } = useParams(); + + return ( +
+
+ +
+
+ +
+
+ +
+
+ ); } export default GeneralInfos; diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx new file mode 100644 index 000000000000..850d04f7e0f6 --- /dev/null +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx @@ -0,0 +1,99 @@ +import { screen, waitFor } from '@testing-library/react'; +import { renderTestApp } from '@/utils/tests/renderTestApp'; +import '@testing-library/jest-dom'; +import { labels } from '@/utils/tests/init.i18n'; +import { LicenseStatus } from '@/type/hycu.details.interface'; + +describe('License Hycu general informations tile for dashboard test suite', () => { + it('should show informations of services', async () => { + await renderTestApp('/fake-id'); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_generals_informations_title, + )[1], + ).toBeVisible(), + { timeout: 30_000 }, + ); + + expect( + screen.getByText(labels.dashboard.hycu_dashboard_label_name), + ).toBeVisible(); + expect( + screen.getByText(labels.dashboard.hycu_dashboard_label_status), + ).toBeVisible(); + expect( + screen.getByText(labels.dashboard.hycu_dashboard_label_pack_type), + ).toBeVisible(); + expect( + screen.getByText(labels.dashboard.hycu_dashboard_label_controller_id), + ).toBeVisible(); + expect( + screen.getByText(labels.dashboard.hycu_dashboard_label_license_key), + ).toBeVisible(); + + expect( + screen.queryByText(labels.dashboard.hycu_dashboard_download_license_file), + ).not.toBeInTheDocument(); + }); + + it('should show download license button when license is activated', async () => { + await renderTestApp('/fake-id', { licenseStatus: LicenseStatus.ACTIVATED }); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_generals_informations_title, + )[1], + ).toBeVisible(), + { timeout: 30_000 }, + ); + + await waitFor( + () => + expect( + screen.getByText( + labels.dashboard.hycu_dashboard_download_license_file, + ), + ).toBeVisible(), + { timeout: 30_000 }, + ); + + expect( + screen.queryByText(labels.dashboard.hycu_dashboard_wait_for_activation), + ).not.toBeInTheDocument(); + }); + + it('should show wait for activation if license is not activated', async () => { + await renderTestApp('/fake-id', { + licenseStatus: LicenseStatus.TO_ACTIVATE, + }); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_generals_informations_title, + )[1], + ).toBeVisible(), + { timeout: 10_000 }, + ); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_wait_for_activation, + )[0], + ).toBeVisible(), + { timeout: 10_000 }, + ); + + expect( + screen.queryByText(labels.dashboard.hycu_dashboard_download_license_file), + ).not.toBeInTheDocument(); + }); +}); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx new file mode 100644 index 000000000000..b453d3984efa --- /dev/null +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx @@ -0,0 +1,150 @@ +import { + DashboardTile, + Description, + useServiceDetails, +} from '@ovh-ux/manager-react-components'; +import { + OsdsChip, + OsdsIcon, + OsdsButton, + OsdsSkeleton, + OsdsLink, +} from '@ovhcloud/ods-components/react'; +import { + ODS_BUTTON_SIZE, + ODS_BUTTON_VARIANT, + ODS_CHIP_SIZE, + ODS_ICON_NAME, + ODS_ICON_SIZE, +} from '@ovhcloud/ods-components'; + +import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; + +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { getStatusColor } from '@/utils/statusColor'; +import { useDetailsLicenseHYCU } from '@/hooks/api/license'; +import { LicenseStatus } from '@/type/hycu.details.interface'; + +const DownloadHycuLicense = ({ serviceName }: { serviceName: string }) => { + const { t } = useTranslation('hycu/dashboard'); + const { data: hycuDetail, isLoading } = useDetailsLicenseHYCU(serviceName); + + if (isLoading) return ; + if (LicenseStatus.ACTIVATED !== hycuDetail.data.licenseStatus) + return <>{t('hycu_dashboard_wait_for_activation')}; + return ( + + {t('hycu_dashboard_download_license_file')} + + + + + ); +}; + +const ControllerIdHycuLicense = ({ serviceName }: { serviceName: string }) => { + const { t } = useTranslation('hycu/dashboard'); + const { data: hycuDetail, isLoading } = useDetailsLicenseHYCU(serviceName); + + if (isLoading) return ; + if (!hycuDetail?.data.controllerId) + return <>{t('hycu_dashboard_wait_for_activation')}; + return {hycuDetail?.data.controllerId}; +}; + +const GeneralInformationsTile = ({ serviceName }: { serviceName: string }) => { + const { t: tCommon } = useTranslation('hycu'); + const { t } = useTranslation('hycu/dashboard'); + const { data: hycuDetail } = useDetailsLicenseHYCU(serviceName); + const { data: serviceDetails, isLoading } = useServiceDetails({ + resourceName: serviceName, + }); + + return ( + + ) : ( +
+ + {serviceDetails?.data.resource.displayName} + + + + + +
+ ), + }, + { + id: 'status', + label: t('hycu_dashboard_label_status'), + value: isLoading ? ( + + ) : ( + + {tCommon([ + `hycu_status_${hycuDetail?.data.licenseStatus}`, + 'hycu_status_error', + ])} + + ), + }, + { + id: 'pack_type', + label: t('hycu_dashboard_label_pack_type'), + value: isLoading ? ( + + ) : ( + + {serviceDetails?.data.resource.product.description} + + ), + }, + { + id: 'controller_id', + label: t('hycu_dashboard_label_controller_id'), + value: ControllerIdHycuLicense({ serviceName }), + }, + { + id: 'license_key', + label: t('hycu_dashboard_label_license_key'), + value: isLoading ? ( + + ) : ( + + ), + }, + ]} + >
+ ); +}; + +export default GeneralInformationsTile; diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx new file mode 100644 index 000000000000..f28b5348f1be --- /dev/null +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx @@ -0,0 +1,65 @@ +import '@testing-library/jest-dom'; +import { screen, waitFor } from '@testing-library/react'; +import { renderTestApp } from '@/utils/tests/renderTestApp'; +import { labels } from '@/utils/tests/init.i18n'; +import { LicenseStatus } from '@/type/hycu.details.interface'; + +describe('License Hycu shortcuts tile for dashboard test suite', () => { + it('should show links of service to activate', async () => { + await renderTestApp('/fake-id', { + licenseStatus: LicenseStatus.TO_ACTIVATE, + }); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_shortcuts_title, + )[0], + ).toBeVisible(), + { timeout: 30_000 }, + ); + + await waitFor( + () => + expect( + screen.getByText(labels.dashboard.hycu_dashboard_link_activate), + ).toBeVisible(), + { timeout: 30_000 }, + ); + expect( + screen.queryByText(labels.dashboard.hycu_dashboard_link_change_pack_type), + ).not.toBeInTheDocument(); + }); + + it('should show links of services activated', async () => { + await renderTestApp('/fake-id', { licenseStatus: LicenseStatus.ACTIVATED }); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_shortcuts_title, + )[0], + ).toBeVisible(), + { timeout: 30_000 }, + ); + + await waitFor( + () => + expect( + screen.getByText(labels.dashboard.hycu_dashboard_link_reactivate), + ).toBeVisible(), + { timeout: 20_000 }, + ); + await waitFor( + () => + expect( + screen.getByText( + labels.dashboard.hycu_dashboard_link_change_pack_type, + ), + ).toBeVisible(), + { timeout: 20_000 }, + ); + }); +}); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx new file mode 100644 index 000000000000..055cf9ee3029 --- /dev/null +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx @@ -0,0 +1,65 @@ +import { OsdsLink, OsdsIcon } from '@ovhcloud/ods-components/react'; +import { DashboardTile } from '@ovh-ux/manager-react-components'; + +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { ODS_ICON_NAME } from '@ovhcloud/ods-components'; +import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import { useDetailsLicenseHYCU } from '@/hooks/api/license'; +import { LicenseStatus } from '@/type/hycu.details.interface'; + +const ShortcutsItem = ({ + children, + ...rest +}: React.ComponentProps) => ( + +
+
{children}
+ +
+
+); + +const ShortcutsTile = ({ serviceName }: { serviceName: string }) => { + const { data: hycuDetail } = useDetailsLicenseHYCU(serviceName); + const { t } = useTranslation('hycu/dashboard'); + + const links = { + linkActivated: { + id: 'link_activated', + value: {t('hycu_dashboard_link_activate')}, + }, + linkReactivated: { + id: 'link_reactivated', + value: ( + {t('hycu_dashboard_link_reactivate')} + ), + }, + linkChangePackType: { + id: 'link_change_pack_type', + value: ( + + {t('hycu_dashboard_link_change_pack_type')} + + ), + }, + } as const; + + return ( + + ); +}; + +export default ShortcutsTile; diff --git a/packages/manager/apps/hycu/src/pages/dashboard/tab2/index.tsx b/packages/manager/apps/hycu/src/pages/dashboard/tab2/index.tsx deleted file mode 100644 index 9cb100623734..000000000000 --- a/packages/manager/apps/hycu/src/pages/dashboard/tab2/index.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import React from 'react'; - -function Tab2() { - return
Tab 2
; -} - -export default Tab2; diff --git a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx index 6d29ba59cc2c..12dd2f548d1f 100644 --- a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx +++ b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx @@ -56,11 +56,11 @@ const DatagridIdCell = (hycuDetail: IHycuDetails) => { }; const DatagridControllerIdCell = (hycuDetail: IHycuDetails) => { - return {hycuDetail.controllerId}; + return {hycuDetail.controllerId || '-'}; }; const DatagridStatusCell = (hycuDetail: IHycuDetails) => { - const { t } = useTranslation('hycu/listing'); + const { t } = useTranslation('hycu'); return ( diff --git a/packages/manager/apps/hycu/src/pages/listing/Listing.spec.tsx b/packages/manager/apps/hycu/src/pages/listing/Listing.spec.tsx index 396747dc0831..fc4739d31029 100644 --- a/packages/manager/apps/hycu/src/pages/listing/Listing.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/listing/Listing.spec.tsx @@ -8,7 +8,7 @@ import HYCU_CONFIG from '@/hycu.config'; describe('License Hycu listing test suite', () => { it('should redirect to the onboarding page when the license hycu list is empty', async () => { - await renderTestApp({ nbLicenseHycu: 0 }); + await renderTestApp('/', { nbLicenseHycu: 0 }); expect(screen.getByText(HYCU_CONFIG.rootLabel)).toBeVisible(); expect( @@ -40,7 +40,9 @@ describe('License Hycu listing test suite', () => { await waitFor( () => expect( - screen.getByText(labels.dashboard.general_informations), + screen.getAllByText( + labels.dashboard.hycu_dashboard_generals_informations_title, + )[0], ).toBeVisible(), { timeout: 30_000 }, ); diff --git a/packages/manager/apps/hycu/src/routes/routes.tsx b/packages/manager/apps/hycu/src/routes/routes.tsx index 0fa1bc776da3..28fafd148573 100644 --- a/packages/manager/apps/hycu/src/routes/routes.tsx +++ b/packages/manager/apps/hycu/src/routes/routes.tsx @@ -51,17 +51,6 @@ export const Routes: any = [ }, }, }, - { - id: 'dashboard.tab2', - path: 'Tab2', - ...lazyRouteConfig(() => import('@/pages/dashboard/tab2')), - handle: { - tracking: { - pageName: 'tab2', - pageType: PageType.dashboard, - }, - }, - }, ], }, { diff --git a/packages/manager/apps/hycu/src/utils/statusColor.ts b/packages/manager/apps/hycu/src/utils/statusColor.ts index 1aedb85a5ad8..75efb753736a 100644 --- a/packages/manager/apps/hycu/src/utils/statusColor.ts +++ b/packages/manager/apps/hycu/src/utils/statusColor.ts @@ -1,6 +1,7 @@ import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; import { LicenseStatus } from '@/type/hycu.details.interface'; +/* v8 ignore start */ export const getStatusColor = ( licenseStatus: LicenseStatus, ): ODS_THEME_COLOR_INTENT => { diff --git a/packages/manager/apps/hycu/src/utils/tests/TestApp.tsx b/packages/manager/apps/hycu/src/utils/tests/TestApp.tsx index b016f4d6ec24..0ec94df2580f 100644 --- a/packages/manager/apps/hycu/src/utils/tests/TestApp.tsx +++ b/packages/manager/apps/hycu/src/utils/tests/TestApp.tsx @@ -3,9 +3,9 @@ import { QueryClientProvider, QueryClient } from '@tanstack/react-query'; import { createMemoryRouter, RouterProvider } from 'react-router-dom'; import { Routes } from '../../routes/routes'; -export function TestApp() { +export function TestApp({ initialRoute = '/' }: { initialRoute: string }) { const router = createMemoryRouter(Routes, { - initialEntries: ['/'], + initialEntries: [initialRoute], initialIndex: 0, }); diff --git a/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts b/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts index 9af278be892c..6a1248a254ba 100644 --- a/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts +++ b/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts @@ -1,6 +1,7 @@ -import i18next, { i18n } from 'i18next'; +import i18next, { i18n, InitOptions } from 'i18next'; +import error from '@ovh-ux/manager-react-components/src/components/templates/error/translations/Messages_fr_FR.json'; import common from '../../../public/translations/hycu/Messages_fr_FR.json'; -import dashboard from '../../../public/translations/dashboard/Messages_fr_FR.json'; +import dashboard from '../../../public/translations/hycu/dashboard/Messages_fr_FR.json'; import listing from '../../../public/translations/hycu/listing/Messages_fr_FR.json'; import onboarding from '../../../public/translations/hycu/onboarding/Messages_fr_FR.json'; @@ -10,9 +11,10 @@ export const defaultAvailableLocales = [defaultLocale]; function addTranslations() { i18next .addResources(defaultLocale, 'hycu', common) - .addResources(defaultLocale, 'dashboard', dashboard) + .addResources(defaultLocale, 'hycu/dashboard', dashboard) .addResources(defaultLocale, 'hycu/listing', listing) .addResources(defaultLocale, 'hycu/onboarding', onboarding) + .addResources(defaultLocale, 'error', error) .use({ type: 'postProcessor', name: 'normalize', @@ -21,18 +23,20 @@ function addTranslations() { }); } +export const getTesti18nParams = (): InitOptions => ({ + lng: defaultLocale, + defaultNS: 'hycu', + ns: [], + supportedLngs: defaultAvailableLocales, + postProcess: 'normalize', + interpolation: { + escapeValue: false, + }, +}); + export const initTestI18n = () => new Promise((resolve) => { - i18next.init({ - lng: defaultLocale, - defaultNS: 'hycu', - ns: [], - supportedLngs: defaultAvailableLocales, - postProcess: 'normalize', - interpolation: { - escapeValue: false, - }, - }); + i18next.init(getTesti18nParams()); if (i18next.isInitialized) { addTranslations(); @@ -49,4 +53,5 @@ export const labels = { dashboard, listing, onboarding, + error, }; diff --git a/packages/manager/apps/hycu/src/utils/tests/renderTestApp.tsx b/packages/manager/apps/hycu/src/utils/tests/renderTestApp.tsx index 3fde0e151880..85db8ffa213a 100644 --- a/packages/manager/apps/hycu/src/utils/tests/renderTestApp.tsx +++ b/packages/manager/apps/hycu/src/utils/tests/renderTestApp.tsx @@ -12,22 +12,33 @@ import { GetServicesMocksParams, } from '@ovh-ux/manager-react-components'; import { TestApp } from './TestApp'; -import { initTestI18n } from './init.i18n'; +import { getTesti18nParams, initTestI18n } from './init.i18n'; import { toMswHandlers } from '../../../../../../../playwright-helpers'; import { getAuthenticationMocks } from '../../../../../../../playwright-helpers/mocks/auth'; -import { getLicenseHycuMocks, GetLicenseHycuMocksParams } from '@/mocks'; +import { + getLicenseHycuMocks, + GetLicenseHycuMocksParams, + getServiceLicenseHycuMocks, + GetServiceLicenseHycuMocksParams, +} from '@/mocks'; let context: ShellContextType; let i18nValue: i18n; export const renderTestApp = async ( - mockParams: GetServicesMocksParams & GetLicenseHycuMocksParams = {}, + initialRoute = '/', + mockParams: GetServicesMocksParams & + GetLicenseHycuMocksParams & + GetServicesMocksParams & + GetServicesMocksParams & + GetServiceLicenseHycuMocksParams = {}, ) => { global.server?.resetHandlers( ...toMswHandlers([ ...getAuthenticationMocks({ isAuthMocked: true }), - ...getServicesMocks(mockParams), ...getLicenseHycuMocks(mockParams), + ...getServiceLicenseHycuMocks(mockParams), + ...getServicesMocks(mockParams), ]), ); @@ -42,18 +53,20 @@ export const renderTestApp = async ( const result = render( - + , ); - await waitFor( - () => - expect( - screen.getAllByText('HYCU', { exact: false }).length, - ).toBeGreaterThan(0), - { timeout: 30000 }, - ); + if (!initialRoute || initialRoute === '/') { + await waitFor( + () => + expect( + screen.getAllByText('HYCU', { exact: false }).length, + ).toBeGreaterThan(0), + { timeout: 30000 }, + ); + } return result; }; diff --git a/packages/manager/apps/hycu/vitest.config.js b/packages/manager/apps/hycu/vitest.config.js index 5ad6ce3dccf7..9075895638be 100644 --- a/packages/manager/apps/hycu/vitest.config.js +++ b/packages/manager/apps/hycu/vitest.config.js @@ -10,8 +10,11 @@ export default defineConfig({ environment: 'jsdom', setupFiles: ['./src/setupTests.tsx'], coverage: { + provider: 'v8', + reporter: ['text'], include: ['src'], exclude: [ + 'src/mocks', 'src/App.tsx', 'src/index.tsx', 'src/tracking.constant.ts', diff --git a/yarn.lock b/yarn.lock index 4815b3d6a803..bcf6f054be84 100644 --- a/yarn.lock +++ b/yarn.lock @@ -938,6 +938,13 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.7.tgz#9a5226f92f0c5c8ead550b750f5608e766c8ce85" integrity sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw== +"@babel/parser@^7.25.4": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.8.tgz#f6aaf38e80c36129460c1657c0762db584c9d5e2" + integrity sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ== + dependencies: + "@babel/types" "^7.25.8" + "@babel/parser@^7.25.7": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.7.tgz#99b927720f4ddbfeb8cd195a363ed4532f87c590" @@ -2086,7 +2093,7 @@ "@babel/helper-validator-identifier" "^7.24.7" to-fast-properties "^2.0.0" -"@babel/types@^7.25.4", "@babel/types@^7.25.7", "@babel/types@^7.25.8": +"@babel/types@^7.25.4", "@babel/types@^7.25.8": version "7.25.8" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.8.tgz#5cf6037258e8a9bcad533f4979025140cb9993e1" integrity sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg== @@ -2095,6 +2102,15 @@ "@babel/helper-validator-identifier" "^7.25.7" to-fast-properties "^2.0.0" +"@babel/types@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.7.tgz#1b7725c1d3a59f328cb700ce704c46371e6eef9b" + integrity sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ== + dependencies: + "@babel/helper-string-parser" "^7.25.7" + "@babel/helper-validator-identifier" "^7.25.7" + to-fast-properties "^2.0.0" + "@base2/pretty-print-object@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" @@ -8620,6 +8636,14 @@ lodash "^4.17.21" redent "^3.0.0" +"@testing-library/react-hooks@^8.0.1": + version "8.0.1" + resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz#0924bbd5b55e0c0c0502d1754657ada66947ca12" + integrity sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g== + dependencies: + "@babel/runtime" "^7.12.5" + react-error-boundary "^3.1.0" + "@testing-library/react@14.0.0": version "14.0.0" resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-14.0.0.tgz#59030392a6792450b9ab8e67aea5f3cc18d6347c" @@ -9762,7 +9786,7 @@ strip-literal "^2.0.0" test-exclude "^6.0.0" -"@vitest/coverage-v8@^2.1.2": +"@vitest/coverage-v8@^2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@vitest/coverage-v8/-/coverage-v8-2.1.3.tgz#22d519e5e56385ec126305492f5a3cfe5b44b14d" integrity sha512-2OJ3c7UPoFSmBZwqD2VEkUw6A/tzPF0LmW0ZZhhB8PFxuc+9IBG/FaSM+RLEenc7ljzFvGN+G0nGQoZnh7sy2A== @@ -9925,7 +9949,7 @@ resolved "https://registry.npmjs.org/@vitest/spy/-/spy-1.3.1.tgz#814245d46d011b99edd1c7528f5725c64e85a88b" integrity sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig== dependencies: - "@vitest/pretty-format" "2.1.2" + "@vitest/pretty-format" "2.1.3" magic-string "^0.30.11" pathe "^1.1.2" @@ -21142,7 +21166,7 @@ magic-string@^0.30.0, magic-string@^0.30.1, magic-string@^0.30.5, magic-string@^ dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" -magic-string@^0.30.10, magic-string@^0.30.11: +magic-string@^0.30.10: version "0.30.11" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.11.tgz#301a6f93b3e8c2cb13ac1a7a673492c0dfd12954" integrity sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A== @@ -24271,6 +24295,13 @@ react-element-to-jsx-string@^15.0.0: is-plain-object "5.0.0" react-is "18.1.0" +react-error-boundary@^3.1.0: + version "3.1.4" + resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0" + integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA== + dependencies: + "@babel/runtime" "^7.12.5" + react-hook-form@^7.47.0, react-hook-form@^7.50.1: version "7.51.2" resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.51.2.tgz#79f7f72ee217c5114ff831012d1a7ec344096e7f" @@ -29117,7 +29148,7 @@ vitest@^2.0.5: vite-node "2.0.5" why-is-node-running "^2.3.0" -vitest@^2.1.2: +vitest@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/vitest/-/vitest-2.1.3.tgz#dae1055dd328621b59fc6e594fd988fbf2e5370e" integrity sha512-Zrxbg/WiIvUP2uEzelDNTXmEMJXuzJ1kCpbDvaKByFA9MNeO95V+7r/3ti0qzJzrxdyuUw5VduN7k+D3VmVOSA== From 23d9a5f1f76f682cd97a42bf86260f8d9639d988 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Mon, 21 Oct 2024 15:33:06 +0200 Subject: [PATCH 06/43] refactor(container): improve regex veeam and hycu to be more explicit Enables compliance with the rule : typescript:S5850 ref: #NTNX-1 Signed-off-by: Thibault Barske --- .../server-sidebar/universe/HostedPrivateCloudSidebar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/manager/apps/container/src/container/legacy/server-sidebar/universe/HostedPrivateCloudSidebar.tsx b/packages/manager/apps/container/src/container/legacy/server-sidebar/universe/HostedPrivateCloudSidebar.tsx index 05a14762c527..7d682cde04fe 100644 --- a/packages/manager/apps/container/src/container/legacy/server-sidebar/universe/HostedPrivateCloudSidebar.tsx +++ b/packages/manager/apps/container/src/container/legacy/server-sidebar/universe/HostedPrivateCloudSidebar.tsx @@ -278,7 +278,7 @@ export default function HostedPrivateCloudSidebar() { id: 'hpc-storage-backup', label: t('sidebar_storage_backup'), icon: , - pathMatcher: new RegExp('^/hycu|/veeam-backup'), + pathMatcher: new RegExp('^/(hycu|veeam-backup)'), badge: 'new', subItems: [ (feature['veeam-backup']) && { From 6130376069465f0cf8521ba3d7076635d9f3ed30 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Mon, 21 Oct 2024 15:37:26 +0200 Subject: [PATCH 07/43] refactor(hycu): move type in types to be compliance with other uapp ref: NTNX-1 Signed-off-by: Thibault Barske --- packages/manager/apps/hycu/src/data/api/hycu.ts | 2 +- packages/manager/apps/hycu/src/hooks/api/license.ts | 2 +- .../manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.data.ts | 2 +- packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts | 2 +- .../hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.ts | 2 +- .../GeneralInformationsTiles/GeneralInformationsTile.spec.tsx | 2 +- .../GeneralInformationsTiles/GeneralInformationsTile.tsx | 2 +- .../general-information/ShortcutsTile/ShortcutsTile.spec.tsx | 2 +- .../general-information/ShortcutsTile/ShortcutsTile.tsx | 2 +- packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx | 2 +- .../hycu/src/pages/listing/menu/HycuActionMenu.component.tsx | 2 +- .../apps/hycu/src/{type => types}/hycu.details.interface.ts | 0 packages/manager/apps/hycu/src/utils/statusColor.ts | 2 +- 13 files changed, 12 insertions(+), 12 deletions(-) rename packages/manager/apps/hycu/src/{type => types}/hycu.details.interface.ts (100%) diff --git a/packages/manager/apps/hycu/src/data/api/hycu.ts b/packages/manager/apps/hycu/src/data/api/hycu.ts index b7ebf0617df5..a21d12cf6aeb 100644 --- a/packages/manager/apps/hycu/src/data/api/hycu.ts +++ b/packages/manager/apps/hycu/src/data/api/hycu.ts @@ -1,6 +1,6 @@ import { AxiosResponse } from 'axios'; import { fetchIcebergV6, apiClient } from '@ovh-ux/manager-core-api'; -import { IHycuDetails } from '@/type/hycu.details.interface'; +import { IHycuDetails } from '@/types/hycu.details.interface'; export type GetlicenseHycuListParams = { /** Filter resources on IAM tags */ diff --git a/packages/manager/apps/hycu/src/hooks/api/license.ts b/packages/manager/apps/hycu/src/hooks/api/license.ts index 3c7854b22c14..f92474b566f6 100644 --- a/packages/manager/apps/hycu/src/hooks/api/license.ts +++ b/packages/manager/apps/hycu/src/hooks/api/license.ts @@ -1,7 +1,7 @@ import { AxiosResponse } from 'axios'; import { DefinedInitialDataOptions, useQuery } from '@tanstack/react-query'; import { getlicenseHycuService } from '@/data/api/hycu'; -import { IHycuDetails } from '@/type/hycu.details.interface'; +import { IHycuDetails } from '@/types/hycu.details.interface'; export const useDetailsLicenseHYCU = ( serviceName: string, diff --git a/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.data.ts b/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.data.ts index 998a3e14e3fb..4136c839cbab 100644 --- a/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.data.ts +++ b/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.data.ts @@ -1,4 +1,4 @@ -import { IHycuDetails, LicenseStatus } from '@/type/hycu.details.interface'; +import { IHycuDetails, LicenseStatus } from '@/types/hycu.details.interface'; export const licensesHycu: IHycuDetails[] = [ { diff --git a/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts b/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts index 9d12981a842b..896897416377 100644 --- a/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts +++ b/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts @@ -1,4 +1,4 @@ -import { LicenseStatus } from '@/type/hycu.details.interface'; +import { LicenseStatus } from '@/types/hycu.details.interface'; import { Handler } from '../../../../../../../playwright-helpers'; import { licensesHycu } from './licenseHycu.data'; diff --git a/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.ts b/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.ts index 8168d84c5468..27ea5e1218e6 100644 --- a/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.ts +++ b/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.ts @@ -1,4 +1,4 @@ -import { LicenseStatus } from '@/type/hycu.details.interface'; +import { LicenseStatus } from '@/types/hycu.details.interface'; import { Handler } from '../../../../../../../playwright-helpers'; import { licensesHycuService } from './serviceLicenseHycu.data'; diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx index 850d04f7e0f6..338b97b16a21 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx @@ -2,7 +2,7 @@ import { screen, waitFor } from '@testing-library/react'; import { renderTestApp } from '@/utils/tests/renderTestApp'; import '@testing-library/jest-dom'; import { labels } from '@/utils/tests/init.i18n'; -import { LicenseStatus } from '@/type/hycu.details.interface'; +import { LicenseStatus } from '@/types/hycu.details.interface'; describe('License Hycu general informations tile for dashboard test suite', () => { it('should show informations of services', async () => { diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx index b453d3984efa..c3f20b738151 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx @@ -24,7 +24,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { getStatusColor } from '@/utils/statusColor'; import { useDetailsLicenseHYCU } from '@/hooks/api/license'; -import { LicenseStatus } from '@/type/hycu.details.interface'; +import { LicenseStatus } from '@/types/hycu.details.interface'; const DownloadHycuLicense = ({ serviceName }: { serviceName: string }) => { const { t } = useTranslation('hycu/dashboard'); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx index f28b5348f1be..a346035d6a91 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx @@ -2,7 +2,7 @@ import '@testing-library/jest-dom'; import { screen, waitFor } from '@testing-library/react'; import { renderTestApp } from '@/utils/tests/renderTestApp'; import { labels } from '@/utils/tests/init.i18n'; -import { LicenseStatus } from '@/type/hycu.details.interface'; +import { LicenseStatus } from '@/types/hycu.details.interface'; describe('License Hycu shortcuts tile for dashboard test suite', () => { it('should show links of service to activate', async () => { diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx index 055cf9ee3029..f94f4c5bf6b7 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx @@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next'; import { ODS_ICON_NAME } from '@ovhcloud/ods-components'; import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; import { useDetailsLicenseHYCU } from '@/hooks/api/license'; -import { LicenseStatus } from '@/type/hycu.details.interface'; +import { LicenseStatus } from '@/types/hycu.details.interface'; const ShortcutsItem = ({ children, diff --git a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx index 12dd2f548d1f..0ea010d3bf9d 100644 --- a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx +++ b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx @@ -28,7 +28,7 @@ import { ODS_BUTTON_SIZE, } from '@ovhcloud/ods-components'; import HYCU_CONFIG from '@/hycu.config'; -import { IHycuDetails } from '@/type/hycu.details.interface'; +import { IHycuDetails } from '@/types/hycu.details.interface'; import { urls, subRoutes } from '@/routes/routes.constant'; import HycuActionMenu from './menu/HycuActionMenu.component'; diff --git a/packages/manager/apps/hycu/src/pages/listing/menu/HycuActionMenu.component.tsx b/packages/manager/apps/hycu/src/pages/listing/menu/HycuActionMenu.component.tsx index 24d7466a0bbc..1bc6481d690f 100644 --- a/packages/manager/apps/hycu/src/pages/listing/menu/HycuActionMenu.component.tsx +++ b/packages/manager/apps/hycu/src/pages/listing/menu/HycuActionMenu.component.tsx @@ -3,7 +3,7 @@ import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; import React from 'react'; import { ODS_ICON_NAME } from '@ovhcloud/ods-components'; import { useTranslation } from 'react-i18next'; -import { IHycuDetails } from '@/type/hycu.details.interface'; +import { IHycuDetails } from '@/types/hycu.details.interface'; const HycuActionMenu = ({ serviceName: _serviceName, diff --git a/packages/manager/apps/hycu/src/type/hycu.details.interface.ts b/packages/manager/apps/hycu/src/types/hycu.details.interface.ts similarity index 100% rename from packages/manager/apps/hycu/src/type/hycu.details.interface.ts rename to packages/manager/apps/hycu/src/types/hycu.details.interface.ts diff --git a/packages/manager/apps/hycu/src/utils/statusColor.ts b/packages/manager/apps/hycu/src/utils/statusColor.ts index 75efb753736a..a904a26482d2 100644 --- a/packages/manager/apps/hycu/src/utils/statusColor.ts +++ b/packages/manager/apps/hycu/src/utils/statusColor.ts @@ -1,5 +1,5 @@ import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; -import { LicenseStatus } from '@/type/hycu.details.interface'; +import { LicenseStatus } from '@/types/hycu.details.interface'; /* v8 ignore start */ export const getStatusColor = ( From da78d05e2d4d254fb185995df3acf508c61a5176 Mon Sep 17 00:00:00 2001 From: Thibaud Crespin Date: Tue, 22 Oct 2024 18:25:26 +0200 Subject: [PATCH 08/43] feat(hycu): create order page ref: MANAGER-14504 Signed-off-by: Thibaud Crespin --- .../hycu/order/Messages_fr_FR.json | 12 ++ .../components/Loading/Loading.component.tsx | 4 +- .../components/Order/OrderConfirmation.tsx | 96 ++++++++++++ .../src/components/Order/PackSelection.tsx | 140 ++++++++++++++++++ .../hycu/src/data/api/orderCatalogHYCU.ts | 15 ++ .../src/hooks/order/useOrderCatalogHYCU.ts | 20 +++ .../hycu/src/hooks/order/useOrderHYCU.spec.ts | 46 ++++++ .../apps/hycu/src/hooks/order/useOrderHYCU.ts | 31 ++++ .../src/mocks/catalogHycu/catalogHycu.data.ts | 81 ++++++++++ .../hycu/src/mocks/catalogHycu/catalogHycu.ts | 23 +++ packages/manager/apps/hycu/src/mocks/index.ts | 1 + .../apps/hycu/src/pages/order/Order.page.tsx | 54 +++++++ .../apps/hycu/src/pages/order/Order.spec.tsx | 73 +++++++++ .../apps/hycu/src/routes/routes.constant.ts | 1 + .../manager/apps/hycu/src/routes/routes.tsx | 11 ++ .../hycu/src/types/orderCatalogHYCU.type.ts | 26 ++++ .../apps/hycu/src/utils/contactList.ts | 30 ++++ .../apps/hycu/src/utils/getRenewPrice.ts | 14 ++ .../manager/apps/hycu/src/utils/sortPacks.ts | 10 ++ .../apps/hycu/src/utils/tests/init.i18n.ts | 3 + .../hycu/src/utils/tests/renderTestApp.tsx | 5 +- .../modules/order/src/order.constant.ts | 15 ++ 22 files changed, 709 insertions(+), 2 deletions(-) create mode 100644 packages/manager/apps/hycu/public/translations/hycu/order/Messages_fr_FR.json create mode 100644 packages/manager/apps/hycu/src/components/Order/OrderConfirmation.tsx create mode 100644 packages/manager/apps/hycu/src/components/Order/PackSelection.tsx create mode 100644 packages/manager/apps/hycu/src/data/api/orderCatalogHYCU.ts create mode 100644 packages/manager/apps/hycu/src/hooks/order/useOrderCatalogHYCU.ts create mode 100644 packages/manager/apps/hycu/src/hooks/order/useOrderHYCU.spec.ts create mode 100644 packages/manager/apps/hycu/src/hooks/order/useOrderHYCU.ts create mode 100644 packages/manager/apps/hycu/src/mocks/catalogHycu/catalogHycu.data.ts create mode 100644 packages/manager/apps/hycu/src/mocks/catalogHycu/catalogHycu.ts create mode 100644 packages/manager/apps/hycu/src/pages/order/Order.page.tsx create mode 100644 packages/manager/apps/hycu/src/pages/order/Order.spec.tsx create mode 100644 packages/manager/apps/hycu/src/types/orderCatalogHYCU.type.ts create mode 100644 packages/manager/apps/hycu/src/utils/contactList.ts create mode 100644 packages/manager/apps/hycu/src/utils/getRenewPrice.ts create mode 100644 packages/manager/apps/hycu/src/utils/sortPacks.ts diff --git a/packages/manager/apps/hycu/public/translations/hycu/order/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_fr_FR.json new file mode 100644 index 000000000000..f1e402e13f43 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_fr_FR.json @@ -0,0 +1,12 @@ +{ + "hycu_order_title": "Commander une licence HYCU Hybrid Cloud", + "hycu_order_description": "HYCU Hybrid Cloud est un logiciel de sauvegarde et de restauration spécialement conçu pour Nutanix. Nous vous proposons différents packs de licences selon le nombre de machines virtuelles (VM) utilisées par vos charges de travail Nutanix.", + "hycu_order_subtitle": "Choisissez le type de pack", + "hycu_order_subtitle_description": "Sélectionnez le nombre de machines virtuelles (VM) à couvrir par la licence HYCU Hybrid Cloud. Veuillez noter qu'il vous sera impossible de sauvegarder plus de VM que le nombre prévu dans le pack. Si vous souhaitez protéger plus de 500 VM, merci de vous rapprocher de notre service commercial.", + "hycu_order_cta_cancel": "Annuler", + "hycu_order_cta_order": "Commander", + "hycu_order_initiated_title": "Commande de votre pack", + "hycu_order_initiated_description": "Si vous n'avez pas encore finalisé votre commande, vous pouvez la compléter en cliquant sur le lien suivant :", + "hycu_order_initiated_info": "Nous vous informerons de la disponibilité de votre licence par e-mail.", + "hycu_order_initiated_cta_done": "Terminer" +} diff --git a/packages/manager/apps/hycu/src/components/Loading/Loading.component.tsx b/packages/manager/apps/hycu/src/components/Loading/Loading.component.tsx index 8623d319f92b..99da53549ec2 100644 --- a/packages/manager/apps/hycu/src/components/Loading/Loading.component.tsx +++ b/packages/manager/apps/hycu/src/components/Loading/Loading.component.tsx @@ -5,7 +5,9 @@ import { OsdsSpinner } from '@ovhcloud/ods-components/react'; export default function Loading() { return (
- +
+ +
); } diff --git a/packages/manager/apps/hycu/src/components/Order/OrderConfirmation.tsx b/packages/manager/apps/hycu/src/components/Order/OrderConfirmation.tsx new file mode 100644 index 000000000000..91bb69910917 --- /dev/null +++ b/packages/manager/apps/hycu/src/components/Order/OrderConfirmation.tsx @@ -0,0 +1,96 @@ +import React from 'react'; +import { + OsdsText, + OsdsButton, + OsdsLink, + OsdsIcon, + OsdsTile, +} from '@ovhcloud/ods-components/react'; +import { + ODS_BUTTON_SIZE, + ODS_BUTTON_VARIANT, + ODS_ICON_SIZE, + ODS_ICON_NAME, + ODS_LINK_REFERRER_POLICY, +} from '@ovhcloud/ods-components'; +import { + ODS_THEME_COLOR_INTENT, + ODS_THEME_TYPOGRAPHY_SIZE, + ODS_THEME_TYPOGRAPHY_LEVEL, +} from '@ovhcloud/ods-common-theming'; +import { OdsHTMLAnchorElementTarget } from '@ovhcloud/ods-common-core'; +import { useNavigate } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; +import { urls } from '@/routes/routes.constant'; + +type OrderConfirmationProps = { + orderLink: string; +}; + +const OrderConfirmation = ({ orderLink }: OrderConfirmationProps) => { + const { t } = useTranslation('hycu/order'); + const navigate = useNavigate(); + + return ( + <> + + +
+ + {t('hycu_order_initiated_title')} + + + {t('hycu_order_initiated_description')} + + + {orderLink} + + + + + + {t('hycu_order_initiated_info')} + +
+
+
+ { + navigate(urls.listing); + }} + > + {t('hycu_order_initiated_cta_done')} + + + ); +}; + +export default OrderConfirmation; diff --git a/packages/manager/apps/hycu/src/components/Order/PackSelection.tsx b/packages/manager/apps/hycu/src/components/Order/PackSelection.tsx new file mode 100644 index 000000000000..d8d7fc375e19 --- /dev/null +++ b/packages/manager/apps/hycu/src/components/Order/PackSelection.tsx @@ -0,0 +1,140 @@ +import React, { Dispatch, SetStateAction } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { Trans, useTranslation } from 'react-i18next'; + +import { OdsHTMLAnchorElementTarget } from '@ovhcloud/ods-common-core'; +import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import { + ODS_BUTTON_VARIANT, + ODS_TEXT_LEVEL, + ODS_TEXT_SIZE, +} from '@ovhcloud/ods-components'; +import { + OsdsText, + OsdsButton, + OsdsTile, + OsdsLink, +} from '@ovhcloud/ods-components/react'; +import { + Description, + OvhSubsidiary, + Price, + Subtitle, +} from '@ovh-ux/manager-react-components'; + +import Error from '@/components/Error/Error'; +import Loading from '@/components/Loading/Loading.component'; +import { useOrderCatalogHYCU } from '@/hooks/order/useOrderCatalogHYCU'; +import { urls } from '@/routes/routes.constant'; +import { sortPacksByPrice } from '@/utils/sortPacks'; +import { getRenewPrice } from '@/utils/getRenewPrice'; +import { CONTACT_URL_BY_SUBSIDIARY } from '@/utils/contactList'; + +type PackSelectionProps = { + selectPack: Dispatch>; + setOrderInitiated: () => void; + orderLink: string; + selectedPack: string; + subsidiary: OvhSubsidiary; +}; + +const PackSelection = ({ + selectPack, + setOrderInitiated, + orderLink, + selectedPack, + subsidiary, +}: PackSelectionProps) => { + const { t } = useTranslation('hycu/order'); + const navigate = useNavigate(); + + const { data: orderCatalogHYCU, isLoading, error } = useOrderCatalogHYCU( + subsidiary, + { + refetchOnWindowFocus: false, + keepPreviousData: true, + }, + ); + + if (!isLoading && error) return ; + + return ( + <> + {t('hycu_order_subtitle')} + + + ), + }} + > + + {isLoading && } + {orderCatalogHYCU && !isLoading && ( +
+ {sortPacksByPrice(orderCatalogHYCU.plans).map((product) => ( + { + selectPack(product.planCode); + }} + rounded + > +
+ + {product.invoiceName} + + +
+
+ ))} +
+ )} +
+ { + navigate(urls.listing); + }} + slot="actions" + variant={ODS_BUTTON_VARIANT.ghost} + > + {t('hycu_order_cta_cancel')} + + { + setOrderInitiated(); + }} + slot="actions" + > + {t('hycu_order_cta_order')} + +
+ + ); +}; + +export default PackSelection; diff --git a/packages/manager/apps/hycu/src/data/api/orderCatalogHYCU.ts b/packages/manager/apps/hycu/src/data/api/orderCatalogHYCU.ts new file mode 100644 index 000000000000..9207b0ea459e --- /dev/null +++ b/packages/manager/apps/hycu/src/data/api/orderCatalogHYCU.ts @@ -0,0 +1,15 @@ +import apiClient from '@ovh-ux/manager-core-api'; +import { OvhSubsidiary } from '@ovh-ux/manager-react-components'; +import { HYCUCatalog } from '@/types/orderCatalogHYCU.type'; + +/** + * HYCU Catalog : Get HYCU Order Catalog + */ +export const getOrderCatalogHYCU = async ( + ovhSubsidiary: OvhSubsidiary, +): Promise => { + const { data } = await apiClient.v6.get( + `/order/catalog/public/licenseHycu?ovhSubsidiary=${ovhSubsidiary}`, + ); + return data; +}; diff --git a/packages/manager/apps/hycu/src/hooks/order/useOrderCatalogHYCU.ts b/packages/manager/apps/hycu/src/hooks/order/useOrderCatalogHYCU.ts new file mode 100644 index 000000000000..798f3157110b --- /dev/null +++ b/packages/manager/apps/hycu/src/hooks/order/useOrderCatalogHYCU.ts @@ -0,0 +1,20 @@ +import { DefinedInitialDataOptions, useQuery } from '@tanstack/react-query'; +import { OvhSubsidiary } from '@ovh-ux/manager-react-components'; +import { ApiError } from '@ovh-ux/manager-core-api'; +import { getOrderCatalogHYCU } from '../../data/api/orderCatalogHYCU'; +import { HYCUCatalog } from '@/types/orderCatalogHYCU.type'; + +export type OrderCatalogProps = { + ovhSubsidiary: OvhSubsidiary; +}; + +export const useOrderCatalogHYCU = ( + ovhSubsidiary: OvhSubsidiary, + options: Partial> = {}, +) => { + return useQuery({ + queryKey: ['order/catalog/public/licenseHycu', ovhSubsidiary], + queryFn: () => getOrderCatalogHYCU(ovhSubsidiary), + ...options, + }); +}; diff --git a/packages/manager/apps/hycu/src/hooks/order/useOrderHYCU.spec.ts b/packages/manager/apps/hycu/src/hooks/order/useOrderHYCU.spec.ts new file mode 100644 index 000000000000..cf4e6673425b --- /dev/null +++ b/packages/manager/apps/hycu/src/hooks/order/useOrderHYCU.spec.ts @@ -0,0 +1,46 @@ +import { describe, expect, it, test, vi } from 'vitest'; +import { renderHook } from '@testing-library/react'; +import useOrderHYCU from './useOrderHYCU'; + +vi.mock('@ovh-ux/manager-module-order', () => ({ + useOrderURL: () => 'http://test', + getHYCUProductSettings: () => 'test-settings', +})); + +describe('get hycu express order linl ', () => { + const useCases: { + planCode: string; + region: string; + }[] = [ + { + planCode: 'hycu-cloud-vm-pack-25', + region: 'FR', + }, + { + planCode: 'hycu-cloud-vm-pack-250', + region: 'US', + }, + ]; + test.each(useCases)( + 'should return the right translation key for $type', + ({ planCode, region }) => { + // given type and translationKey + // when + const { result } = renderHook(() => useOrderHYCU({ planCode, region })); + // then + expect(result.current.orderLink).toContain( + 'http://test?products=~(test-settings)', + ); + }, + ); + it('should return null if planCode is not defined', () => { + // given + const planCode = undefined; + const region = 'FR'; + // when + const { result } = renderHook(() => useOrderHYCU({ planCode, region })); + + // then + expect(result.current.orderLink).toBeNull(); + }); +}); diff --git a/packages/manager/apps/hycu/src/hooks/order/useOrderHYCU.ts b/packages/manager/apps/hycu/src/hooks/order/useOrderHYCU.ts new file mode 100644 index 000000000000..00b562cef8b8 --- /dev/null +++ b/packages/manager/apps/hycu/src/hooks/order/useOrderHYCU.ts @@ -0,0 +1,31 @@ +import { + useOrderURL, + getHYCUProductSettings, +} from '@ovh-ux/manager-module-order'; +import { OvhSubsidiary } from '@ovh-ux/manager-react-components'; +import { useMemo } from 'react'; + +interface HYCUOrder { + planCode: string; + region: OvhSubsidiary; +} + +const useOrderHYCU = ({ planCode, region }: HYCUOrder) => { + const orderBaseUrl = useOrderURL('express_review_base'); + const orderLink = useMemo(() => { + const HYCUProductSettings = getHYCUProductSettings({ + planCode, + region, + }); + if (planCode) return `${orderBaseUrl}?products=~(${HYCUProductSettings})`; + return null; + }, [planCode, region]); + + const redirectToOrder = () => { + window.open(orderLink, '_blank', 'noopener,noreferrer'); + }; + + return { orderLink, redirectToOrder }; +}; + +export default useOrderHYCU; diff --git a/packages/manager/apps/hycu/src/mocks/catalogHycu/catalogHycu.data.ts b/packages/manager/apps/hycu/src/mocks/catalogHycu/catalogHycu.data.ts new file mode 100644 index 000000000000..0ed346662554 --- /dev/null +++ b/packages/manager/apps/hycu/src/mocks/catalogHycu/catalogHycu.data.ts @@ -0,0 +1,81 @@ +import { IntervalUnitType } from '@ovh-ux/manager-react-components'; +import { HYCUCatalog } from '@/types/orderCatalogHYCU.type'; + +export const catalog: HYCUCatalog = { + plans: [ + { + configurations: [ + { + name: 'region', + isCustom: false, + isMandatory: true, + values: ['europe', 'canada'], + }, + ], + invoiceName: 'HYCU Hybrid Cloud - Test VMs', + planCode: 'hycu-vms-pack-test', + pricings: [ + { + capacities: ['installation'], + intervalUnit: IntervalUnitType.none, + price: 0, + tax: 0, + }, + { + capacities: ['upgrade'], + + intervalUnit: IntervalUnitType.none, + + price: 0, + tax: 0, + }, + { + capacities: ['renew'], + + intervalUnit: IntervalUnitType.month, + + price: 63000000000, + tax: 12600000000, + }, + ], + }, + { + planCode: 'hycu-vms-pack-test-2', + invoiceName: 'HYCU Hybrid Cloud - Test 2 VMs', + pricings: [ + { + capacities: ['installation'], + + intervalUnit: IntervalUnitType.none, + + price: 0, + tax: 0, + }, + { + capacities: ['upgrade'], + + intervalUnit: IntervalUnitType.none, + + price: 0, + tax: 0, + }, + { + capacities: ['renew'], + + intervalUnit: IntervalUnitType.month, + + price: 94500000000, + tax: 18900000000, + }, + ], + configurations: [ + { + name: 'region', + isCustom: false, + isMandatory: true, + values: ['europe', 'canada'], + }, + ], + }, + ], +}; diff --git a/packages/manager/apps/hycu/src/mocks/catalogHycu/catalogHycu.ts b/packages/manager/apps/hycu/src/mocks/catalogHycu/catalogHycu.ts new file mode 100644 index 000000000000..fbdfaa206022 --- /dev/null +++ b/packages/manager/apps/hycu/src/mocks/catalogHycu/catalogHycu.ts @@ -0,0 +1,23 @@ +import { Handler } from '../../../../../../../playwright-helpers'; +import { catalog } from './catalogHycu.data'; + +export type CatalogHycuMocksParams = { + isCatalogHycuKo?: boolean; +}; + +export const getCatalogHycuMocks = ({ + isCatalogHycuKo = false, +}: CatalogHycuMocksParams): Handler[] => { + return [ + { + url: '/order/catalog/public/licenseHycu', + response: isCatalogHycuKo + ? { + message: 'Backup error', + } + : catalog, + status: isCatalogHycuKo ? 500 : 200, + api: 'v6', + }, + ]; +}; diff --git a/packages/manager/apps/hycu/src/mocks/index.ts b/packages/manager/apps/hycu/src/mocks/index.ts index 1d92b2f2ffea..9f1d845c7ee4 100644 --- a/packages/manager/apps/hycu/src/mocks/index.ts +++ b/packages/manager/apps/hycu/src/mocks/index.ts @@ -1,2 +1,3 @@ export * from './licenseHycu/licenseHycu'; export * from './serviceLicenseHycu/serviceLicenseHycu'; +export * from './catalogHycu/catalogHycu'; diff --git a/packages/manager/apps/hycu/src/pages/order/Order.page.tsx b/packages/manager/apps/hycu/src/pages/order/Order.page.tsx new file mode 100644 index 000000000000..14f0783c453e --- /dev/null +++ b/packages/manager/apps/hycu/src/pages/order/Order.page.tsx @@ -0,0 +1,54 @@ +import React, { useContext, useState } from 'react'; +import { useTranslation } from 'react-i18next'; + +import { BaseLayout, OvhSubsidiary } from '@ovh-ux/manager-react-components'; +import { ShellContext } from '@ovh-ux/manager-react-shell-client'; + +import Breadcrumb from '@/components/Breadcrumb/Breadcrumb.component'; +import OrderConfirmation from '@/components/Order/OrderConfirmation'; +import PackSelection from '@/components/Order/PackSelection'; +import useOrderHYCU from '@/hooks/order/useOrderHYCU'; + +export default function Order() { + const { t } = useTranslation('hycu/order'); + + const { environment } = useContext(ShellContext); + const subsidiary: OvhSubsidiary = environment.getUser() + .ovhSubsidiary as OvhSubsidiary; + + const header = { + title: t('hycu_order_title'), + }; + const description: string = t('hycu_order_description'); + + const [selectedPack, setSelectedPack] = useState(null); + const [isOrderInitiated, setIsOrderInitiated] = useState(false); + + const { orderLink, redirectToOrder } = useOrderHYCU({ + planCode: selectedPack, + region: subsidiary, + }); + + return ( + } + description={description} + header={header} + > + {!isOrderInitiated ? ( + setSelectedPack(pack)} + selectedPack={selectedPack} + setOrderInitiated={() => { + setIsOrderInitiated(true); + redirectToOrder(); + }} + > + ) : ( + + )} + + ); +} diff --git a/packages/manager/apps/hycu/src/pages/order/Order.spec.tsx b/packages/manager/apps/hycu/src/pages/order/Order.spec.tsx new file mode 100644 index 000000000000..1919ae5cb930 --- /dev/null +++ b/packages/manager/apps/hycu/src/pages/order/Order.spec.tsx @@ -0,0 +1,73 @@ +import { act, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { vi } from 'vitest'; +import { renderTestApp } from '@/utils/tests/renderTestApp'; +import '@testing-library/jest-dom'; +import { labels } from '@/utils/tests/init.i18n'; +import { catalog } from '@/mocks/catalogHycu/catalogHycu.data'; + +describe('License Hycu order test suite', () => { + it('should display the hycu order page', async () => { + await renderTestApp('/order'); + + await waitFor(() => screen.getByText(labels.order.hycu_order_title), { + timeout: 10_000, + }); + + expect(screen.getByText(labels.order.hycu_order_title)).toBeVisible(); + expect(screen.getByText(labels.order.hycu_order_description)).toBeVisible(); + expect(screen.getByText(labels.order.hycu_order_subtitle)).toBeVisible(); + + expect( + screen.queryByText(labels.order.hycu_order_initiated_title), + ).not.toBeInTheDocument(); + }); + + it('should enable order button when pack is selected', async () => { + await renderTestApp('/order'); + + await waitFor(() => screen.getByText(catalog.plans[0].invoiceName), { + timeout: 10_000, + }); + + expect(screen.getByText(labels.order.hycu_order_cta_order)).toBeDisabled(); + + await act(() => + userEvent.click(screen.getByText(catalog.plans[0].invoiceName)), + ); + + expect(screen.getByText(labels.order.hycu_order_cta_order)).toBeEnabled(); + }); + + it('should redirect to express order and change page informations', async () => { + const closeSpy = vi.fn(); + window.open = vi.fn().mockReturnValue({ close: closeSpy }); + + await renderTestApp('/order'); + + await waitFor(() => screen.getByText(catalog.plans[0].invoiceName), { + timeout: 10_000, + }); + + // Pack selection + await act(() => + userEvent.click(screen.getByText(catalog.plans[0].invoiceName)), + ); + + // Click on order button + await act(() => + userEvent.click(screen.getByText(labels.order.hycu_order_cta_order)), + ); + + expect(window.open).toHaveBeenCalled(); + + // Check page has changed to display express order info + expect( + screen.getByText(labels.order.hycu_order_initiated_title), + ).toBeVisible(); + + expect( + screen.queryByText(labels.order.hycu_order_subtitle), + ).not.toBeInTheDocument(); + }); +}); diff --git a/packages/manager/apps/hycu/src/routes/routes.constant.ts b/packages/manager/apps/hycu/src/routes/routes.constant.ts index 61e0fa44744f..a8be45c4ea7f 100644 --- a/packages/manager/apps/hycu/src/routes/routes.constant.ts +++ b/packages/manager/apps/hycu/src/routes/routes.constant.ts @@ -9,4 +9,5 @@ export const urls = { listing: '/', dashboard: `/${subRoutes.serviceName}`, tab2: 'Tab2', + order: '/order', } as const; diff --git a/packages/manager/apps/hycu/src/routes/routes.tsx b/packages/manager/apps/hycu/src/routes/routes.tsx index 28fafd148573..cfb225296d1b 100644 --- a/packages/manager/apps/hycu/src/routes/routes.tsx +++ b/packages/manager/apps/hycu/src/routes/routes.tsx @@ -64,6 +64,17 @@ export const Routes: any = [ }, }, }, + { + id: 'order', + path: urls.order, + ...lazyRouteConfig(() => import('@/pages/order/Order.page')), + handle: { + tracking: { + pageName: 'order', + pageType: PageType.dashboard, + }, + }, + }, ], }, { diff --git a/packages/manager/apps/hycu/src/types/orderCatalogHYCU.type.ts b/packages/manager/apps/hycu/src/types/orderCatalogHYCU.type.ts new file mode 100644 index 000000000000..bf4ad3547835 --- /dev/null +++ b/packages/manager/apps/hycu/src/types/orderCatalogHYCU.type.ts @@ -0,0 +1,26 @@ +import { IntervalUnitType } from '@ovh-ux/manager-react-components'; + +type HYCUCatalogPlanConfiguration = { + isCustom: boolean; + isMandatory: boolean; + name: string; + values: string[]; +}; + +export type HYCUCatalogPlanPricing = { + capacities: ['installation' | 'upgrade' | 'renew']; + price: number; + intervalUnit: IntervalUnitType; + tax: number; +}; + +export type HYCUCatalogPlan = { + configurations: HYCUCatalogPlanConfiguration[]; + invoiceName: string; + planCode: string; + pricings: HYCUCatalogPlanPricing[]; +}; + +export type HYCUCatalog = { + plans: HYCUCatalogPlan[]; +}; diff --git a/packages/manager/apps/hycu/src/utils/contactList.ts b/packages/manager/apps/hycu/src/utils/contactList.ts new file mode 100644 index 000000000000..674453700f71 --- /dev/null +++ b/packages/manager/apps/hycu/src/utils/contactList.ts @@ -0,0 +1,30 @@ +import { OvhSubsidiary } from '@ovh-ux/manager-react-components'; + +export const CONTACT_URL_BY_SUBSIDIARY: Record = { + ASIA: 'https://www.ovhcloud.com/asia/contact/', + CZ: 'https://www.ovhcloud.com/en-ie/contact', + DE: 'https://www.ovhcloud.com/de/contact/', + ES: 'https://www.ovhcloud.com/es-es/contact/', + FI: 'https://www.ovhcloud.com/en-ie/contact', + WS: 'https://www.ovhcloud.com/es/contact/', + IE: 'https://www.ovhcloud.com/en-ie/contact/', + IT: 'https://www.ovhcloud.com/it/contact/', + LT: 'https://www.ovhcloud.com/en-ie/contact', + PL: 'https://www.ovhcloud.com/pl/contact/', + PT: 'https://www.ovhcloud.com/pt/contact/', + FR: 'https://www.ovhcloud.com/fr/contact/', + GB: 'https://www.ovhcloud.com/en-gb/contact/', + CA: 'https://www.ovhcloud.com/en-ca/contact/', + QC: 'https://www.ovhcloud.com/fr-ca/contact/', + US: 'https://www.ovhcloud.com/en/contact/', + AU: 'https://www.ovhcloud.com/en-au/contact/', + SG: 'https://www.ovhcloud.com/en-sg/contact/', + MA: 'https://www.ovhcloud.com/fr-ma/contact/', + SN: 'https://www.ovhcloud.com/fr-sn/contact/', + TN: 'https://www.ovhcloud.com/fr-tn/contact/', + NL: 'https://www.ovhcloud.com/nl/contact/', + IN: 'https://www.ovhcloud.com/en-in/contact/', + WE: 'https://www.ovhcloud.com/en/contact/', + EU: 'https://www.ovhcloud.com/fr/contact/', + DEFAULT: 'https://www.ovhcloud.com/fr/contact/', +}; diff --git a/packages/manager/apps/hycu/src/utils/getRenewPrice.ts b/packages/manager/apps/hycu/src/utils/getRenewPrice.ts new file mode 100644 index 000000000000..62d341093dca --- /dev/null +++ b/packages/manager/apps/hycu/src/utils/getRenewPrice.ts @@ -0,0 +1,14 @@ +import { HYCUCatalogPlanPricing } from '@/types/orderCatalogHYCU.type'; + +/** + * + * @param pricings + * @returns pricing which correspond to renew capacity + */ +export const getRenewPrice = ( + pricings: HYCUCatalogPlanPricing[], +): HYCUCatalogPlanPricing => { + return pricings.find((pricing) => + pricing.capacities.find((capacity) => capacity === 'renew'), + ); +}; diff --git a/packages/manager/apps/hycu/src/utils/sortPacks.ts b/packages/manager/apps/hycu/src/utils/sortPacks.ts new file mode 100644 index 000000000000..e1e403e2cb2c --- /dev/null +++ b/packages/manager/apps/hycu/src/utils/sortPacks.ts @@ -0,0 +1,10 @@ +import { HYCUCatalogPlan } from '@/types/orderCatalogHYCU.type'; + +/** + * + * @param packs + * @returns packs ordered by price + */ +export const sortPacksByPrice = (packs: HYCUCatalogPlan[]) => { + return packs.sort((a, b) => a.pricings[2].price - b.pricings[2].price); +}; diff --git a/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts b/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts index 6a1248a254ba..fd6ddc81e034 100644 --- a/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts +++ b/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts @@ -4,6 +4,7 @@ import common from '../../../public/translations/hycu/Messages_fr_FR.json'; import dashboard from '../../../public/translations/hycu/dashboard/Messages_fr_FR.json'; import listing from '../../../public/translations/hycu/listing/Messages_fr_FR.json'; import onboarding from '../../../public/translations/hycu/onboarding/Messages_fr_FR.json'; +import order from '../../../public/translations/hycu/order/Messages_fr_FR.json'; export const defaultLocale = 'fr_FR'; export const defaultAvailableLocales = [defaultLocale]; @@ -14,6 +15,7 @@ function addTranslations() { .addResources(defaultLocale, 'hycu/dashboard', dashboard) .addResources(defaultLocale, 'hycu/listing', listing) .addResources(defaultLocale, 'hycu/onboarding', onboarding) + .addResources(defaultLocale, 'hycu/order', order) .addResources(defaultLocale, 'error', error) .use({ type: 'postProcessor', @@ -53,5 +55,6 @@ export const labels = { dashboard, listing, onboarding, + order, error, }; diff --git a/packages/manager/apps/hycu/src/utils/tests/renderTestApp.tsx b/packages/manager/apps/hycu/src/utils/tests/renderTestApp.tsx index 85db8ffa213a..5888263eba74 100644 --- a/packages/manager/apps/hycu/src/utils/tests/renderTestApp.tsx +++ b/packages/manager/apps/hycu/src/utils/tests/renderTestApp.tsx @@ -16,6 +16,8 @@ import { getTesti18nParams, initTestI18n } from './init.i18n'; import { toMswHandlers } from '../../../../../../../playwright-helpers'; import { getAuthenticationMocks } from '../../../../../../../playwright-helpers/mocks/auth'; import { + CatalogHycuMocksParams, + getCatalogHycuMocks, getLicenseHycuMocks, GetLicenseHycuMocksParams, getServiceLicenseHycuMocks, @@ -30,7 +32,7 @@ export const renderTestApp = async ( mockParams: GetServicesMocksParams & GetLicenseHycuMocksParams & GetServicesMocksParams & - GetServicesMocksParams & + CatalogHycuMocksParams & GetServiceLicenseHycuMocksParams = {}, ) => { global.server?.resetHandlers( @@ -39,6 +41,7 @@ export const renderTestApp = async ( ...getLicenseHycuMocks(mockParams), ...getServiceLicenseHycuMocks(mockParams), ...getServicesMocks(mockParams), + ...getCatalogHycuMocks(mockParams), ]), ); diff --git a/packages/manager/modules/order/src/order.constant.ts b/packages/manager/modules/order/src/order.constant.ts index e70c8a5f7d9a..35a00b0014c6 100644 --- a/packages/manager/modules/order/src/order.constant.ts +++ b/packages/manager/modules/order/src/order.constant.ts @@ -56,6 +56,21 @@ export const getVcdProductSettings = ({ : undefined, }); +export const getHYCUProductSettings = ({ + planCode, + region, +}: { + planCode: string; + region: string; +}) => + JSURL.stringify({ + productId: 'licenseHycu', + planCode, + duration: 'P1M', + pricingMode: 'default', + configuration: [{ label: 'region', value: region }], + }); + export const ORDER_URLS = { EU: { DEDICATED: { From 9319a0e3178eab64250a3855fe953a7e59c44007 Mon Sep 17 00:00:00 2001 From: Thibaud Crespin Date: Wed, 23 Oct 2024 09:53:27 +0200 Subject: [PATCH 09/43] fix(hycu): build errors with tests and sonar ref: MANAGER-14504 Signed-off-by: Thibaud Crespin --- .../src/hooks/order/useOrderCatalogHYCU.ts | 4 +++- .../hycu/src/hooks/order/useOrderHYCU.spec.ts | 18 ++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/manager/apps/hycu/src/hooks/order/useOrderCatalogHYCU.ts b/packages/manager/apps/hycu/src/hooks/order/useOrderCatalogHYCU.ts index 798f3157110b..5ee801cccbe1 100644 --- a/packages/manager/apps/hycu/src/hooks/order/useOrderCatalogHYCU.ts +++ b/packages/manager/apps/hycu/src/hooks/order/useOrderCatalogHYCU.ts @@ -10,7 +10,9 @@ export type OrderCatalogProps = { export const useOrderCatalogHYCU = ( ovhSubsidiary: OvhSubsidiary, - options: Partial> = {}, + options: Partial> & { + keepPreviousData?: boolean; + } = {}, ) => { return useQuery({ queryKey: ['order/catalog/public/licenseHycu', ovhSubsidiary], diff --git a/packages/manager/apps/hycu/src/hooks/order/useOrderHYCU.spec.ts b/packages/manager/apps/hycu/src/hooks/order/useOrderHYCU.spec.ts index cf4e6673425b..1d9612c575bb 100644 --- a/packages/manager/apps/hycu/src/hooks/order/useOrderHYCU.spec.ts +++ b/packages/manager/apps/hycu/src/hooks/order/useOrderHYCU.spec.ts @@ -1,24 +1,25 @@ import { describe, expect, it, test, vi } from 'vitest'; import { renderHook } from '@testing-library/react'; +import { OvhSubsidiary } from '@ovh-ux/manager-react-components'; import useOrderHYCU from './useOrderHYCU'; vi.mock('@ovh-ux/manager-module-order', () => ({ - useOrderURL: () => 'http://test', + useOrderURL: () => 'https://test', getHYCUProductSettings: () => 'test-settings', })); describe('get hycu express order linl ', () => { const useCases: { planCode: string; - region: string; + region: OvhSubsidiary; }[] = [ { planCode: 'hycu-cloud-vm-pack-25', - region: 'FR', + region: OvhSubsidiary.FR, }, { planCode: 'hycu-cloud-vm-pack-250', - region: 'US', + region: OvhSubsidiary.US, }, ]; test.each(useCases)( @@ -29,16 +30,17 @@ describe('get hycu express order linl ', () => { const { result } = renderHook(() => useOrderHYCU({ planCode, region })); // then expect(result.current.orderLink).toContain( - 'http://test?products=~(test-settings)', + 'https://test?products=~(test-settings)', ); }, ); it('should return null if planCode is not defined', () => { // given - const planCode = undefined; - const region = 'FR'; + const region = OvhSubsidiary.FR; // when - const { result } = renderHook(() => useOrderHYCU({ planCode, region })); + const { result } = renderHook(() => + useOrderHYCU({ planCode: null, region }), + ); // then expect(result.current.orderLink).toBeNull(); From 2fc684231d95ca205f5f46856628143790e1959f Mon Sep 17 00:00:00 2001 From: Thibaud Crespin Date: Thu, 24 Oct 2024 10:29:16 +0200 Subject: [PATCH 10/43] fix(hycu): breadcrumb and order links ref: MANAGER-15780 Signed-off-by: Thibaud Crespin --- .../Breadcrumb/Breadcrumb.component.tsx | 4 +- .../src/hooks/breadcrumb/useBreadcrumb.tsx | 62 ++++++++++--------- .../hycu/src/pages/listing/Listing.page.tsx | 4 ++ .../hycu/src/pages/listing/Listing.spec.tsx | 14 +++++ .../src/pages/onboarding/Onboarding.page.tsx | 7 ++- .../apps/hycu/src/pages/order/Order.page.tsx | 10 ++- .../apps/hycu/src/routes/routes.constant.ts | 6 +- 7 files changed, 70 insertions(+), 37 deletions(-) diff --git a/packages/manager/apps/hycu/src/components/Breadcrumb/Breadcrumb.component.tsx b/packages/manager/apps/hycu/src/components/Breadcrumb/Breadcrumb.component.tsx index 0260f73b7499..2e321a7de738 100644 --- a/packages/manager/apps/hycu/src/components/Breadcrumb/Breadcrumb.component.tsx +++ b/packages/manager/apps/hycu/src/components/Breadcrumb/Breadcrumb.component.tsx @@ -12,12 +12,12 @@ export interface BreadcrumbProps { items?: BreadcrumbItem[]; } -function Breadcrumb({ customRootLabel }: BreadcrumbProps): JSX.Element { +function Breadcrumb({ customRootLabel, items }: BreadcrumbProps): JSX.Element { const label = customRootLabel || appConfig.rootLabel; const breadcrumbItems = useBreadcrumb({ rootLabel: label, - appName: 'hycu', + items, }); return ; } diff --git a/packages/manager/apps/hycu/src/hooks/breadcrumb/useBreadcrumb.tsx b/packages/manager/apps/hycu/src/hooks/breadcrumb/useBreadcrumb.tsx index d61852b056a4..d5eccc940b14 100644 --- a/packages/manager/apps/hycu/src/hooks/breadcrumb/useBreadcrumb.tsx +++ b/packages/manager/apps/hycu/src/hooks/breadcrumb/useBreadcrumb.tsx @@ -1,49 +1,51 @@ -import { useEffect, useState, useContext } from 'react'; -import { useLocation } from 'react-router-dom'; -import { ShellContext } from '@ovh-ux/manager-react-shell-client'; +import { useEffect, useState } from 'react'; +import { useLocation, useNavigate } from 'react-router-dom'; +import { urls } from '@/routes/routes.constant'; export type BreadcrumbItem = { + id: string; label: string | undefined; - href?: string; + onClick?: (event?: BreadcrumbEvent) => void; +}; + +type BreadcrumbEvent = Event & { + target: { isCollapsed?: boolean; isLast?: boolean }; }; export interface BreadcrumbProps { rootLabel?: string; - appName?: string; - projectId?: string; items?: BreadcrumbItem[]; } -export const useBreadcrumb = ({ rootLabel, appName }: BreadcrumbProps) => { - const { shell } = useContext(ShellContext); - const [root, setRoot] = useState([]); +export const useBreadcrumb = ({ rootLabel, items }: BreadcrumbProps) => { const [paths, setPaths] = useState([]); const location = useLocation(); + const navigate = useNavigate(); const pathnames = location.pathname.split('/').filter((x) => x); - useEffect(() => { - const fetchRoot = async () => { - try { - const response = await shell?.navigation.getURL(appName, '#/', {}); - const rootItem = { - label: rootLabel, - href: String(response), - }; - setRoot([rootItem]); - } catch { - // Fetch navigation error - } - }; - fetchRoot(); - }, [rootLabel, appName, shell?.navigation]); + const root: BreadcrumbItem = { + id: rootLabel, + label: rootLabel, + onClick: () => navigate(urls.root), + }; useEffect(() => { - const pathsTab = pathnames.map((value) => ({ - label: value, - href: `/#/${appName}/${value}`, - })); + const pathsTab = pathnames.map((value, index) => { + const item = items?.find(({ id }) => id === value); + + return { + id: item?.id ?? value, + label: item?.label ?? value, + onClick: (event: BreadcrumbEvent) => { + const { isCollapsed, isLast } = event.target; + if (!isCollapsed && !isLast) { + navigate(`/${pathnames.slice(0, index + 1).join('/')}`); + } + }, + }; + }); setPaths(pathsTab); - }, [location]); + }, [location, items]); - return [...root, ...paths]; + return [root, ...paths]; }; diff --git a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx index 0ea010d3bf9d..1bbd3597b307 100644 --- a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx +++ b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx @@ -118,6 +118,7 @@ const DatagridActionCell = (hycuDetail: IHycuDetails) => { }; export default function Listing() { + const navigate = useNavigate(); const { t } = useTranslation('hycu/listing'); const { t: tCommon } = useTranslation('hycu'); const { t: tError } = useTranslation('hycu/error'); @@ -196,6 +197,9 @@ export default function Listing() { color={ODS_THEME_COLOR_INTENT.primary} variant={ODS_BUTTON_VARIANT.stroked} size={ODS_BUTTON_SIZE.sm} + onClick={() => { + navigate(urls.order); + }} inline > {t('hycu_order')} diff --git a/packages/manager/apps/hycu/src/pages/listing/Listing.spec.tsx b/packages/manager/apps/hycu/src/pages/listing/Listing.spec.tsx index fc4739d31029..8f66769de572 100644 --- a/packages/manager/apps/hycu/src/pages/listing/Listing.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/listing/Listing.spec.tsx @@ -47,4 +47,18 @@ describe('License Hycu listing test suite', () => { { timeout: 30_000 }, ); }); + + it('should navigate to hycu order on click order button ', async () => { + await renderTestApp(); + + await act(() => + userEvent.click(screen.getByText(labels.listing.hycu_order)), + ); + + await waitFor( + () => + expect(screen.getByText(labels.order.hycu_order_title)).toBeVisible(), + { timeout: 30_000 }, + ); + }); }); diff --git a/packages/manager/apps/hycu/src/pages/onboarding/Onboarding.page.tsx b/packages/manager/apps/hycu/src/pages/onboarding/Onboarding.page.tsx index 3e8b8641a796..540de1555857 100644 --- a/packages/manager/apps/hycu/src/pages/onboarding/Onboarding.page.tsx +++ b/packages/manager/apps/hycu/src/pages/onboarding/Onboarding.page.tsx @@ -1,11 +1,14 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { Card, OnboardingLayout } from '@ovh-ux/manager-react-components'; +import { useNavigate } from 'react-router-dom'; import useGuideUtils from '@/hooks/guide/useGuideUtils'; import onboardingImgSrc from './hycu-x-ovhcloud.svg'; import HYCU_CONFIG from '@/hycu.config'; +import { urls } from '@/routes/routes.constant'; export default function Onboarding() { + const navigate = useNavigate(); const { t } = useTranslation('hycu/onboarding'); const { t: tCommon } = useTranslation('hycu'); const link = useGuideUtils(); @@ -53,7 +56,9 @@ export default function Onboarding() { img={imgSrc} description={description} orderButtonLabel={t('orderButtonLabel')} - orderHref={t('orderButtonLink')} + onOrderButtonClick={() => { + navigate(urls.order); + }} moreInfoButtonLabel={t('moreInfoButtonLabel')} moreInfoHref={link?.main} > diff --git a/packages/manager/apps/hycu/src/pages/order/Order.page.tsx b/packages/manager/apps/hycu/src/pages/order/Order.page.tsx index 14f0783c453e..706b2114d653 100644 --- a/packages/manager/apps/hycu/src/pages/order/Order.page.tsx +++ b/packages/manager/apps/hycu/src/pages/order/Order.page.tsx @@ -8,6 +8,7 @@ import Breadcrumb from '@/components/Breadcrumb/Breadcrumb.component'; import OrderConfirmation from '@/components/Order/OrderConfirmation'; import PackSelection from '@/components/Order/PackSelection'; import useOrderHYCU from '@/hooks/order/useOrderHYCU'; +import { BreadcrumbItem } from '@/hooks/breadcrumb/useBreadcrumb'; export default function Order() { const { t } = useTranslation('hycu/order'); @@ -29,9 +30,16 @@ export default function Order() { region: subsidiary, }); + const breadcrumbItems: BreadcrumbItem[] = [ + { + id: 'order', + label: t('hycu_order_title'), + }, + ]; + return ( } + breadcrumb={} description={description} header={header} > diff --git a/packages/manager/apps/hycu/src/routes/routes.constant.ts b/packages/manager/apps/hycu/src/routes/routes.constant.ts index a8be45c4ea7f..b9d1adde65e0 100644 --- a/packages/manager/apps/hycu/src/routes/routes.constant.ts +++ b/packages/manager/apps/hycu/src/routes/routes.constant.ts @@ -1,13 +1,13 @@ export const subRoutes = { onboarding: 'onboarding', + order: 'order', serviceName: ':serviceName', }; export const urls = { root: '/', - onboarding: `/${subRoutes.onboarding}`, listing: '/', + onboarding: `/${subRoutes.onboarding}`, + order: `/${subRoutes.order}`, dashboard: `/${subRoutes.serviceName}`, - tab2: 'Tab2', - order: '/order', } as const; From 56de7fbc37d772cabdffad80bb38833ee343aa06 Mon Sep 17 00:00:00 2001 From: "Thibault Barske (Tibs)" Date: Fri, 18 Oct 2024 10:22:51 +0200 Subject: [PATCH 11/43] feat(hycu): add product HYCU for OVHCloud (#13244) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ref: MANAGER-14488 Signed-off-by: Thibault Barske Co-authored-by: David Arsène --- yarn.lock | 70 +++++++++++++++++++++---------------------------------- 1 file changed, 27 insertions(+), 43 deletions(-) diff --git a/yarn.lock b/yarn.lock index bcf6f054be84..1d60342732c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -792,6 +792,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz#d50e8d37b1176207b4fe9acedec386c565a44a54" integrity sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g== +"@babel/helper-string-parser@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c" + integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== + "@babel/helper-validator-identifier@^7.22.19", "@babel/helper-validator-identifier@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" @@ -807,6 +812,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz#77b7f60c40b15c97df735b38a66ba1d7c3e93da5" integrity sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg== +"@babel/helper-validator-identifier@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" + integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== + "@babel/helper-validator-option@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" @@ -946,11 +956,11 @@ "@babel/types" "^7.25.8" "@babel/parser@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.7.tgz#99b927720f4ddbfeb8cd195a363ed4532f87c590" - integrity sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw== + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.9.tgz#8fcaa079ac7458facfddc5cd705cc8005e4d3817" + integrity sha512-aI3jjAAO1fh7vY/pBGsn1i9LDbRP43+asrRlkPuTXW5yHXtd1NgTEMudbBoDDxrf1daEEfPJqR+JBMakzrR4Dg== dependencies: - "@babel/types" "^7.25.7" + "@babel/types" "^7.25.9" "@babel/parser@^7.7.0": version "7.10.3" @@ -2111,6 +2121,14 @@ "@babel/helper-validator-identifier" "^7.25.7" to-fast-properties "^2.0.0" +"@babel/types@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.9.tgz#620f35ea1f4233df529ec9a2668d2db26574deee" + integrity sha512-OwS2CM5KocvQ/k7dFJa8i5bNGJP0hXWfVCfDkqRFP1IreH1JDC7wG6eCYCi0+McbfT8OR/kNqsI0UU0xP9H6PQ== + dependencies: + "@babel/helper-string-parser" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + "@base2/pretty-print-object@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" @@ -9786,7 +9804,7 @@ strip-literal "^2.0.0" test-exclude "^6.0.0" -"@vitest/coverage-v8@^2.1.3": +"@vitest/coverage-v8@^2.1.2", "@vitest/coverage-v8@^2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@vitest/coverage-v8/-/coverage-v8-2.1.3.tgz#22d519e5e56385ec126305492f5a3cfe5b44b14d" integrity sha512-2OJ3c7UPoFSmBZwqD2VEkUw6A/tzPF0LmW0ZZhhB8PFxuc+9IBG/FaSM+RLEenc7ljzFvGN+G0nGQoZnh7sy2A== @@ -9948,15 +9966,6 @@ version "1.3.1" resolved "https://registry.npmjs.org/@vitest/spy/-/spy-1.3.1.tgz#814245d46d011b99edd1c7528f5725c64e85a88b" integrity sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig== - dependencies: - "@vitest/pretty-format" "2.1.3" - magic-string "^0.30.11" - pathe "^1.1.2" - -"@vitest/spy@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-1.3.1.tgz#814245d46d011b99edd1c7528f5725c64e85a88b" - integrity sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig== dependencies: tinyspy "^2.2.0" @@ -26679,16 +26688,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -26802,14 +26802,7 @@ stringify-entities@^3.0.0: character-entities-legacy "^1.0.0" xtend "^4.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -29148,7 +29141,7 @@ vitest@^2.0.5: vite-node "2.0.5" why-is-node-running "^2.3.0" -vitest@^2.1.3: +vitest@^2.1.2, vitest@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/vitest/-/vitest-2.1.3.tgz#dae1055dd328621b59fc6e594fd988fbf2e5370e" integrity sha512-Zrxbg/WiIvUP2uEzelDNTXmEMJXuzJ1kCpbDvaKByFA9MNeO95V+7r/3ti0qzJzrxdyuUw5VduN7k+D3VmVOSA== @@ -29650,7 +29643,7 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -29676,15 +29669,6 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From d3f7f3eb07e441780350c37efa93f2fe6e0d567a Mon Sep 17 00:00:00 2001 From: Nicode Date: Fri, 18 Oct 2024 11:28:54 +0200 Subject: [PATCH 12/43] feat(veeam-backup): add new product veeam-backup (#12611) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ref: MANAGER-14740 Signed-off-by: Nicolas Pierre-charles Co-authored-by: David Arsène --- yarn.lock | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/yarn.lock b/yarn.lock index 1d60342732c6..aa77e2f0e5c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9969,6 +9969,13 @@ dependencies: tinyspy "^2.2.0" +"@vitest/spy@1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-1.3.1.tgz#814245d46d011b99edd1c7528f5725c64e85a88b" + integrity sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig== + dependencies: + tinyspy "^2.2.0" + "@vitest/spy@1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-1.4.0.tgz#cf953c93ae54885e801cbe6b408a547ae613f26c" From 9f1059281f2b8fa3883b04fc41358749d376bb69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ars=C3=A8ne?= Date: Thu, 24 Oct 2024 18:10:33 +0200 Subject: [PATCH 13/43] feat(hycu): add hycu service on hub and my services MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ref: MANAGER-14762 Signed-off-by: David Arsène --- .../hub/products/Messages_fr_FR.json | 1 + .../products/Products.component.tsx | 28 ++++++++++--------- .../components/products/Products.constants.ts | 4 +++ .../src/hooks/products/useProducts.spec.tsx | 5 ++-- .../translations/Messages_fr_FR.json | 1 + .../products/listing-pages.constants.js | 4 +++ .../products/translations/Messages_fr_FR.json | 1 + 7 files changed, 29 insertions(+), 15 deletions(-) diff --git a/packages/manager/apps/hub-react/public/translations/hub/products/Messages_fr_FR.json b/packages/manager/apps/hub-react/public/translations/hub/products/Messages_fr_FR.json index 074d7f76ccd3..827f403e41f4 100644 --- a/packages/manager/apps/hub-react/public/translations/hub/products/Messages_fr_FR.json +++ b/packages/manager/apps/hub-react/public/translations/hub/products/Messages_fr_FR.json @@ -37,6 +37,7 @@ "manager_hub_products_LICENSE_VIRTUOZZO": "Licences Virtuozzo", "manager_hub_products_LICENSE_WORKLIGHT": "Licences Worklight", "manager_hub_products_LICENSE_SQLSERVER": "Licences SQL Server", + "manager_hub_products_LICENSE_HYCU": "HYCU", "manager_hub_products_LICENCE_WINDOWS": "Licences Windows", "manager_hub_products_LICENCE_OFFICE": "Licences Office 365", "manager_hub_products_LICENCE_CLOUD_LINUX": "Licences CloudLinux", diff --git a/packages/manager/apps/hub-react/src/components/products/Products.component.tsx b/packages/manager/apps/hub-react/src/components/products/Products.component.tsx index 026858bbf71b..afb24b408730 100644 --- a/packages/manager/apps/hub-react/src/components/products/Products.component.tsx +++ b/packages/manager/apps/hub-react/src/components/products/Products.component.tsx @@ -105,15 +105,15 @@ export default function Products({ services }: ProductsProps) { {product.count} - {product.link && ( - - } - > - ( + + } + > + + link ? ( <> - )} - /> - - )} + ) : ( + <> + ) + } + /> +
    { }, ); - await waitFor(() => { - expect(result.current.products[0].link).toBeNull(); + await waitFor(async () => { + const link = await result.current.products[0].link; + expect(link).toBeNull(); }); }); diff --git a/packages/manager/modules/billing/src/autoRenew/translations/Messages_fr_FR.json b/packages/manager/modules/billing/src/autoRenew/translations/Messages_fr_FR.json index a2061afbd2e6..b905a258f263 100644 --- a/packages/manager/modules/billing/src/autoRenew/translations/Messages_fr_FR.json +++ b/packages/manager/modules/billing/src/autoRenew/translations/Messages_fr_FR.json @@ -149,6 +149,7 @@ "billing_autorenew_service_type_LICENSE_SQLSERVER": "Licences SQL Server", "billing_autorenew_service_type_LICENCE_SQLSERVER": "Licences SQL Server", "billing_autorenew_service_type_LICENSE_OFFICE_PREPAID": "Licences Office 365", + "billing_autorenew_service_type_LICENSE_HYCU": "HYCU", "billing_autorenew_service_type_MS_SERVICES_SHAREPOINT": "Microsoft SharePoint", "billing_autorenew_service_type_PACK_XDSL": "Packs xDSL", "billing_autorenew_service_type_VRACK": "vRacks", diff --git a/packages/manager/modules/hub/src/components/products/listing-pages.constants.js b/packages/manager/modules/hub/src/components/products/listing-pages.constants.js index 5336ca6e6a29..60bc5c2bf96d 100644 --- a/packages/manager/modules/hub/src/components/products/listing-pages.constants.js +++ b/packages/manager/modules/hub/src/components/products/listing-pages.constants.js @@ -99,6 +99,10 @@ const productListingPages = { application: 'dedicated', hash: '#/license', }, + LICENSE_HYCU: { + application: 'hycu', + hash: '#', + }, LICENSE_OFFICE: { application: 'web', hash: '#/office/license', diff --git a/packages/manager/modules/hub/src/components/products/translations/Messages_fr_FR.json b/packages/manager/modules/hub/src/components/products/translations/Messages_fr_FR.json index 194be480d691..a1a408d8a402 100644 --- a/packages/manager/modules/hub/src/components/products/translations/Messages_fr_FR.json +++ b/packages/manager/modules/hub/src/components/products/translations/Messages_fr_FR.json @@ -36,6 +36,7 @@ "manager_hub_products_LICENSE_VIRTUOZZO": "Licences Virtuozzo", "manager_hub_products_LICENSE_WORKLIGHT": "Licences Worklight", "manager_hub_products_LICENSE_SQLSERVER": "Licences SQL Server", + "manager_hub_products_LICENSE_HYCU": "HYCU", "manager_hub_products_LICENCE_WINDOWS": "Licences Windows", "manager_hub_products_LICENCE_OFFICE": "Licences Office 365", "manager_hub_products_LICENCE_CLOUD_LINUX": "Licences CloudLinux", From 0c52755692a09bbc804b56cdda9375b379900f2b Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Fri, 25 Oct 2024 09:19:43 +0200 Subject: [PATCH 14/43] feat(hycu): add renew link on dashboard ref: 14499 Signed-off-by: Thibault Barske --- .../BillingInformationsTile.spec.tsx | 3 ++- .../BillingInformationsTile.tsx | 14 +++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.spec.tsx index b5562fb9a1ac..bf52fc02de2d 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.spec.tsx @@ -2,10 +2,11 @@ import { screen, waitFor } from '@testing-library/react'; import { renderTestApp } from '@/utils/tests/renderTestApp'; import '@testing-library/jest-dom'; import { labels } from '@/utils/tests/init.i18n'; +import { licensesHycu } from '@/mocks/licenseHycu/licenseHycu.data'; describe('License Hycu billing information tile for dashboard test suite', () => { it('should show informations of services', async () => { - await renderTestApp('/fake-id'); + await renderTestApp(`/${licensesHycu[0].serviceName}`); await waitFor( () => diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx index cef4561d3014..d6699e96ba56 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx @@ -43,6 +43,12 @@ const BillingInformationsTile = ({ serviceName }: { serviceName: string }) => { { serviceName }, ]); + const { data: renewUrl, isLoading: isRenewUrlLoading } = useNavigationGetUrl([ + 'dedicated', + '#/billing/autorenew', + { searchText: serviceName }, + ]); + return ( { value: isLoading ? ( ) : ( - {renewDate} + + {renewDate} + ), }, { From 95e0ad7d645afacd97b5ec9939898da51c5b0fc2 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Thu, 24 Oct 2024 21:29:16 +0200 Subject: [PATCH 15/43] feat(hycu): add activate license modal ref: MANAGER-15175 Signed-off-by: Thibault Barske --- .../src/hooks/iam/useOvhIam.tsx | 3 +- packages/manager/apps/hycu/package.json | 1 + .../translations/hycu/Messages_fr_FR.json | 6 +- .../hycu/dashboard/Messages_fr_FR.json | 15 +- .../FileUpload/FileUpload.component.tsx | 145 ++++++++++++++ .../ManagerLink/ManagerLink.component.tsx | 46 +++++ .../manager/apps/hycu/src/data/api/hycu.ts | 31 ++- .../apps/hycu/src/hooks/api/license.ts | 55 +++++- .../apps/hycu/src/mocks/iam/iam.handler.ts | 15 ++ .../apps/hycu/src/mocks/iam/iam.mock.ts | 16 ++ .../src/mocks/licenseHycu/licenseHycu.data.ts | 2 +- .../hycu/src/mocks/licenseHycu/licenseHycu.ts | 35 +++- .../pages/dashboard/Dashboard.page.spec.tsx | 4 +- .../src/pages/dashboard/Dashboard.page.tsx | 17 +- .../DashboardGeneralInformation.page.tsx | 25 +-- .../GeneralInformationsTile.spec.tsx | 8 +- .../GeneralInformationsTile.tsx | 14 +- .../ShortcutsTile/ShortcutsTile.spec.tsx | 97 ++++++++- .../ShortcutsTile/ShortcutsTile.tsx | 32 ++- .../ActivationLicenseModal.page.spec.tsx | 187 ++++++++++++++++++ .../ActivationLicenseModal.page.tsx | 144 ++++++++++++++ .../hycu/src/pages/listing/Listing.page.tsx | 2 +- .../apps/hycu/src/routes/routes.constant.ts | 1 + .../manager/apps/hycu/src/routes/routes.tsx | 11 ++ .../hycu/src/types/hycu.details.interface.ts | 2 +- .../apps/hycu/src/utils/iam.constants.ts | 3 + .../hycu/src/utils/tests/renderTestApp.tsx | 4 +- yarn.lock | 5 + 28 files changed, 855 insertions(+), 71 deletions(-) create mode 100644 packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx create mode 100644 packages/manager/apps/hycu/src/components/ManagerLink/ManagerLink.component.tsx create mode 100644 packages/manager/apps/hycu/src/mocks/iam/iam.handler.ts create mode 100644 packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts create mode 100644 packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.spec.tsx create mode 100644 packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.tsx create mode 100644 packages/manager/apps/hycu/src/utils/iam.constants.ts diff --git a/packages/manager-react-components/src/hooks/iam/useOvhIam.tsx b/packages/manager-react-components/src/hooks/iam/useOvhIam.tsx index c03f58511aef..3d0d8deeee52 100644 --- a/packages/manager-react-components/src/hooks/iam/useOvhIam.tsx +++ b/packages/manager-react-components/src/hooks/iam/useOvhIam.tsx @@ -50,8 +50,9 @@ export function useAuthorizationIam( const { data, ...query } = useQuery({ queryKey: [urn, actions], queryFn: () => fetchAuthorizationCheck(actions, urn), - enabled: + enabled: Boolean( urn && urn.length > 0 && actions && actions.length > 0 && isTrigger, + ), placeholderData: keepPreviousData, }); diff --git a/packages/manager/apps/hycu/package.json b/packages/manager/apps/hycu/package.json index 6d7d2fcdab32..eae8c67a74f6 100644 --- a/packages/manager/apps/hycu/package.json +++ b/packages/manager/apps/hycu/package.json @@ -40,6 +40,7 @@ "i18next-http-backend": "^2.4.2", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-hook-form": "^7.53.1", "react-i18next": "^14.0.5", "react-router-dom": "^6.3.0", "tailwindcss": "^3.4.4" diff --git a/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json index a9a3a8b8dee5..5d312a1aefbf 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json @@ -1,10 +1,10 @@ { "hycu_crumb": "HYCU", - "tabs_2": "Tabs 2", "hycu_description": "Simplifiez vos sauvegardes, plans de reprise après sinistre et migrations de votre infrastructure Nutanix. Ce service vous propose différents packs de licences HYCU Hybrid Cloud pour protéger vos charges de travail Nutanix.", "hycu_cloud_vm_pack_unknown": "Pack inconnu", "hycu_status_activated": "Active", "hycu_status_toActivate": "À activer", - "hycu_status_pending": "En cours d'activation", - "hycu_status_error": "Erreur d'activation" + "hycu_status_processing": "En cours d'activation", + "hycu_status_error": "Erreur d'activation", + "common_iam_actions_message": "Vous ne disposez pas des permissions nécessaires pour effectuer cette action, veuillez contacter votre administrateur" } diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json index 4f6227f18791..ccef3a134723 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json @@ -21,5 +21,18 @@ "hycu_dashboard_field_label_date_creation": "Date de création", "hycu_dashboard_download_license_file": "Télécharger la license", "hycu_dashboard_back_link": "Retour à la liste", - "hycu_dashboard_wait_for_activation": "En attente d'activation" + "hycu_dashboard_wait_for_activation": "En attente d'activation", + "hycu_dashboard_license_activate_heading": "Activer la licence", + "hycu_dashboard_license_activate_description": "Veuillez transférer votre fichier de demande de licence. Ce fichier est à télécharger depuis votre controller HYCU une fois votre installation réalisée", + "hycu_dashboard_license_more_information_link": "(plus de détails ici)", + "hycu_dashboard_activation_license_success_message": "La demande d'activation de votre licence a bien été prise en compte. Votre fichier de licence sera bientôt disponible sur cette interface et vous sera également envoyé par e-mail.", + "hycu_dashboard_activation_license_error_message": "Une erreur est survenue lors de la soumission de votre license.", + "hycu_dashboard_license_upload": "Upload", + "hycu_dashboard_upload_cancel": "Annuler", + "hycu_dashboard_upload_confirm": "Activer", + "hycu_dashboard_upload_valid_file": "Merci de sélectionner un fichier valide", + "hycu_dashboard_upload_license_required": "Veuillez sélectionner une license", + "hycu_dashboard_drag_and_drop_attachment": "Glissez-Déposer une pièce jointe", + "hycu_dashboard_accepted_formats": "Format accepté: .dat", + "hycu_dashboard_browse": "Parcourir" } diff --git a/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx b/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx new file mode 100644 index 000000000000..5c4c828f2b29 --- /dev/null +++ b/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx @@ -0,0 +1,145 @@ +import { + ODS_BUTTON_SIZE, + ODS_BUTTON_TYPE, + ODS_BUTTON_VARIANT, + ODS_ICON_NAME, + ODS_ICON_SIZE, +} from '@ovhcloud/ods-components'; +import { + ODS_THEME_COLOR_INTENT, + ODS_THEME_TYPOGRAPHY_SIZE, +} from '@ovhcloud/ods-common-theming'; +import { OsdsButton, OsdsIcon, OsdsText } from '@ovhcloud/ods-components/react'; +import React, { ChangeEvent, useRef, useState } from 'react'; +import { Controller, UseControllerProps } from 'react-hook-form'; +import { useTranslation } from 'react-i18next'; + +const MAX_FILE_SIZE = 10e3; // 1 MB limit ~ + +export const FileInputField = ({ + name, + control, + ...rest +}: UseControllerProps) => { + const { t } = useTranslation('hycu/dashboard'); + const [fileName, setFileName] = useState(''); + const fileInputRef = useRef(null); + const [isDragHover, setIsDragHover] = useState(false); + + const parseFile = async (file: File, onChange: (result: string) => void) => { + onChange(undefined); + if (file.size > MAX_FILE_SIZE) { + setFileName(''); + control.setError(name, { + message: t('hycu_dashboard_upload_valid_file'), + }); + return; + } + + const reader = new FileReader(); + reader.onloadend = () => { + const base64String = btoa(reader.result as string); + onChange(base64String); + setFileName(file.name); + control.setError(name, undefined); + }; + reader.readAsDataURL(file); + }; + + const handleFileChange = async ( + event: ChangeEvent, + onChange: (result: string) => void, + ) => { + const file = event.target.files[0]; + if (file) parseFile(file, onChange); + }; + + const handleDrop = async ( + event: React.DragEvent, + onChange: (result: string) => void, + ) => { + setIsDragHover(false); + event.preventDefault(); + event.stopPropagation(); + if (event.dataTransfer.files[0]) + parseFile(event.dataTransfer.files[0], onChange); + }; + + const handleDragOver = (event: React.DragEvent) => { + // eslint-disable-next-line no-param-reassign + event.dataTransfer.dropEffect = 'copy'; + event.preventDefault(); + event.stopPropagation(); + }; + + return ( + ( + <> + handleFileChange(e, onChange)} + style={{ display: 'none' }} + /> +
    setIsDragHover(true)} + onDragLeave={() => setIsDragHover(false)} + onDragOver={(e) => handleDragOver(e)} + onDrop={(e) => handleDrop(e, onChange)} + > + + + {t('hycu_dashboard_drag_and_drop_attachment')} + + + {t('hycu_dashboard_accepted_formats')} + + fileInputRef.current.click()} + inline + > + {t('hycu_dashboard_browse')} + + + {error?.message} + + {fileName && ( + + + {fileName} + + )} +
    + + )} + /> + ); +}; diff --git a/packages/manager/apps/hycu/src/components/ManagerLink/ManagerLink.component.tsx b/packages/manager/apps/hycu/src/components/ManagerLink/ManagerLink.component.tsx new file mode 100644 index 000000000000..5bd63e346c11 --- /dev/null +++ b/packages/manager/apps/hycu/src/components/ManagerLink/ManagerLink.component.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import { + OsdsLink, + OsdsTooltip, + OsdsTooltipContent, +} from '@ovhcloud/ods-components/react'; +import { useTranslation } from 'react-i18next'; +import { useAuthorizationIam } from '@ovh-ux/manager-react-components'; + +export type ManagerLinkProps = React.ComponentProps & { + iamActions?: string[]; + urn?: string; + displayTooltip?: boolean; + isIamTrigger?: boolean; +}; + +export const ManagerLink = ({ + children, + iamActions, + urn, + displayTooltip = true, + isIamTrigger = true, + ...restProps +}: ManagerLinkProps) => { + const { t } = useTranslation('hycu'); + const { isAuthorized } = useAuthorizationIam(iamActions, urn, isIamTrigger); + + if (isAuthorized) { + return {children}; + } + + return !displayTooltip ? ( + + {children} + + ) : ( + + + {children} + + +
    {t('common_iam_actions_message')}
    +
    +
    + ); +}; diff --git a/packages/manager/apps/hycu/src/data/api/hycu.ts b/packages/manager/apps/hycu/src/data/api/hycu.ts index a21d12cf6aeb..f181d9bf9c0a 100644 --- a/packages/manager/apps/hycu/src/data/api/hycu.ts +++ b/packages/manager/apps/hycu/src/data/api/hycu.ts @@ -7,12 +7,21 @@ export type GetlicenseHycuListParams = { iamTags: string; }; -export const getlicenseHycuListQueryKey = ['get/license/hycu']; +export const getLicenseHycuListQueryKey = () => ['license/hycu', 'get', 'list']; +export const getLicenseHycuQueryKey = (serviceName: string) => [ + 'license/hycu', + 'get', + serviceName, +]; +export const postActivateLicenseHycuMutationKey = () => [ + 'license/hycu/activate', + 'post', +]; /** * Manage HYCU licenses : Get list of owned HYCU licenses */ -export const getlicenseHycuList = ( +export const getLicenseHycu = ( params: GetlicenseHycuListParams, ): Promise => apiClient.v6.get('/license/hycu', { data: params }); @@ -24,11 +33,27 @@ export type GetlicenseHycuServiceParams = { /** * Manage HYCU licenses : Get HYCU license info */ -export const getlicenseHycuService = ( +export const getLicenseHycuService = ( params: GetlicenseHycuServiceParams, ): Promise> => apiClient.v6.get(`/license/hycu/${params.serviceName}`); +export type PostLicenseHycuActivateServiceParams = { + /** Service name */ + serviceName: string; + licenseContent: string; +}; + +/** + * Activate HYCU licenses : Post HYCU license content + */ +export const postLicenseHycuActivateService = ( + params: PostLicenseHycuActivateServiceParams, +): Promise => + apiClient.v6.post(`/license/hycu/${params.serviceName}/activate`, { + licenseRequest: params.licenseContent, + }); + /** * Get listing with iceberg V6 */ diff --git a/packages/manager/apps/hycu/src/hooks/api/license.ts b/packages/manager/apps/hycu/src/hooks/api/license.ts index f92474b566f6..6d95c0f146f0 100644 --- a/packages/manager/apps/hycu/src/hooks/api/license.ts +++ b/packages/manager/apps/hycu/src/hooks/api/license.ts @@ -1,15 +1,60 @@ import { AxiosResponse } from 'axios'; -import { DefinedInitialDataOptions, useQuery } from '@tanstack/react-query'; -import { getlicenseHycuService } from '@/data/api/hycu'; +import { + DefinedInitialDataOptions, + UseMutationOptions, + useQuery, + useMutation, + useQueryClient, +} from '@tanstack/react-query'; +import { getServiceDetailsQueryKey } from '@ovh-ux/manager-react-components'; +import { + getLicenseHycuListQueryKey, + getLicenseHycuQueryKey, + getLicenseHycuService, + postActivateLicenseHycuMutationKey, + postLicenseHycuActivateService, + PostLicenseHycuActivateServiceParams, +} from '@/data/api/hycu'; import { IHycuDetails } from '@/types/hycu.details.interface'; export const useDetailsLicenseHYCU = ( serviceName: string, - options?: DefinedInitialDataOptions>, + options?: Partial>>, ) => { return useQuery({ - queryKey: ['license/hycu', 'get', serviceName], - queryFn: () => getlicenseHycuService({ serviceName }), + queryKey: getLicenseHycuQueryKey(serviceName), + queryFn: () => getLicenseHycuService({ serviceName }), ...(options ?? {}), }); }; + +export const useActivateLicenseHYCUMutation = ( + options: Partial< + UseMutationOptions< + AxiosResponse, + Error, + PostLicenseHycuActivateServiceParams + > + > = {}, +) => { + const queryClient = useQueryClient(); + + const { onSuccess, ...restOptions } = options; + + return useMutation({ + mutationKey: postActivateLicenseHycuMutationKey(), + mutationFn: (params) => postLicenseHycuActivateService(params), + onSuccess: (data, variables, context) => { + queryClient.invalidateQueries({ queryKey: getLicenseHycuListQueryKey() }); + queryClient.invalidateQueries({ + queryKey: getServiceDetailsQueryKey(variables.serviceName), + }); + queryClient.invalidateQueries({ + queryKey: getLicenseHycuQueryKey(variables.serviceName), + }); + + onSuccess?.(data, variables, context); + }, + ...(restOptions ?? {}), + }); +}; diff --git a/packages/manager/apps/hycu/src/mocks/iam/iam.handler.ts b/packages/manager/apps/hycu/src/mocks/iam/iam.handler.ts new file mode 100644 index 000000000000..0d2ee1e39f5b --- /dev/null +++ b/packages/manager/apps/hycu/src/mocks/iam/iam.handler.ts @@ -0,0 +1,15 @@ +import { PathParams } from 'msw'; +import { Handler } from '../../../../../../../playwright-helpers'; +import { resourceList } from './iam.mock'; + +const findResourceByUrn = (params: PathParams) => + resourceList.find(({ urn }) => urn === params.urn); + +export const getIamMocks = (): Handler[] => [ + { + url: '/iam/resource/:urn/authorization/check', + response: (_: unknown, params: PathParams) => findResourceByUrn(params), + api: 'v2', + method: 'post', + }, +]; diff --git a/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts b/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts new file mode 100644 index 000000000000..4a01a599cf13 --- /dev/null +++ b/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts @@ -0,0 +1,16 @@ +import { IamCheckResponse } from '@ovh-ux/manager-react-components'; +import { licensesHycu } from '../licenseHycu/licenseHycu.data'; +import { IAM_ACTIONS } from '@/utils/iam.constants'; + +export const resourceList: IamCheckResponse[] = [ + { + urn: licensesHycu[0].iam.urn, + authorizedActions: [IAM_ACTIONS.licenseHycuApiovhActivate], + unauthorizedActions: [], + }, + { + urn: licensesHycu[1].iam.urn, + authorizedActions: [], + unauthorizedActions: [], + }, +]; diff --git a/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.data.ts b/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.data.ts index 4136c839cbab..4ade2e3e461b 100644 --- a/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.data.ts +++ b/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.data.ts @@ -1,6 +1,6 @@ import { IHycuDetails, LicenseStatus } from '@/types/hycu.details.interface'; -export const licensesHycu: IHycuDetails[] = [ +export const licensesHycu: Readonly = [ { iam: { id: '4a26ef55-d46b-4b71-88c8-76ad71b154b4', diff --git a/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts b/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts index 896897416377..db57ffa1c9db 100644 --- a/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts +++ b/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts @@ -1,15 +1,18 @@ +import { PathParams } from 'msw'; import { LicenseStatus } from '@/types/hycu.details.interface'; import { Handler } from '../../../../../../../playwright-helpers'; import { licensesHycu } from './licenseHycu.data'; export type GetLicenseHycuMocksParams = { isGetLicenseHycuKo?: boolean; + isPostLicenseHycuKo?: boolean; nbLicenseHycu?: number; licenseStatus?: LicenseStatus; }; export const getLicenseHycuMocks = ({ isGetLicenseHycuKo, + isPostLicenseHycuKo, nbLicenseHycu = Number.POSITIVE_INFINITY, licenseStatus = LicenseStatus.TO_ACTIVATE, }: GetLicenseHycuMocksParams): Handler[] => { @@ -28,18 +31,30 @@ export const getLicenseHycuMocks = ({ }, { url: 'license/hycu/:serviceName', - response: isGetLicenseHycuKo - ? { - message: 'Backup error', - } - : { - ...licensesHycu[0], - licenseStatus, - controllerId: - licenseStatus !== LicenseStatus.TO_ACTIVATE ? 'test-id' : '', - }, + response: (_: unknown, params: PathParams) => { + return isGetLicenseHycuKo + ? { + message: 'Backup error', + } + : { + ...licensesHycu.find( + (licenseHycu) => licenseHycu.serviceName === params.serviceName, + ), + licenseStatus, + controllerId: + licenseStatus !== LicenseStatus.TO_ACTIVATE ? 'test-id' : '', + }; + }, status: isGetLicenseHycuKo ? 500 : 200, api: 'v6', }, + + { + url: 'license/hycu/:serviceName/activate', + response: null, + method: 'post', + status: isPostLicenseHycuKo ? 500 : 200, + api: 'v6', + }, ]; }; diff --git a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.spec.tsx index 5bab4a2ccd8d..4520dadf9998 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.spec.tsx @@ -4,7 +4,7 @@ import '@testing-library/jest-dom'; describe('License Hycu Dashboard route test suite', () => { it('should show informations of services', async () => { - await renderTestApp('/fake-id'); + await renderTestApp('/4a26ef55-d46b-4b71-88c8-76ad71b154b4'); await waitFor( () => @@ -18,7 +18,7 @@ describe('License Hycu Dashboard route test suite', () => { }); it('should show error if api services fail', async () => { - await renderTestApp('/fake-id', { + await renderTestApp('/4a26ef55-d46b-4b71-88c8-76ad71b154b4', { getServicesKo: true, isGetLicenseHycuKo: true, isGetServiceLicenseHycuKo: true, diff --git a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx index 4f718e86902f..2614a12a960b 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx @@ -1,9 +1,8 @@ -import React, { useState, useEffect } from 'react'; +import React from 'react'; import { useTranslation } from 'react-i18next'; import { Outlet, NavLink, - useLocation, useNavigate, useResolvedPath, useParams, @@ -17,6 +16,7 @@ import { import { BaseLayout, useServiceDetails, + Notifications, } from '@ovh-ux/manager-react-components'; import Breadcrumb from '@/components/Breadcrumb/Breadcrumb.component'; @@ -35,8 +35,6 @@ export type DashboardLayoutProps = { export default function DashboardPage() { const { serviceName } = useParams(); - const [panel, setActivePanel] = useState(''); - const location = useLocation(); const navigate = useNavigate(); const { t } = useTranslation('hycu/dashboard'); @@ -52,15 +50,7 @@ export default function DashboardPage() { }, ] as const; - useEffect(() => { - const activeTab = tabsList.find((tab) => tab.to === location.pathname); - if (activeTab) { - setActivePanel(activeTab.name); - } else { - setActivePanel(tabsList[0].name); - navigate(`${tabsList[0].to}`); - } - }, [location.pathname]); + const panel = tabsList[0].name; const header = { title: serviceDetails?.data.resource.displayName, @@ -83,6 +73,7 @@ export default function DashboardPage() { onClickReturn={() => { navigate(urls.listing); }} + message={} tabs={ diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/DashboardGeneralInformation.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/DashboardGeneralInformation.page.tsx index 09627a1c37c2..50937a5b2edc 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/DashboardGeneralInformation.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/DashboardGeneralInformation.page.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { useParams } from 'react-router-dom'; +import { Outlet, useParams } from 'react-router-dom'; import BillingInformationsTile from './BillingInformations/BillingInformationsTile'; import GeneralInformationsTile from './GeneralInformationsTiles/GeneralInformationsTile'; import ShortcutsTile from './ShortcutsTile/ShortcutsTile'; @@ -8,17 +8,20 @@ function GeneralInfos() { const { serviceName } = useParams(); return ( -
    -
    - + <> +
    +
    + +
    +
    + +
    +
    + +
    -
    - -
    -
    - -
    -
    + + ); } diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx index 338b97b16a21..5947f5d9f19b 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx @@ -6,7 +6,7 @@ import { LicenseStatus } from '@/types/hycu.details.interface'; describe('License Hycu general informations tile for dashboard test suite', () => { it('should show informations of services', async () => { - await renderTestApp('/fake-id'); + await renderTestApp('/4a26ef55-d46b-4b71-88c8-76ad71b154b4'); await waitFor( () => @@ -40,7 +40,9 @@ describe('License Hycu general informations tile for dashboard test suite', () = }); it('should show download license button when license is activated', async () => { - await renderTestApp('/fake-id', { licenseStatus: LicenseStatus.ACTIVATED }); + await renderTestApp('/4a26ef55-d46b-4b71-88c8-76ad71b154b4', { + licenseStatus: LicenseStatus.ACTIVATED, + }); await waitFor( () => @@ -68,7 +70,7 @@ describe('License Hycu general informations tile for dashboard test suite', () = }); it('should show wait for activation if license is not activated', async () => { - await renderTestApp('/fake-id', { + await renderTestApp('/4a26ef55-d46b-4b71-88c8-76ad71b154b4', { licenseStatus: LicenseStatus.TO_ACTIVATE, }); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx index c3f20b738151..ee0abae27a6d 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx @@ -25,16 +25,20 @@ import { useTranslation } from 'react-i18next'; import { getStatusColor } from '@/utils/statusColor'; import { useDetailsLicenseHYCU } from '@/hooks/api/license'; import { LicenseStatus } from '@/types/hycu.details.interface'; +import { subRoutes, urls } from '@/routes/routes.constant'; -const DownloadHycuLicense = ({ serviceName }: { serviceName: string }) => { +const ActivateHycuLicense = ({ serviceName }: { serviceName: string }) => { const { t } = useTranslation('hycu/dashboard'); const { data: hycuDetail, isLoading } = useDetailsLicenseHYCU(serviceName); if (isLoading) return ; - if (LicenseStatus.ACTIVATED !== hycuDetail.data.licenseStatus) + if (LicenseStatus.ACTIVATED !== hycuDetail?.data.licenseStatus) return <>{t('hycu_dashboard_wait_for_activation')}; return ( - + {t('hycu_dashboard_download_license_file')} { value: isLoading ? ( ) : ( - + > ), }, ]} diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx index a346035d6a91..2272f54074b2 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx @@ -1,12 +1,14 @@ import '@testing-library/jest-dom'; -import { screen, waitFor } from '@testing-library/react'; +import { act, screen, waitFor } from '@testing-library/react'; +import { userEvent } from '@testing-library/user-event'; import { renderTestApp } from '@/utils/tests/renderTestApp'; import { labels } from '@/utils/tests/init.i18n'; import { LicenseStatus } from '@/types/hycu.details.interface'; +import { licensesHycu } from '@/mocks/licenseHycu/licenseHycu.data'; describe('License Hycu shortcuts tile for dashboard test suite', () => { it('should show links of service to activate', async () => { - await renderTestApp('/fake-id', { + await renderTestApp(`/${licensesHycu[0].serviceName}`, { licenseStatus: LicenseStatus.TO_ACTIVATE, }); @@ -33,7 +35,42 @@ describe('License Hycu shortcuts tile for dashboard test suite', () => { }); it('should show links of services activated', async () => { - await renderTestApp('/fake-id', { licenseStatus: LicenseStatus.ACTIVATED }); + await renderTestApp(`/${licensesHycu[0].serviceName}`, { + licenseStatus: LicenseStatus.ACTIVATED, + }); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_shortcuts_title, + )[0], + ).toBeVisible(), + { timeout: 30_000 }, + ); + + await waitFor( + () => + expect( + screen.getByText(labels.dashboard.hycu_dashboard_link_reactivate), + ).toBeVisible(), + { timeout: 20_000 }, + ); + await waitFor( + () => + expect( + screen.getByText( + labels.dashboard.hycu_dashboard_link_change_pack_type, + ), + ).toBeVisible(), + { timeout: 20_000 }, + ); + }); + + it('should show links of services activated', async () => { + await renderTestApp(`/${licensesHycu[0].serviceName}`, { + licenseStatus: LicenseStatus.ACTIVATED, + }); await waitFor( () => @@ -62,4 +99,58 @@ describe('License Hycu shortcuts tile for dashboard test suite', () => { { timeout: 20_000 }, ); }); + + it('Can open activate modal with IAM authorization', async () => { + const user = userEvent.setup(); + await renderTestApp(`/${licensesHycu[0].serviceName}`, { + licenseStatus: LicenseStatus.TO_ACTIVATE, + }); + + await waitFor( + () => { + expect( + screen.getByTestId('hycu_link_activated_test_id'), + ).not.toHaveAttribute('disabled'); + }, + { timeout: 30_000 }, + ); + await act(() => + user.click(screen.getByTestId('hycu_link_activated_test_id')), + ); + + await waitFor( + () => + expect( + screen.getByText( + labels.dashboard.hycu_dashboard_license_activate_description, + ), + ).toBeVisible(), + { timeout: 20_000 }, + ); + }); + + it('Can open activate modal without IAM authorization', async () => { + const user = userEvent.setup(); + await renderTestApp(`/${licensesHycu[1].serviceName}`, { + licenseStatus: LicenseStatus.TO_ACTIVATE, + }); + + await waitFor( + () => + expect(screen.getByTestId('hycu_link_activated_test_id')).toBeVisible(), + { timeout: 30_000 }, + ); + + await user.click(screen.getByTestId('hycu_link_activated_test_id')); + + await waitFor( + () => + expect( + screen.queryByText( + labels.dashboard.hycu_dashboard_license_activate_description, + ), + ).not.toBeInTheDocument(), + { timeout: 20_000 }, + ); + }); }); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx index f94f4c5bf6b7..98862049e059 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx @@ -5,14 +5,18 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { ODS_ICON_NAME } from '@ovhcloud/ods-components'; import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import { useNavigate } from 'react-router-dom'; import { useDetailsLicenseHYCU } from '@/hooks/api/license'; import { LicenseStatus } from '@/types/hycu.details.interface'; +import { subRoutes, urls } from '@/routes/routes.constant'; +import { + ManagerLink, + ManagerLinkProps, +} from '@/components/ManagerLink/ManagerLink.component'; +import { IAM_ACTIONS } from '@/utils/iam.constants'; -const ShortcutsItem = ({ - children, - ...rest -}: React.ComponentProps) => ( - +const ShortcutsItem = ({ children, ...rest }: ManagerLinkProps) => ( +
    {children}
    -
    + ); const ShortcutsTile = ({ serviceName }: { serviceName: string }) => { + const navigate = useNavigate(); const { data: hycuDetail } = useDetailsLicenseHYCU(serviceName); const { t } = useTranslation('hycu/dashboard'); const links = { linkActivated: { id: 'link_activated', - value: {t('hycu_dashboard_link_activate')}, + value: ( + { + navigate( + urls.activateLicense.replace(subRoutes.serviceName, serviceName), + ); + }} + > + {t('hycu_dashboard_link_activate')} + + ), }, linkReactivated: { id: 'link_reactivated', diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.spec.tsx new file mode 100644 index 000000000000..91d7f0092970 --- /dev/null +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.spec.tsx @@ -0,0 +1,187 @@ +import { Mock, vi } from 'vitest'; +import { act, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { renderTestApp } from '@/utils/tests/renderTestApp'; +import '@testing-library/jest-dom'; +import { labels } from '@/utils/tests/init.i18n'; +import { licensesHycu } from '@/mocks/licenseHycu/licenseHycu.data'; + +const createFakeFile = () => { + // Create a Blob with the desired content + const content = 'Hello, this is hycu license! Yes trust me !'; + const blob = new Blob([content], { type: 'text/plain' }); + + // Convert the Blob to a File object + return new File([blob], 'license.dat', { + type: 'text/plain', + lastModified: Date.now(), + }); +}; + +describe('License Hycu activate license route test suite', () => { + beforeEach(() => { + vi.restoreAllMocks(); + }); + + it('should show modal title', async () => { + await renderTestApp(`/${licensesHycu[0].serviceName}/activate-license`); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_license_activate_description, + )[0], + ).toBeVisible(), + { timeout: 30_000 }, + ); + + expect(screen.getByTestId('hycu-dashboard-upload-confirm')).toBeVisible(); + + expect(screen.queryByAltText('OOPS')).not.toBeInTheDocument(); + }); + + it('should show error if api services fail', async () => { + await renderTestApp(`/${licensesHycu[0].serviceName}/activate-license`, { + getServicesKo: true, + isGetLicenseHycuKo: true, + isGetServiceLicenseHycuKo: true, + }); + + await waitFor(() => expect(screen.getByAltText('OOPS')).toBeVisible(), { + timeout: 30_000, + }); + }); + + it('should not call mutate when form is empty', async () => { + const user = userEvent.setup(); + await renderTestApp(`/${licensesHycu[0].serviceName}/activate-license`); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_license_activate_description, + )[0], + ).toBeVisible(), + { timeout: 30_000 }, + ); + + const submitButton = screen.getByTestId('hycu-dashboard-upload-confirm'); + await act(() => user.click(submitButton)); + + expect( + screen.getByText(labels.dashboard.hycu_dashboard_upload_license_required), + ).toBeVisible(); + }); + + it('should call mutate when form valid and submitted', async () => { + const user = userEvent.setup(); + await renderTestApp(`/${licensesHycu[0].serviceName}/activate-license`); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_license_activate_description, + )[0], + ).toBeVisible(), + { timeout: 30_000 }, + ); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_upload_confirm, + )[0], + ).toBeVisible(), + { timeout: 10_000 }, + ); + + const submitButton = screen.getByText( + labels.dashboard.hycu_dashboard_upload_confirm, + ); + + await act(() => + user.upload(screen.getByTestId('license-file-input'), createFakeFile()), + ); + + await act(() => user.click(submitButton)); + + expect( + screen.queryByText( + labels.dashboard.hycu_dashboard_upload_license_required, + ), + ).not.toBeInTheDocument(); + + await waitFor( + () => + expect( + screen.queryByText( + labels.dashboard.hycu_dashboard_license_activate_description, + ), + ).not.toBeInTheDocument(), + { timeout: 10_000 }, + ); + }); + + it('should show a error if server fail', async () => { + const user = userEvent.setup(); + await renderTestApp(`/${licensesHycu[0].serviceName}/activate-license`, { + isPostLicenseHycuKo: true, + }); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_license_activate_description, + )[0], + ).toBeVisible(), + { timeout: 30_000 }, + ); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_upload_confirm, + )[0], + ).toBeVisible(), + { timeout: 10_000 }, + ); + + const submitButton = screen.getByText( + labels.dashboard.hycu_dashboard_upload_confirm, + ); + + await act(() => + user.upload(screen.getByTestId('license-file-input'), createFakeFile()), + ); + + await act(() => user.click(submitButton)); + + expect( + screen.queryByText( + labels.dashboard.hycu_dashboard_upload_license_required, + ), + ).not.toBeInTheDocument(); + + await waitFor( + () => { + expect( + screen.queryByText( + labels.dashboard.hycu_dashboard_license_activate_description, + ), + ).toBeVisible(); + expect( + screen.queryAllByText( + labels.dashboard.hycu_dashboard_activation_license_error_message, + )[1], + ).toBeVisible(); + }, + { timeout: 10_000 }, + ); + }); +}); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.tsx new file mode 100644 index 000000000000..8135dad0fb0e --- /dev/null +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.tsx @@ -0,0 +1,144 @@ +import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import { + ODS_BUTTON_TYPE, + ODS_BUTTON_VARIANT, + ODS_LINK_REFERRER_POLICY, + ODS_SPINNER_SIZE, + ODS_TEXT_LEVEL, +} from '@ovhcloud/ods-components'; +import { OdsHTMLAnchorElementTarget } from '@ovhcloud/ods-common-core'; +import { + OsdsButton, + OsdsLink, + OsdsModal, + OsdsSpinner, + OsdsText, +} from '@ovhcloud/ods-components/react'; +import { SubmitHandler, useForm } from 'react-hook-form'; +import { useNavigate, useParams } from 'react-router-dom'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { + Notifications, + useNotifications, +} from '@ovh-ux/manager-react-components'; +import { FileInputField } from '@/components/FileUpload/FileUpload.component'; +import { useActivateLicenseHYCUMutation } from '@/hooks/api/license'; +import useGuideUtils from '@/hooks/guide/useGuideUtils'; + +export type ActivationHycuLicenseModalProps = { + closeModal: () => void; + isLoading?: boolean; + onConfirmActivationHycuLicense: () => void; +}; + +interface FormValues { + license?: string; +} + +export const ActivationHycuLicenseModal: React.FC = () => { + const { serviceName } = useParams(); + const { t } = useTranslation('hycu/dashboard'); + const navigate = useNavigate(); + const closeModal = () => navigate('..'); + const { addSuccess, addError } = useNotifications(); + const link = useGuideUtils(); + const { + control, + handleSubmit, + formState: { isValid, isSubmitted }, + } = useForm(); + const { + mutate, + isPending: isActivationPending, + } = useActivateLicenseHYCUMutation({ + onSuccess: () => { + addSuccess(t('hycu_dashboard_activation_license_success_message'), true); + closeModal(); + }, + onError: () => { + addError(t('hycu_dashboard_activation_license_error_message')); + }, + }); + const onSubmit: SubmitHandler = (data) => { + if (isValid) { + mutate({ serviceName, licenseContent: data.license }); + } + }; + + return ( + closeModal()} + > + +
    +
    + <> + + {t('hycu_dashboard_license_activate_description')}{' '} + + {t('hycu_dashboard_license_more_information_link')} + + + + +
    +
    + { + closeModal(); + }} + inline + > + {t('hycu_dashboard_upload_cancel')} + + + + {isActivationPending && ( + + )} + + {t('hycu_dashboard_upload_confirm')} + +
    +
    +
    + ); +}; + +export default ActivationHycuLicenseModal; diff --git a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx index 1bbd3597b307..e4110a3891bb 100644 --- a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx +++ b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx @@ -134,7 +134,7 @@ export default function Listing() { setSorting, } = useResourcesIcebergV6({ route: '/license/hycu', - queryKey: ['hycu', '/license/hycu'], + queryKey: ['/license/hycu', 'list'], }); const columns = useMemo(() => { diff --git a/packages/manager/apps/hycu/src/routes/routes.constant.ts b/packages/manager/apps/hycu/src/routes/routes.constant.ts index b9d1adde65e0..7f6d7477fad1 100644 --- a/packages/manager/apps/hycu/src/routes/routes.constant.ts +++ b/packages/manager/apps/hycu/src/routes/routes.constant.ts @@ -10,4 +10,5 @@ export const urls = { onboarding: `/${subRoutes.onboarding}`, order: `/${subRoutes.order}`, dashboard: `/${subRoutes.serviceName}`, + activateLicense: `/${subRoutes.serviceName}/activate-license`, } as const; diff --git a/packages/manager/apps/hycu/src/routes/routes.tsx b/packages/manager/apps/hycu/src/routes/routes.tsx index cfb225296d1b..83e9d319e305 100644 --- a/packages/manager/apps/hycu/src/routes/routes.tsx +++ b/packages/manager/apps/hycu/src/routes/routes.tsx @@ -50,6 +50,17 @@ export const Routes: any = [ pageType: PageType.dashboard, }, }, + children: [ + { + id: 'activate-license', + path: urls.activateLicense, + ...lazyRouteConfig(() => + import( + '@/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page' + ), + ), + }, + ], }, ], }, diff --git a/packages/manager/apps/hycu/src/types/hycu.details.interface.ts b/packages/manager/apps/hycu/src/types/hycu.details.interface.ts index 64b1af7066ff..44c680ebd3a1 100644 --- a/packages/manager/apps/hycu/src/types/hycu.details.interface.ts +++ b/packages/manager/apps/hycu/src/types/hycu.details.interface.ts @@ -1,7 +1,7 @@ export enum LicenseStatus { ACTIVATED = 'activated', TO_ACTIVATE = 'toActivate', - PENDING = 'pending', + PENDING = 'processing', ERROR = 'error', } diff --git a/packages/manager/apps/hycu/src/utils/iam.constants.ts b/packages/manager/apps/hycu/src/utils/iam.constants.ts new file mode 100644 index 000000000000..78c95e6abea7 --- /dev/null +++ b/packages/manager/apps/hycu/src/utils/iam.constants.ts @@ -0,0 +1,3 @@ +export const IAM_ACTIONS = { + licenseHycuApiovhActivate: 'licenseHycu:apiovh:activate', +} as const; diff --git a/packages/manager/apps/hycu/src/utils/tests/renderTestApp.tsx b/packages/manager/apps/hycu/src/utils/tests/renderTestApp.tsx index 5888263eba74..14a0ccf4610e 100644 --- a/packages/manager/apps/hycu/src/utils/tests/renderTestApp.tsx +++ b/packages/manager/apps/hycu/src/utils/tests/renderTestApp.tsx @@ -12,7 +12,7 @@ import { GetServicesMocksParams, } from '@ovh-ux/manager-react-components'; import { TestApp } from './TestApp'; -import { getTesti18nParams, initTestI18n } from './init.i18n'; +import { initTestI18n } from './init.i18n'; import { toMswHandlers } from '../../../../../../../playwright-helpers'; import { getAuthenticationMocks } from '../../../../../../../playwright-helpers/mocks/auth'; import { @@ -23,6 +23,7 @@ import { getServiceLicenseHycuMocks, GetServiceLicenseHycuMocksParams, } from '@/mocks'; +import { getIamMocks } from '@/mocks/iam/iam.handler'; let context: ShellContextType; let i18nValue: i18n; @@ -38,6 +39,7 @@ export const renderTestApp = async ( global.server?.resetHandlers( ...toMswHandlers([ ...getAuthenticationMocks({ isAuthMocked: true }), + ...getIamMocks(), ...getLicenseHycuMocks(mockParams), ...getServiceLicenseHycuMocks(mockParams), ...getServicesMocks(mockParams), diff --git a/yarn.lock b/yarn.lock index aa77e2f0e5c2..621a0e38fb98 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24333,6 +24333,11 @@ react-hook-form@^7.52.1: resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.52.2.tgz#ff40f4776250b86ddfcde6be68d34aa82b1c60fe" integrity sha512-pqfPEbERnxxiNMPd0bzmt1tuaPcVccywFDpyk2uV5xCIBphHV5T8SVnX9/o3kplPE1zzKt77+YIoq+EMwJp56A== +react-hook-form@^7.53.1: + version "7.53.1" + resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.53.1.tgz#3f2cd1ed2b3af99416a4ac674da2d526625add67" + integrity sha512-6aiQeBda4zjcuaugWvim9WsGqisoUk+etmFEsSUMm451/Ic8L/UAb7sRtMj3V+Hdzm6mMjU1VhiSzYUZeBm0Vg== + react-i18next@^11.18.1, react-i18next@^11.18.6: version "11.18.6" resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.18.6.tgz#e159c2960c718c1314f1e8fcaa282d1c8b167887" From 6f123b28558bba24b85664ecb7b3310f9c0960c2 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Fri, 25 Oct 2024 08:33:56 +0200 Subject: [PATCH 16/43] feat(hycu): add regenerate license modal ref: MANAGER-15179 Signed-off-by: Thibault Barske --- .../hycu/dashboard/Messages_fr_FR.json | 12 +- .../FileUpload/FileUpload.component.tsx | 9 +- .../manager/apps/hycu/src/data/api/hycu.ts | 16 ++ .../apps/hycu/src/hooks/api/license.ts | 48 ++++- .../apps/hycu/src/mocks/iam/iam.mock.ts | 5 +- .../hycu/src/mocks/licenseHycu/licenseHycu.ts | 8 +- .../ShortcutsTile/ShortcutsTile.spec.tsx | 68 ++++++- .../ShortcutsTile/ShortcutsTile.tsx | 24 ++- .../RegenerateLicenseModal.page.spec.tsx | 191 ++++++++++++++++++ .../RegenerateLicenseModal.page.tsx | 127 ++++++++++++ .../apps/hycu/src/routes/routes.constant.ts | 1 + .../manager/apps/hycu/src/routes/routes.tsx | 9 + .../apps/hycu/src/utils/iam.constants.ts | 3 +- 13 files changed, 496 insertions(+), 25 deletions(-) create mode 100644 packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.spec.tsx create mode 100644 packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.tsx diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json index ccef3a134723..ddbb60163504 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json @@ -7,7 +7,7 @@ "hycu_dashboard_label_license_key": "Clé de licence", "hycu_dashboard_shortcuts_title": "Raccourcis", "hycu_dashboard_link_activate": "Activer la licence", - "hycu_dashboard_link_reactivate": "Regénérer la licence", + "hycu_dashboard_link_regenerate": "Regénérer la licence", "hycu_dashboard_link_terminated": "Résilier la licence", "hycu_dashboard_link_change_pack_type": "Modifier le type de pack", "hycu_dashboard_field_label_contacts": "Contacts", @@ -19,19 +19,23 @@ "hycu_dashboard_label_renew": "Renouvellement automatique", "hycu_dashboard_subscription_title": "Abonnement", "hycu_dashboard_field_label_date_creation": "Date de création", - "hycu_dashboard_download_license_file": "Télécharger la license", + "hycu_dashboard_download_license_file": "Télécharger la licence", "hycu_dashboard_back_link": "Retour à la liste", "hycu_dashboard_wait_for_activation": "En attente d'activation", "hycu_dashboard_license_activate_heading": "Activer la licence", "hycu_dashboard_license_activate_description": "Veuillez transférer votre fichier de demande de licence. Ce fichier est à télécharger depuis votre controller HYCU une fois votre installation réalisée", "hycu_dashboard_license_more_information_link": "(plus de détails ici)", "hycu_dashboard_activation_license_success_message": "La demande d'activation de votre licence a bien été prise en compte. Votre fichier de licence sera bientôt disponible sur cette interface et vous sera également envoyé par e-mail.", - "hycu_dashboard_activation_license_error_message": "Une erreur est survenue lors de la soumission de votre license.", + "hycu_dashboard_activation_license_error_message": "Une erreur est survenue lors de la soumission de votre licence.", + "hycu_dashboard_regenerate_error_message": "Une erreur est survenue lors de la soumission de votre licence.", + "hycu_dashboard_license_regenerate_heading": "Regénérer la licence", + "hycu_dashboard_license_regenerate_description": "Si votre environnement technique HYCU a changé, il est nécessaire de soumettre une nouvelle demande afin d'obtenir un nouveau fichier de licence compatible avec votre controller HYCU. Veuillez transférer votre nouveau fichier de demande de licence. En réalisant cette action, vous vous engagez également à ne plus utiliser le fichier de licence précédemment fourni.", "hycu_dashboard_license_upload": "Upload", + "hycu_dashboard_regenerate_upload_confirm": "Regénérer", "hycu_dashboard_upload_cancel": "Annuler", "hycu_dashboard_upload_confirm": "Activer", "hycu_dashboard_upload_valid_file": "Merci de sélectionner un fichier valide", - "hycu_dashboard_upload_license_required": "Veuillez sélectionner une license", + "hycu_dashboard_upload_license_required": "Veuillez sélectionner une licence", "hycu_dashboard_drag_and_drop_attachment": "Glissez-Déposer une pièce jointe", "hycu_dashboard_accepted_formats": "Format accepté: .dat", "hycu_dashboard_browse": "Parcourir" diff --git a/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx b/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx index 5c4c828f2b29..f3e8c0177147 100644 --- a/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx +++ b/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx @@ -103,7 +103,7 @@ export const FileInputField = ({ size={ODS_ICON_SIZE.lg} >
    {t('hycu_dashboard_drag_and_drop_attachment')} @@ -119,6 +119,13 @@ export const FileInputField = ({ onClick={() => fileInputRef.current.click()} inline > + + + {t('hycu_dashboard_browse')} diff --git a/packages/manager/apps/hycu/src/data/api/hycu.ts b/packages/manager/apps/hycu/src/data/api/hycu.ts index f181d9bf9c0a..fd35524f7363 100644 --- a/packages/manager/apps/hycu/src/data/api/hycu.ts +++ b/packages/manager/apps/hycu/src/data/api/hycu.ts @@ -17,6 +17,10 @@ export const postActivateLicenseHycuMutationKey = () => [ 'license/hycu/activate', 'post', ]; +export const postRegenerateLicenseHycuMutationKey = () => [ + 'license/hycu/refresh', + 'post', +]; /** * Manage HYCU licenses : Get list of owned HYCU licenses @@ -44,6 +48,8 @@ export type PostLicenseHycuActivateServiceParams = { licenseContent: string; }; +export type PostLicenseHycuRegenerateServiceParams = PostLicenseHycuActivateServiceParams; + /** * Activate HYCU licenses : Post HYCU license content */ @@ -54,6 +60,16 @@ export const postLicenseHycuActivateService = ( licenseRequest: params.licenseContent, }); +/** + * Regenerate HYCU licenses : Post HYCU license content + */ +export const postLicenseHycuRegenerateService = ( + params: PostLicenseHycuRegenerateServiceParams, +): Promise => + apiClient.v6.post(`/license/hycu/${params.serviceName}/refresh`, { + licenseRequest: params.licenseContent, + }); + /** * Get listing with iceberg V6 */ diff --git a/packages/manager/apps/hycu/src/hooks/api/license.ts b/packages/manager/apps/hycu/src/hooks/api/license.ts index 6d95c0f146f0..dc53680d3dee 100644 --- a/packages/manager/apps/hycu/src/hooks/api/license.ts +++ b/packages/manager/apps/hycu/src/hooks/api/license.ts @@ -14,6 +14,8 @@ import { postActivateLicenseHycuMutationKey, postLicenseHycuActivateService, PostLicenseHycuActivateServiceParams, + postLicenseHycuRegenerateService, + postRegenerateLicenseHycuMutationKey, } from '@/data/api/hycu'; import { IHycuDetails } from '@/types/hycu.details.interface'; @@ -28,6 +30,20 @@ export const useDetailsLicenseHYCU = ( }); }; +export const useInvalidateCacheForALicenseHycu = () => { + const queryClient = useQueryClient(); + + return (serviceName: string) => { + queryClient.invalidateQueries({ queryKey: getLicenseHycuListQueryKey() }); + queryClient.invalidateQueries({ + queryKey: getServiceDetailsQueryKey(serviceName), + }); + queryClient.invalidateQueries({ + queryKey: getLicenseHycuQueryKey(serviceName), + }); + }; +}; + export const useActivateLicenseHYCUMutation = ( options: Partial< UseMutationOptions< @@ -37,7 +53,7 @@ export const useActivateLicenseHYCUMutation = ( > > = {}, ) => { - const queryClient = useQueryClient(); + const invalidateCacheForService = useInvalidateCacheForALicenseHycu(); const { onSuccess, ...restOptions } = options; @@ -45,14 +61,30 @@ export const useActivateLicenseHYCUMutation = ( mutationKey: postActivateLicenseHycuMutationKey(), mutationFn: (params) => postLicenseHycuActivateService(params), onSuccess: (data, variables, context) => { - queryClient.invalidateQueries({ queryKey: getLicenseHycuListQueryKey() }); - queryClient.invalidateQueries({ - queryKey: getServiceDetailsQueryKey(variables.serviceName), - }); - queryClient.invalidateQueries({ - queryKey: getLicenseHycuQueryKey(variables.serviceName), - }); + invalidateCacheForService(variables.serviceName); + onSuccess?.(data, variables, context); + }, + ...(restOptions ?? {}), + }); +}; + +export const useRegenerateLicenseHYCUMutation = ( + options: Partial< + UseMutationOptions< + AxiosResponse, + Error, + PostLicenseHycuActivateServiceParams + > + > = {}, +) => { + const invalidateCacheForService = useInvalidateCacheForALicenseHycu(); + const { onSuccess, ...restOptions } = options; + return useMutation({ + mutationKey: postRegenerateLicenseHycuMutationKey(), + mutationFn: (params) => postLicenseHycuRegenerateService(params), + onSuccess: (data, variables, context) => { + invalidateCacheForService(variables.serviceName); onSuccess?.(data, variables, context); }, ...(restOptions ?? {}), diff --git a/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts b/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts index 4a01a599cf13..308ab639d3ee 100644 --- a/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts +++ b/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts @@ -5,7 +5,10 @@ import { IAM_ACTIONS } from '@/utils/iam.constants'; export const resourceList: IamCheckResponse[] = [ { urn: licensesHycu[0].iam.urn, - authorizedActions: [IAM_ACTIONS.licenseHycuApiovhActivate], + authorizedActions: [ + IAM_ACTIONS.licenseHycuApiOvhActivate, + IAM_ACTIONS.licenseHycuApiOvhRefresh, + ], unauthorizedActions: [], }, { diff --git a/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts b/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts index db57ffa1c9db..5c9a9bc707bd 100644 --- a/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts +++ b/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts @@ -48,7 +48,6 @@ export const getLicenseHycuMocks = ({ status: isGetLicenseHycuKo ? 500 : 200, api: 'v6', }, - { url: 'license/hycu/:serviceName/activate', response: null, @@ -56,5 +55,12 @@ export const getLicenseHycuMocks = ({ status: isPostLicenseHycuKo ? 500 : 200, api: 'v6', }, + { + url: 'license/hycu/:serviceName/refresh', + response: null, + method: 'post', + status: isPostLicenseHycuKo ? 500 : 200, + api: 'v6', + }, ]; }; diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx index 2272f54074b2..0364df135033 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx @@ -52,7 +52,7 @@ describe('License Hycu shortcuts tile for dashboard test suite', () => { await waitFor( () => expect( - screen.getByText(labels.dashboard.hycu_dashboard_link_reactivate), + screen.getByText(labels.dashboard.hycu_dashboard_link_regenerate), ).toBeVisible(), { timeout: 20_000 }, ); @@ -85,7 +85,7 @@ describe('License Hycu shortcuts tile for dashboard test suite', () => { await waitFor( () => expect( - screen.getByText(labels.dashboard.hycu_dashboard_link_reactivate), + screen.getByText(labels.dashboard.hycu_dashboard_link_regenerate), ).toBeVisible(), { timeout: 20_000 }, ); @@ -129,7 +129,7 @@ describe('License Hycu shortcuts tile for dashboard test suite', () => { ); }); - it('Can open activate modal without IAM authorization', async () => { + it("Can't open activate modal without IAM authorization", async () => { const user = userEvent.setup(); await renderTestApp(`/${licensesHycu[1].serviceName}`, { licenseStatus: LicenseStatus.TO_ACTIVATE, @@ -141,7 +141,9 @@ describe('License Hycu shortcuts tile for dashboard test suite', () => { { timeout: 30_000 }, ); - await user.click(screen.getByTestId('hycu_link_activated_test_id')); + await act(() => + user.click(screen.getByTestId('hycu_link_activated_test_id')), + ); await waitFor( () => @@ -153,4 +155,62 @@ describe('License Hycu shortcuts tile for dashboard test suite', () => { { timeout: 20_000 }, ); }); + + it('Can open regenerate modal with IAM authorization', async () => { + const user = userEvent.setup(); + await renderTestApp(`/${licensesHycu[0].serviceName}`, { + licenseStatus: LicenseStatus.ACTIVATED, + }); + + await waitFor( + () => { + expect( + screen.getByTestId('hycu_link_regenerate_test_id'), + ).not.toHaveAttribute('disabled'); + }, + { timeout: 30_000 }, + ); + await act(() => + user.click(screen.getByTestId('hycu_link_regenerate_test_id')), + ); + + await waitFor( + () => + expect( + screen.getByText( + labels.dashboard.hycu_dashboard_license_regenerate_description, + ), + ).toBeVisible(), + { timeout: 20_000 }, + ); + }); + + it("Can't open regenerate modal without IAM authorization", async () => { + const user = userEvent.setup(); + await renderTestApp(`/${licensesHycu[1].serviceName}`, { + licenseStatus: LicenseStatus.ACTIVATED, + }); + + await waitFor( + () => + expect( + screen.getByTestId('hycu_link_regenerate_test_id'), + ).toBeVisible(), + { timeout: 30_000 }, + ); + + await act(() => + user.click(screen.getByTestId('hycu_link_regenerate_test_id')), + ); + + await waitFor( + () => + expect( + screen.queryByText( + labels.dashboard.hycu_dashboard_license_regenerate_description, + ), + ).not.toBeInTheDocument(), + { timeout: 20_000 }, + ); + }); }); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx index 98862049e059..78f4a5333b84 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx @@ -1,4 +1,4 @@ -import { OsdsLink, OsdsIcon } from '@ovhcloud/ods-components/react'; +import { OsdsIcon } from '@ovhcloud/ods-components/react'; import { DashboardTile } from '@ovh-ux/manager-react-components'; import React from 'react'; @@ -37,7 +37,7 @@ const ShortcutsTile = ({ serviceName }: { serviceName: string }) => { id: 'link_activated', value: ( { @@ -51,9 +51,23 @@ const ShortcutsTile = ({ serviceName }: { serviceName: string }) => { ), }, linkReactivated: { - id: 'link_reactivated', + id: 'link_regenerate', value: ( - {t('hycu_dashboard_link_reactivate')} + { + navigate( + urls.regenerateLicense.replace( + subRoutes.serviceName, + serviceName, + ), + ); + }} + > + {t('hycu_dashboard_link_regenerate')} + ), }, linkChangePackType: { @@ -70,7 +84,7 @@ const ShortcutsTile = ({ serviceName }: { serviceName: string }) => { { + // Create a Blob with the desired content + const content = 'Hello, this is hycu license! Yes trust me !'; + const blob = new Blob([content], { type: 'text/plain' }); + + // Convert the Blob to a File object + return new File([blob], 'license.dat', { + type: 'text/plain', + lastModified: Date.now(), + }); +}; + +describe('License Hycu regenerate license route test suite', () => { + beforeEach(() => { + vi.restoreAllMocks(); + }); + + it('should show modal title', async () => { + await renderTestApp(`/${licensesHycu[0].serviceName}/regenerate-license`); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_license_regenerate_description, + )[0], + ).toBeVisible(), + { timeout: 30_000 }, + ); + + expect( + screen.getByTestId('hycu-dashboard-regenerate-upload-confirm'), + ).toBeVisible(); + + expect(screen.queryByAltText('OOPS')).not.toBeInTheDocument(); + }); + + it('should show error if api services fail', async () => { + await renderTestApp(`/${licensesHycu[0].serviceName}/regenerate-license`, { + getServicesKo: true, + isGetLicenseHycuKo: true, + isGetServiceLicenseHycuKo: true, + }); + + await waitFor(() => expect(screen.getByAltText('OOPS')).toBeVisible(), { + timeout: 30_000, + }); + }); + + it('should not call mutate when form is empty', async () => { + const user = userEvent.setup(); + await renderTestApp(`/${licensesHycu[0].serviceName}/regenerate-license`); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_license_regenerate_description, + )[0], + ).toBeVisible(), + { timeout: 30_000 }, + ); + + const submitButton = screen.getByTestId( + 'hycu-dashboard-regenerate-upload-confirm', + ); + await act(() => user.click(submitButton)); + + expect( + screen.getByText(labels.dashboard.hycu_dashboard_upload_license_required), + ).toBeVisible(); + }); + + it('should call mutate when form valid and submitted', async () => { + const user = userEvent.setup(); + await renderTestApp(`/${licensesHycu[0].serviceName}/regenerate-license`); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_license_regenerate_description, + )[0], + ).toBeVisible(), + { timeout: 30_000 }, + ); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_regenerate_upload_confirm, + )[0], + ).toBeVisible(), + { timeout: 10_000 }, + ); + + const submitButton = screen.getByText( + labels.dashboard.hycu_dashboard_regenerate_upload_confirm, + ); + + await act(() => + user.upload(screen.getByTestId('license-file-input'), createFakeFile()), + ); + + await act(() => user.click(submitButton)); + + expect( + screen.queryByText( + labels.dashboard.hycu_dashboard_upload_license_required, + ), + ).not.toBeInTheDocument(); + + await waitFor( + () => + expect( + screen.queryByText( + labels.dashboard.hycu_dashboard_license_regenerate_description, + ), + ).not.toBeInTheDocument(), + { timeout: 10_000 }, + ); + }); + + it('should show a error if server fail', async () => { + const user = userEvent.setup(); + await renderTestApp(`/${licensesHycu[0].serviceName}/regenerate-license`, { + isPostLicenseHycuKo: true, + }); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_license_regenerate_description, + )[0], + ).toBeVisible(), + { timeout: 30_000 }, + ); + + await waitFor( + () => + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_regenerate_upload_confirm, + )[0], + ).toBeVisible(), + { timeout: 10_000 }, + ); + + const submitButton = screen.getByText( + labels.dashboard.hycu_dashboard_regenerate_upload_confirm, + ); + + await act(() => + user.upload(screen.getByTestId('license-file-input'), createFakeFile()), + ); + + await act(() => user.click(submitButton)); + + expect( + screen.queryByText( + labels.dashboard.hycu_dashboard_upload_license_required, + ), + ).not.toBeInTheDocument(); + + await waitFor( + () => { + expect( + screen.queryByText( + labels.dashboard.hycu_dashboard_license_regenerate_description, + ), + ).toBeVisible(); + expect( + screen.queryAllByText( + labels.dashboard.hycu_dashboard_regenerate_error_message, + )[1], + ).toBeVisible(); + }, + { timeout: 10_000 }, + ); + }); +}); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.tsx new file mode 100644 index 000000000000..5a549d630cd1 --- /dev/null +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.tsx @@ -0,0 +1,127 @@ +import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import { + ODS_BUTTON_TYPE, + ODS_BUTTON_VARIANT, + ODS_SPINNER_SIZE, + ODS_TEXT_LEVEL, +} from '@ovhcloud/ods-components'; +import { + OsdsButton, + OsdsModal, + OsdsSpinner, + OsdsText, +} from '@ovhcloud/ods-components/react'; +import { SubmitHandler, useForm } from 'react-hook-form'; +import { useNavigate, useParams } from 'react-router-dom'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { + Notifications, + useNotifications, +} from '@ovh-ux/manager-react-components'; +import { FileInputField } from '@/components/FileUpload/FileUpload.component'; +import { useRegenerateLicenseHYCUMutation } from '@/hooks/api/license'; + +export type RegenerateHycuLicenseModalProps = { + closeModal: () => void; + isLoading?: boolean; + onConfirmRegenerateHycuLicense: () => void; +}; + +interface FormValues { + license?: string; +} + +export const RegenerateHycuLicenseModal: React.FC = () => { + const { serviceName } = useParams(); + const { t } = useTranslation('hycu/dashboard'); + const navigate = useNavigate(); + const closeModal = () => navigate('..'); + const { addSuccess, addError } = useNotifications(); + const { + control, + handleSubmit, + formState: { isValid, isSubmitted }, + } = useForm(); + const { + mutate, + isPending: isRegeneratePending, + } = useRegenerateLicenseHYCUMutation({ + onSuccess: () => { + addSuccess(t('hycu_dashboard_regenerate_success_message'), true); + closeModal(); + }, + onError: () => { + addError(t('hycu_dashboard_regenerate_error_message')); + }, + }); + const onSubmit: SubmitHandler = (data) => { + if (isValid) { + mutate({ serviceName, licenseContent: data.license }); + } + }; + + return ( + + +
    +
    + <> + + {t('hycu_dashboard_license_regenerate_description')} + + + +
    +
    + + {t('hycu_dashboard_upload_cancel')} + + + + {isRegeneratePending && ( + + )} + + {t('hycu_dashboard_regenerate_upload_confirm')} + +
    +
    +
    + ); +}; + +export default RegenerateHycuLicenseModal; diff --git a/packages/manager/apps/hycu/src/routes/routes.constant.ts b/packages/manager/apps/hycu/src/routes/routes.constant.ts index 7f6d7477fad1..4907b60abecf 100644 --- a/packages/manager/apps/hycu/src/routes/routes.constant.ts +++ b/packages/manager/apps/hycu/src/routes/routes.constant.ts @@ -11,4 +11,5 @@ export const urls = { order: `/${subRoutes.order}`, dashboard: `/${subRoutes.serviceName}`, activateLicense: `/${subRoutes.serviceName}/activate-license`, + regenerateLicense: `/${subRoutes.serviceName}/regenerate-license`, } as const; diff --git a/packages/manager/apps/hycu/src/routes/routes.tsx b/packages/manager/apps/hycu/src/routes/routes.tsx index 83e9d319e305..e293a5899c16 100644 --- a/packages/manager/apps/hycu/src/routes/routes.tsx +++ b/packages/manager/apps/hycu/src/routes/routes.tsx @@ -60,6 +60,15 @@ export const Routes: any = [ ), ), }, + { + id: 'regenerate-license', + path: urls.regenerateLicense, + ...lazyRouteConfig(() => + import( + '@/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page' + ), + ), + }, ], }, ], diff --git a/packages/manager/apps/hycu/src/utils/iam.constants.ts b/packages/manager/apps/hycu/src/utils/iam.constants.ts index 78c95e6abea7..a962feaad167 100644 --- a/packages/manager/apps/hycu/src/utils/iam.constants.ts +++ b/packages/manager/apps/hycu/src/utils/iam.constants.ts @@ -1,3 +1,4 @@ export const IAM_ACTIONS = { - licenseHycuApiovhActivate: 'licenseHycu:apiovh:activate', + licenseHycuApiOvhActivate: 'licenseHycu:apiovh:activate', + licenseHycuApiOvhRefresh: 'licenseHycu:apiovh:refresh', } as const; From dfecf5a6f404676ae618e1220cd9f44a1f79afb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ars=C3=A8ne?= Date: Mon, 28 Oct 2024 17:52:15 +0100 Subject: [PATCH 17/43] feat(hycu): add agora termination for hycu service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ref: MANAGER-14762 Signed-off-by: David Arsène --- .../billing-confirmTerminate.service.js | 14 ++++++--- .../confirm-terminate.constants.js | 5 ++-- .../confirmTerminate/termination.routing.js | 29 ++++++++++++------- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/packages/manager/modules/billing-components/src/components/cancellation-form/billing-confirmTerminate.service.js b/packages/manager/modules/billing-components/src/components/cancellation-form/billing-confirmTerminate.service.js index b3542a9a5312..364301571359 100644 --- a/packages/manager/modules/billing-components/src/components/cancellation-form/billing-confirmTerminate.service.js +++ b/packages/manager/modules/billing-components/src/components/cancellation-form/billing-confirmTerminate.service.js @@ -1,6 +1,7 @@ import { map } from 'lodash-es'; import { Service } from '@ovh-ux/manager-models'; import { + SERVICE_GROUP_WITH_AGORA_TERMINATION_REGEX, SERVICE_WITH_AGORA_TERMINATION, TERMINATION_FORM_NAME, } from './confirm-terminate.constants'; @@ -34,11 +35,16 @@ export default class BillingTerminate { ); } - confirmTermination(service, token) { - const isAgoraService = SERVICE_WITH_AGORA_TERMINATION.includes( - service.billing?.plan?.code || '', + static hasAgoraTermination(planCode) { + return ( + SERVICE_WITH_AGORA_TERMINATION.includes(planCode) || + SERVICE_GROUP_WITH_AGORA_TERMINATION_REGEX.test(planCode) ); - return isAgoraService + } + + confirmTermination(service, token) { + const planCode = service.billing?.plan?.code || ''; + return BillingTerminate.hasAgoraTermination(planCode) ? this.$http.post(`/services/${service.serviceId}/terminate/confirm`, { token, }) diff --git a/packages/manager/modules/billing-components/src/components/cancellation-form/confirm-terminate.constants.js b/packages/manager/modules/billing-components/src/components/cancellation-form/confirm-terminate.constants.js index fc973d395857..2cc47f58282a 100644 --- a/packages/manager/modules/billing-components/src/components/cancellation-form/confirm-terminate.constants.js +++ b/packages/manager/modules/billing-components/src/components/cancellation-form/confirm-terminate.constants.js @@ -6,12 +6,13 @@ export const SERVICE_WITH_AGORA_TERMINATION = [ 'vrack-services', 'okms', 'logs-account', - 'logs-enterprise', - 'logs-enterprise-hds', ]; +export const SERVICE_GROUP_WITH_AGORA_TERMINATION_REGEX = /hycu-vms-*|(logs-enterprise(-hds)?$)/; + export default { SPECIAL_CONDITIONS_SUBSIDIARIES, TERMINATION_FORM_NAME, SERVICE_WITH_AGORA_TERMINATION, + SERVICE_GROUP_WITH_AGORA_TERMINATION_REGEX, }; diff --git a/packages/manager/modules/billing/src/confirmTerminate/termination.routing.js b/packages/manager/modules/billing/src/confirmTerminate/termination.routing.js index 8c63794a958c..0030531e19b4 100644 --- a/packages/manager/modules/billing/src/confirmTerminate/termination.routing.js +++ b/packages/manager/modules/billing/src/confirmTerminate/termination.routing.js @@ -1,4 +1,3 @@ -import { SERVICE_WITH_AGORA_TERMINATION } from '../../../billing-components/src/components/cancellation-form/confirm-terminate.constants'; import controller from './legacy/termination-legacy.controller'; import template from './legacy/termination-legacy.html'; @@ -12,17 +11,21 @@ export default /* @ngInject */ ($stateProvider, coreConfigProvider) => { translations: { value: ['./legacy', '../autoRenew'], format: 'json' }, redirectTo: (transition) => { const injector = transition.injector(); - return injector.getAsync('planCode').then((planCode) => { - return SERVICE_WITH_AGORA_TERMINATION.includes(planCode) - ? 'app.account.billing.confirmTerminateAgora' - : false; - }); + return injector + .getAsync('hasAgoraTermination') + .then((hasAgoraTermination) => { + return hasAgoraTermination + ? 'app.account.billing.confirmTerminateAgora' + : false; + }); }, resolve: { planCode: /* @ngInject */ (BillingTerminate, $transition$) => BillingTerminate.getServiceApi($transition$.params().id).then( (service) => service.billing.plan.code, ), + hasAgoraTermination: /* @ngInject */ (BillingTerminate, planCode) => + BillingTerminate.constructor.hasAgoraTermination(planCode), hideBreadcrumb: () => true, }, }); @@ -33,11 +36,13 @@ export default /* @ngInject */ ($stateProvider, coreConfigProvider) => { component: 'billingConfirmTermination', redirectTo: (transition) => { const injector = transition.injector(); - return injector.getAsync('planCode').then((planCode) => { - return !SERVICE_WITH_AGORA_TERMINATION.includes(planCode) - ? 'app.account.billing.confirmTerminate' - : false; - }); + return injector + .getAsync('hasAgoraTermination') + .then((hasAgoraTermination) => { + return !hasAgoraTermination + ? 'app.account.billing.confirmTerminate' + : false; + }); }, resolve: { confirmTermination: /* @ngInject */ ( @@ -55,6 +60,8 @@ export default /* @ngInject */ ($stateProvider, coreConfigProvider) => { serviceId: /* @ngInject */ ($transition$) => $transition$.params().id, token: /* @ngInject */ ($transition$) => $transition$.params().token, user: /* @ngInject */ (currentUser) => currentUser, + hasAgoraTermination: /* @ngInject */ (BillingTerminate, planCode) => + BillingTerminate.constructor.hasAgoraTermination(planCode), hideBreadcrumb: () => true, }, }); From 6dfab9db3974f656ef12bc1cab9edf05754fc5db Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Mon, 28 Oct 2024 09:59:14 +0100 Subject: [PATCH 18/43] feat(hycu): add rename modal ref: MANAGER-14717 Signed-off-by: Thibault Barske --- .../hycu/dashboard/Messages_fr_FR.json | 13 ++++- .../FileUpload/FileUpload.component.tsx | 2 +- .../GeneralInformationsTile.tsx | 7 +++ .../edit/EditHycu.page.tsx | 58 +++++++++++++++++++ .../edit/EditHycu.spec.tsx | 41 +++++++++++++ .../apps/hycu/src/routes/routes.constant.ts | 1 + .../manager/apps/hycu/src/routes/routes.tsx | 9 +++ .../apps/hycu/src/utils/iam.constants.ts | 2 + 8 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 packages/manager/apps/hycu/src/pages/dashboard/general-information/edit/EditHycu.page.tsx create mode 100644 packages/manager/apps/hycu/src/pages/dashboard/general-information/edit/EditHycu.spec.tsx diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json index ddbb60163504..8863e0007465 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json @@ -38,5 +38,16 @@ "hycu_dashboard_upload_license_required": "Veuillez sélectionner une licence", "hycu_dashboard_drag_and_drop_attachment": "Glissez-Déposer une pièce jointe", "hycu_dashboard_accepted_formats": "Format accepté: .dat", - "hycu_dashboard_browse": "Parcourir" + "hycu_dashboard_browse": "Parcourir", + "hycu_dashboard_update_display_name_modal_headline": "Renommer la licence : {{serviceName}}", + "hycu_dashboard_update_display_name_input_label": "Nom", + "hycu_dashboard_update_display_name_description": "", + "hycu_dashboard_update_display_name_pattern_message": "Veuillez saisir un nom dont la longueur est comprise entre 1 et 32 caractères.", + "hycu_dashboard_update_display_name_success": "La description a été modifiée avec succès.", + "hycu_dashboard_edit_modal_error": "Une erreur est survenue: {{error}}.", + "hycu_dashboard_terminate_headline": "", + "hycu_dashboard_terminate_description": "", + "hycu_dashboard_terminate_input_label": "", + "hycu_dashboard_cancel_label": "", + "hycu_dashboard_confirm_label": "" } diff --git a/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx b/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx index f3e8c0177147..a16ecd78b749 100644 --- a/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx +++ b/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx @@ -122,7 +122,7 @@ export const FileInputField = ({ diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx index ee0abae27a6d..d051b3c58bce 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx @@ -22,6 +22,7 @@ import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; import React from 'react'; import { useTranslation } from 'react-i18next'; +import { useNavigate } from 'react-router-dom'; import { getStatusColor } from '@/utils/statusColor'; import { useDetailsLicenseHYCU } from '@/hooks/api/license'; import { LicenseStatus } from '@/types/hycu.details.interface'; @@ -65,10 +66,13 @@ const ControllerIdHycuLicense = ({ serviceName }: { serviceName: string }) => { const GeneralInformationsTile = ({ serviceName }: { serviceName: string }) => { const { t: tCommon } = useTranslation('hycu'); const { t } = useTranslation('hycu/dashboard'); + const navigate = useNavigate(); const { data: hycuDetail } = useDetailsLicenseHYCU(serviceName); const { data: serviceDetails, isLoading } = useServiceDetails({ resourceName: serviceName, }); + const openEditNameModal = () => + navigate(urls.editName.replace(subRoutes.serviceName, serviceName)); return ( { { + navigate('..'); + }; + + return ( + { + navigate('..'); + addSuccess( + t('hycu_dashboard_update_display_name_success', { + serviceName, + }), + ); + setTimeout(() => { + invalidateCacheForLicense(serviceName); + }, 2000); + }} + onError={(requestError: AxiosError) => { + addError( + t('hycu_dashboard_edit_modal_error', { error: requestError.message }), + ); + }} + defaultValue={serviceDetails?.data?.resource?.displayName} + /> + ); +} diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit/EditHycu.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit/EditHycu.spec.tsx new file mode 100644 index 000000000000..0f967aead0d8 --- /dev/null +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit/EditHycu.spec.tsx @@ -0,0 +1,41 @@ +import '@testing-library/jest-dom'; +import { act, screen, waitFor } from '@testing-library/react'; +import { userEvent } from '@testing-library/user-event'; +import { renderTestApp } from '@/utils/tests/renderTestApp'; +import { labels } from '@/utils/tests/init.i18n'; +import { LicenseStatus } from '@/types/hycu.details.interface'; +import { licensesHycu } from '@/mocks/licenseHycu/licenseHycu.data'; + +describe('License Hycu edit name modal test suite', () => { + it('Can open regenerate modal with IAM authorization', async () => { + const user = userEvent.setup(); + await renderTestApp(`/${licensesHycu[0].serviceName}`, { + licenseStatus: LicenseStatus.ACTIVATED, + }); + + await waitFor( + () => { + expect( + screen.getByTestId('edit-hycu-displayname-action'), + ).toBeVisible(); + expect( + screen.getByTestId('edit-hycu-displayname-action'), + ).not.toHaveAttribute('disabled'); + }, + { timeout: 30_000 }, + ); + await act(() => + user.click(screen.getByTestId('edit-hycu-displayname-action')), + ); + + await waitFor( + () => + expect( + screen.queryAllByText( + labels.dashboard.hycu_dashboard_update_display_name_pattern_message, + )[0], + ).toBeVisible(), + { timeout: 20_000 }, + ); + }); +}); diff --git a/packages/manager/apps/hycu/src/routes/routes.constant.ts b/packages/manager/apps/hycu/src/routes/routes.constant.ts index 4907b60abecf..a58039b86642 100644 --- a/packages/manager/apps/hycu/src/routes/routes.constant.ts +++ b/packages/manager/apps/hycu/src/routes/routes.constant.ts @@ -12,4 +12,5 @@ export const urls = { dashboard: `/${subRoutes.serviceName}`, activateLicense: `/${subRoutes.serviceName}/activate-license`, regenerateLicense: `/${subRoutes.serviceName}/regenerate-license`, + editName: `/${subRoutes.serviceName}/edit-name`, } as const; diff --git a/packages/manager/apps/hycu/src/routes/routes.tsx b/packages/manager/apps/hycu/src/routes/routes.tsx index e293a5899c16..365f964f269e 100644 --- a/packages/manager/apps/hycu/src/routes/routes.tsx +++ b/packages/manager/apps/hycu/src/routes/routes.tsx @@ -69,6 +69,15 @@ export const Routes: any = [ ), ), }, + { + id: 'edit-name', + path: urls.editName, + ...lazyRouteConfig(() => + import( + '@/pages/dashboard/general-information/edit/EditHycu.page' + ), + ), + }, ], }, ], diff --git a/packages/manager/apps/hycu/src/utils/iam.constants.ts b/packages/manager/apps/hycu/src/utils/iam.constants.ts index a962feaad167..61967c855ebb 100644 --- a/packages/manager/apps/hycu/src/utils/iam.constants.ts +++ b/packages/manager/apps/hycu/src/utils/iam.constants.ts @@ -1,4 +1,6 @@ export const IAM_ACTIONS = { licenseHycuApiOvhActivate: 'licenseHycu:apiovh:activate', licenseHycuApiOvhRefresh: 'licenseHycu:apiovh:refresh', + licenseHycuApiOvhServiceEdit: 'account:apiovh:service/edit', + licenseHycuApiOvhTerminate: 'account:apiovh:services/terminate', } as const; From b2a3ba31b933a7c4c6db0c46474be98cd4f67e7e Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Mon, 28 Oct 2024 17:44:41 +0100 Subject: [PATCH 19/43] feat(hycu): add terminate modal page ref: MANAGER-14717 Signed-off-by: Thibault Barske --- .../dashboard/Messages_de_DE.json | 7 -- .../dashboard/Messages_en_GB.json | 7 -- .../dashboard/Messages_es_ES.json | 7 -- .../dashboard/Messages_fr_CA.json | 7 -- .../dashboard/Messages_it_IT.json | 7 -- .../dashboard/Messages_pl_PL.json | 7 -- .../dashboard/Messages_pt_PT.json | 7 -- .../translations/hycu/Messages_fr_FR.json | 2 +- .../hycu/dashboard/Messages_fr_FR.json | 11 +-- .../hycu/terminate/Messages_fr_FR.json | 9 ++ .../ManagerLink/ManagerLink.component.tsx | 2 +- .../apps/hycu/src/mocks/iam/iam.mock.ts | 1 + .../pages/dashboard/Dashboard.page.spec.tsx | 7 +- .../BillingInformationsTile.spec.tsx | 78 ++++++++++++++- .../BillingInformationsTile.tsx | 27 ++++-- .../DashboardGeneralInformation.page.tsx | 2 +- .../GeneralInformationsTile.spec.tsx | 7 +- .../ActivationLicenseModal.page.spec.tsx | 5 +- .../ActivationLicenseModal.page.tsx | 9 +- .../EditHycuDisplayName.page.tsx} | 2 +- .../EditHycuDisplayName.spec.tsx} | 0 .../hycu/src/pages/listing/Listing.page.tsx | 97 +++++++++++-------- .../hycu/src/pages/listing/Listing.spec.tsx | 81 +++++++++++++++- .../listing/menu/HycuActionMenu.component.tsx | 16 ++- .../src/pages/terminate/terminate-hycu.tsx | 46 +++++++++ .../apps/hycu/src/routes/routes.constant.ts | 2 + .../manager/apps/hycu/src/routes/routes.tsx | 18 +++- .../apps/hycu/src/utils/tests/init.i18n.ts | 3 + 28 files changed, 344 insertions(+), 130 deletions(-) delete mode 100644 packages/manager/apps/hycu/public/translations/dashboard/Messages_de_DE.json delete mode 100644 packages/manager/apps/hycu/public/translations/dashboard/Messages_en_GB.json delete mode 100644 packages/manager/apps/hycu/public/translations/dashboard/Messages_es_ES.json delete mode 100644 packages/manager/apps/hycu/public/translations/dashboard/Messages_fr_CA.json delete mode 100644 packages/manager/apps/hycu/public/translations/dashboard/Messages_it_IT.json delete mode 100644 packages/manager/apps/hycu/public/translations/dashboard/Messages_pl_PL.json delete mode 100644 packages/manager/apps/hycu/public/translations/dashboard/Messages_pt_PT.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_fr_FR.json rename packages/manager/apps/hycu/src/pages/dashboard/general-information/{edit/EditHycu.page.tsx => edit-display-name/EditHycuDisplayName.page.tsx} (96%) rename packages/manager/apps/hycu/src/pages/dashboard/general-information/{edit/EditHycu.spec.tsx => edit-display-name/EditHycuDisplayName.spec.tsx} (100%) create mode 100644 packages/manager/apps/hycu/src/pages/terminate/terminate-hycu.tsx diff --git a/packages/manager/apps/hycu/public/translations/dashboard/Messages_de_DE.json b/packages/manager/apps/hycu/public/translations/dashboard/Messages_de_DE.json deleted file mode 100644 index dc81bb0ce4d9..000000000000 --- a/packages/manager/apps/hycu/public/translations/dashboard/Messages_de_DE.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "title": "Dashboard-Seite", - "error_service": "Keine Serviceinformationen", - "general_informations": "Allgemeine Informationen", - "tab2": "Tab 2", - "back_link": "Zurück zur Liste" -} diff --git a/packages/manager/apps/hycu/public/translations/dashboard/Messages_en_GB.json b/packages/manager/apps/hycu/public/translations/dashboard/Messages_en_GB.json deleted file mode 100644 index 9522f26c30ab..000000000000 --- a/packages/manager/apps/hycu/public/translations/dashboard/Messages_en_GB.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "title": "Dashboard page", - "error_service": "No service", - "general_informations": "General information", - "tab2": "Tab 2", - "back_link": "Back to list" -} diff --git a/packages/manager/apps/hycu/public/translations/dashboard/Messages_es_ES.json b/packages/manager/apps/hycu/public/translations/dashboard/Messages_es_ES.json deleted file mode 100644 index 31bb48a634ea..000000000000 --- a/packages/manager/apps/hycu/public/translations/dashboard/Messages_es_ES.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "title": "Página del dashboard", - "error_service": "No hay información sobre el servicio", - "general_informations": "Información general", - "tab2": "Tab 2", - "back_link": "Volver a la lista" -} diff --git a/packages/manager/apps/hycu/public/translations/dashboard/Messages_fr_CA.json b/packages/manager/apps/hycu/public/translations/dashboard/Messages_fr_CA.json deleted file mode 100644 index f42a27b3366a..000000000000 --- a/packages/manager/apps/hycu/public/translations/dashboard/Messages_fr_CA.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "title": "Dashboard page", - "error_service": "No services info", - "general_informations": "Informations générales", - "tab2": "Tab 2", - "back_link": "Retour à la liste" -} diff --git a/packages/manager/apps/hycu/public/translations/dashboard/Messages_it_IT.json b/packages/manager/apps/hycu/public/translations/dashboard/Messages_it_IT.json deleted file mode 100644 index 1cf8cc0805eb..000000000000 --- a/packages/manager/apps/hycu/public/translations/dashboard/Messages_it_IT.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "title": "Dashboard page", - "error_service": "No services info", - "general_informations": "Informazioni generali", - "tab2": "Tab 2", - "back_link": "Torna alla lista" -} diff --git a/packages/manager/apps/hycu/public/translations/dashboard/Messages_pl_PL.json b/packages/manager/apps/hycu/public/translations/dashboard/Messages_pl_PL.json deleted file mode 100644 index 36611f8907fd..000000000000 --- a/packages/manager/apps/hycu/public/translations/dashboard/Messages_pl_PL.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "title": "Dashboard page", - "error_service": "No services info", - "general_informations": "Informacje ogólne", - "tab2": "Tab 2", - "back_link": "Powrót do listy" -} diff --git a/packages/manager/apps/hycu/public/translations/dashboard/Messages_pt_PT.json b/packages/manager/apps/hycu/public/translations/dashboard/Messages_pt_PT.json deleted file mode 100644 index 8b8b819ecd5b..000000000000 --- a/packages/manager/apps/hycu/public/translations/dashboard/Messages_pt_PT.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "title": "Dashboard page", - "error_service": "No services info", - "general_informations": "Informações gerais", - "tab2": "Tab 2", - "back_link": "Voltar à lista" -} diff --git a/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json index 5d312a1aefbf..2af5c6f6460a 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json @@ -2,7 +2,7 @@ "hycu_crumb": "HYCU", "hycu_description": "Simplifiez vos sauvegardes, plans de reprise après sinistre et migrations de votre infrastructure Nutanix. Ce service vous propose différents packs de licences HYCU Hybrid Cloud pour protéger vos charges de travail Nutanix.", "hycu_cloud_vm_pack_unknown": "Pack inconnu", - "hycu_status_activated": "Active", + "hycu_status_active": "Active", "hycu_status_toActivate": "À activer", "hycu_status_processing": "En cours d'activation", "hycu_status_error": "Erreur d'activation", diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json index 8863e0007465..21e7a6560142 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json @@ -8,7 +8,7 @@ "hycu_dashboard_shortcuts_title": "Raccourcis", "hycu_dashboard_link_activate": "Activer la licence", "hycu_dashboard_link_regenerate": "Regénérer la licence", - "hycu_dashboard_link_terminated": "Résilier la licence", + "hycu_dashboard_link_terminate": "Résilier la licence", "hycu_dashboard_link_change_pack_type": "Modifier le type de pack", "hycu_dashboard_field_label_contacts": "Contacts", "hycu_dashboard_contact_type_administrator": "Administrateur", @@ -26,7 +26,7 @@ "hycu_dashboard_license_activate_description": "Veuillez transférer votre fichier de demande de licence. Ce fichier est à télécharger depuis votre controller HYCU une fois votre installation réalisée", "hycu_dashboard_license_more_information_link": "(plus de détails ici)", "hycu_dashboard_activation_license_success_message": "La demande d'activation de votre licence a bien été prise en compte. Votre fichier de licence sera bientôt disponible sur cette interface et vous sera également envoyé par e-mail.", - "hycu_dashboard_activation_license_error_message": "Une erreur est survenue lors de la soumission de votre licence.", + "hycu_dashboard_activation_license_error_message": "Une erreur est survenue lors de la soumission de votre licence : {{error}}.", "hycu_dashboard_regenerate_error_message": "Une erreur est survenue lors de la soumission de votre licence.", "hycu_dashboard_license_regenerate_heading": "Regénérer la licence", "hycu_dashboard_license_regenerate_description": "Si votre environnement technique HYCU a changé, il est nécessaire de soumettre une nouvelle demande afin d'obtenir un nouveau fichier de licence compatible avec votre controller HYCU. Veuillez transférer votre nouveau fichier de demande de licence. En réalisant cette action, vous vous engagez également à ne plus utiliser le fichier de licence précédemment fourni.", @@ -44,10 +44,5 @@ "hycu_dashboard_update_display_name_description": "", "hycu_dashboard_update_display_name_pattern_message": "Veuillez saisir un nom dont la longueur est comprise entre 1 et 32 caractères.", "hycu_dashboard_update_display_name_success": "La description a été modifiée avec succès.", - "hycu_dashboard_edit_modal_error": "Une erreur est survenue: {{error}}.", - "hycu_dashboard_terminate_headline": "", - "hycu_dashboard_terminate_description": "", - "hycu_dashboard_terminate_input_label": "", - "hycu_dashboard_cancel_label": "", - "hycu_dashboard_confirm_label": "" + "hycu_dashboard_edit_modal_error": "Une erreur est survenue: {{error}}." } diff --git a/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_fr_FR.json new file mode 100644 index 000000000000..3eb7f2ea5363 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_fr_FR.json @@ -0,0 +1,9 @@ +{ + "hycu_terminate_headline": "Résilier le service HYCU for OVHcloud", + "hycu_terminate_description": "Veuillez entrer le mot \"TERMINATE\" pour confirmer la résiliation de votre service HYCU for OVHcloud. En réalisant cette action, vous vous engagez également à ne plus utiliser le fichier de licence préalablement fourni.", + "hycu_terminate_input_label": "Mot de confirmation : ", + "hycu_terminate_cancel_label": "Annuler", + "hycu_terminate_confirm_label": "Résilier", + "hycu_terminate_success_message": "Votre demande de résiliation pour {{serviceName}} à bien été prise en compte, vous allez recevoir un mail pour valider celle-ci.", + "hycu_terminate_error_message": "Une erreur est survenue: {{error}}." +} diff --git a/packages/manager/apps/hycu/src/components/ManagerLink/ManagerLink.component.tsx b/packages/manager/apps/hycu/src/components/ManagerLink/ManagerLink.component.tsx index 5bd63e346c11..43a57f0c9e27 100644 --- a/packages/manager/apps/hycu/src/components/ManagerLink/ManagerLink.component.tsx +++ b/packages/manager/apps/hycu/src/components/ManagerLink/ManagerLink.component.tsx @@ -25,7 +25,7 @@ export const ManagerLink = ({ const { t } = useTranslation('hycu'); const { isAuthorized } = useAuthorizationIam(iamActions, urn, isIamTrigger); - if (isAuthorized) { + if (isAuthorized || iamActions === undefined) { return {children}; } diff --git a/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts b/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts index 308ab639d3ee..b2c708bfbdbf 100644 --- a/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts +++ b/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts @@ -8,6 +8,7 @@ export const resourceList: IamCheckResponse[] = [ authorizedActions: [ IAM_ACTIONS.licenseHycuApiOvhActivate, IAM_ACTIONS.licenseHycuApiOvhRefresh, + IAM_ACTIONS.licenseHycuApiOvhTerminate, ], unauthorizedActions: [], }, diff --git a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.spec.tsx index 4520dadf9998..25b14fa90f82 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.spec.tsx @@ -1,15 +1,16 @@ import { screen, waitFor } from '@testing-library/react'; import { renderTestApp } from '@/utils/tests/renderTestApp'; import '@testing-library/jest-dom'; +import { licensesHycu } from '@/mocks/licenseHycu/licenseHycu.data'; describe('License Hycu Dashboard route test suite', () => { it('should show informations of services', async () => { - await renderTestApp('/4a26ef55-d46b-4b71-88c8-76ad71b154b4'); + await renderTestApp(`/${licensesHycu[0].serviceName}`); await waitFor( () => expect( - screen.getAllByText('425802fa-fb70-4b2a-9d5b-ec4de86bb40c')[0], + screen.getAllByText(licensesHycu[0].serviceName)[0], ).toBeVisible(), { timeout: 30_000 }, ); @@ -18,7 +19,7 @@ describe('License Hycu Dashboard route test suite', () => { }); it('should show error if api services fail', async () => { - await renderTestApp('/4a26ef55-d46b-4b71-88c8-76ad71b154b4', { + await renderTestApp(`/${licensesHycu[0].serviceName}`, { getServicesKo: true, isGetLicenseHycuKo: true, isGetServiceLicenseHycuKo: true, diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.spec.tsx index bf52fc02de2d..b21f2c30dfd8 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.spec.tsx @@ -1,4 +1,5 @@ -import { screen, waitFor } from '@testing-library/react'; +import { userEvent } from '@testing-library/user-event'; +import { screen, waitFor, act, fireEvent } from '@testing-library/react'; import { renderTestApp } from '@/utils/tests/renderTestApp'; import '@testing-library/jest-dom'; import { labels } from '@/utils/tests/init.i18n'; @@ -30,4 +31,79 @@ describe('License Hycu billing information tile for dashboard test suite', () => ), ).toBeVisible(); }); + + it('open terminate modal on click on resiliate', async () => { + const user = userEvent.setup(); + await renderTestApp(`/${licensesHycu[0].serviceName}`); + + await waitFor( + () => { + expect( + screen.getAllByText( + labels.dashboard.hycu_dashboard_subscription_title, + )[0], + ).toBeVisible(); + expect( + screen.getByText(labels.dashboard.hycu_dashboard_link_terminate), + ).not.toHaveAttribute('disabled'); + }, + { timeout: 30_000 }, + ); + + const resiliateButton = await screen.getByText( + labels.dashboard.hycu_dashboard_link_terminate, + ); + + await act(() => user.click(resiliateButton)); + + await waitFor( + () => + expect( + screen.getByText(labels.terminate.hycu_terminate_description), + ).toBeVisible(), + { timeout: 10_000 }, + ); + }); + + it('See success message after terminate service', async () => { + const user = userEvent.setup(); + await renderTestApp(`/${licensesHycu[0].serviceName}/terminate`); + + await waitFor( + () => + expect( + screen.getByText(labels.terminate.hycu_terminate_description), + ).toBeVisible(), + { timeout: 10_000 }, + ); + + await act(() => + fireEvent.change(screen.getByLabelText('delete-input'), { + target: { value: 'TERMINATE' }, + }), + ); + + const resiliateButton = await screen.getByText( + labels.terminate.hycu_terminate_confirm_label, + { + exact: true, + }, + ); + + await waitFor( + () => expect(resiliateButton).not.toHaveAttribute('disabled'), + { timeout: 10_000 }, + ); + + await act(() => user.click(resiliateButton)); + + await waitFor( + () => { + expect( + screen.queryByText(labels.terminate.hycu_terminate_description), + ).not.toBeInTheDocument(); + }, + { timeout: 10_000 }, + ); + }); }); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx index d6699e96ba56..ccae46fd3c56 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx @@ -2,7 +2,6 @@ import { DashboardTile, DateFormat, Description, - Renew, useFormattedDate, useServiceDetails, } from '@ovh-ux/manager-react-components'; @@ -13,19 +12,23 @@ import { OsdsLink, OsdsSkeleton, } from '@ovhcloud/ods-components/react'; +import { useNavigate } from 'react-router-dom'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { useNavigationGetUrl } from '@/hooks/shell/useNavigationGetUrl'; +import { subRoutes, urls } from '@/routes/routes.constant'; +import { ManagerLink } from '@/components/ManagerLink/ManagerLink.component'; const BillingInformationsTile = ({ serviceName }: { serviceName: string }) => { const { t } = useTranslation('hycu/dashboard'); + const navigate = useNavigate(); const { data: serviceDetails, isLoading } = useServiceDetails({ resourceName: serviceName, }); const renewDate = useFormattedDate({ - dateString: (serviceDetails?.data.billing.renew as Renew)?.current.nextDate, + dateString: serviceDetails?.data.billing.nextBillingDate, format: DateFormat.display, }); @@ -49,6 +52,11 @@ const BillingInformationsTile = ({ serviceName }: { serviceName: string }) => { { searchText: serviceName }, ]); + const openTerminateModal = () => + navigate( + urls.dashboard_terminate.replace(subRoutes.serviceName, serviceName), + ); + return ( { { id: 'link_terminated', value: ( - - {t('hycu_dashboard_link_terminated')} - + +
    +
    {t('hycu_dashboard_link_terminate')}
    - - +
    +
    ), }, ]} diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/DashboardGeneralInformation.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/DashboardGeneralInformation.page.tsx index 50937a5b2edc..f6c2973aee8a 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/DashboardGeneralInformation.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/DashboardGeneralInformation.page.tsx @@ -9,7 +9,7 @@ function GeneralInfos() { return ( <> -
    +
    diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx index 5947f5d9f19b..3244e8e7a6d7 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx @@ -3,10 +3,11 @@ import { renderTestApp } from '@/utils/tests/renderTestApp'; import '@testing-library/jest-dom'; import { labels } from '@/utils/tests/init.i18n'; import { LicenseStatus } from '@/types/hycu.details.interface'; +import { licensesHycu } from '@/mocks/licenseHycu/licenseHycu.data'; describe('License Hycu general informations tile for dashboard test suite', () => { it('should show informations of services', async () => { - await renderTestApp('/4a26ef55-d46b-4b71-88c8-76ad71b154b4'); + await renderTestApp(`/${licensesHycu[0].serviceName}`); await waitFor( () => @@ -40,7 +41,7 @@ describe('License Hycu general informations tile for dashboard test suite', () = }); it('should show download license button when license is activated', async () => { - await renderTestApp('/4a26ef55-d46b-4b71-88c8-76ad71b154b4', { + await renderTestApp(`/${licensesHycu[0].serviceName}`, { licenseStatus: LicenseStatus.ACTIVATED, }); @@ -70,7 +71,7 @@ describe('License Hycu general informations tile for dashboard test suite', () = }); it('should show wait for activation if license is not activated', async () => { - await renderTestApp('/4a26ef55-d46b-4b71-88c8-76ad71b154b4', { + await renderTestApp(`/${licensesHycu[0].serviceName}`, { licenseStatus: LicenseStatus.TO_ACTIVATE, }); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.spec.tsx index 91d7f0092970..e19b6788fa5e 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.spec.tsx @@ -177,7 +177,10 @@ describe('License Hycu activate license route test suite', () => { ).toBeVisible(); expect( screen.queryAllByText( - labels.dashboard.hycu_dashboard_activation_license_error_message, + labels.dashboard.hycu_dashboard_activation_license_error_message.replace( + '{{error}}', + 'Request failed with status code 500', + ), )[1], ).toBeVisible(); }, diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.tsx index 8135dad0fb0e..4837a064304a 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.tsx @@ -1,3 +1,4 @@ +import { AxiosError } from 'axios'; import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; import { ODS_BUTTON_TYPE, @@ -56,8 +57,12 @@ export const ActivationHycuLicenseModal: React.FC { - addError(t('hycu_dashboard_activation_license_error_message')); + onError: (error: AxiosError<{ message: string }>) => { + addError( + t('hycu_dashboard_activation_license_error_message', { + error: error.response.data?.message || error.message, + }), + ); }, }); const onSubmit: SubmitHandler = (data) => { diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit/EditHycu.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx similarity index 96% rename from packages/manager/apps/hycu/src/pages/dashboard/general-information/edit/EditHycu.page.tsx rename to packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx index 675853981966..f5350ebc4a37 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit/EditHycu.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx @@ -9,7 +9,7 @@ import { import { AxiosError } from 'axios'; import { useInvalidateCacheForALicenseHycu } from '@/hooks/api/license'; -export default function EditVeeamBackupDisplayNameModal() { +export default function EditHycuDisplayNameModal() { const { serviceName } = useParams(); const { addSuccess, addError } = useNotifications(); const { t } = useTranslation('hycu/dashboard'); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit/EditHycu.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.spec.tsx similarity index 100% rename from packages/manager/apps/hycu/src/pages/dashboard/general-information/edit/EditHycu.spec.tsx rename to packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.spec.tsx diff --git a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx index e4110a3891bb..59b38ddd0013 100644 --- a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx +++ b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx @@ -1,6 +1,6 @@ import React, { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; -import { useNavigate } from 'react-router-dom'; +import { Outlet, useNavigate } from 'react-router-dom'; import { OsdsButton, @@ -18,6 +18,7 @@ import { useServiceDetails, DateFormat, useFormattedDate, + Notifications, } from '@ovh-ux/manager-react-components'; import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; @@ -56,7 +57,13 @@ const DatagridIdCell = (hycuDetail: IHycuDetails) => { }; const DatagridControllerIdCell = (hycuDetail: IHycuDetails) => { - return {hycuDetail.controllerId || '-'}; + return ( + + {hycuDetail.controllerId || '-'} + + ); }; const DatagridStatusCell = (hycuDetail: IHycuDetails) => { @@ -178,47 +185,51 @@ export default function Listing() { }; return ( - - {tError('manager_error_page_default')} - - } - > - - -
    -
    - { - navigate(urls.order); - }} - inline - > - {t('hycu_order')} - + <> + + {tError('manager_error_page_default')} + + } + > + + + +
    +
    + { + navigate(urls.order); + }} + inline + > + {t('hycu_order')} + +
    + {columns && flattenData && ( + + )}
    - {columns && flattenData && ( - - )} -
    - - - + + + + + ); } diff --git a/packages/manager/apps/hycu/src/pages/listing/Listing.spec.tsx b/packages/manager/apps/hycu/src/pages/listing/Listing.spec.tsx index 8f66769de572..e2bdb8a70f5e 100644 --- a/packages/manager/apps/hycu/src/pages/listing/Listing.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/listing/Listing.spec.tsx @@ -1,4 +1,4 @@ -import { act, screen, waitFor } from '@testing-library/react'; +import { act, fireEvent, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { renderTestApp } from '@/utils/tests/renderTestApp'; import '@testing-library/jest-dom'; @@ -61,4 +61,83 @@ describe('License Hycu listing test suite', () => { { timeout: 30_000 }, ); }); + + it('open terminate modal on click on resiliate', async () => { + const user = userEvent.setup(); + await renderTestApp(`/`); + + const resiliateButton = await screen.getAllByText( + labels.terminate.hycu_terminate_confirm_label, + { + exact: true, + }, + ); + + await waitFor( + () => { + expect( + screen.getAllByText(licensesHycu[0].serviceName)[0], + ).toBeVisible(); + expect(resiliateButton[resiliateButton.length - 1]).not.toHaveAttribute( + 'disabled', + ); + }, + { timeout: 30_000 }, + ); + + await act(() => user.click(resiliateButton[resiliateButton.length - 1])); + + await waitFor( + () => + expect( + screen.getByText(labels.terminate.hycu_terminate_description), + ).toBeVisible(), + { timeout: 10_000 }, + ); + }); + + it('See success message after terminate service', async () => { + const user = userEvent.setup(); + await renderTestApp(`/terminate/${licensesHycu[0].serviceName}`); + + await waitFor( + () => + expect( + screen.getByText(labels.terminate.hycu_terminate_description), + ).toBeVisible(), + { timeout: 10_000 }, + ); + + await act(() => + fireEvent.change(screen.getByLabelText('delete-input'), { + target: { value: 'TERMINATE' }, + }), + ); + + const resiliateButton = await screen.getAllByText( + labels.terminate.hycu_terminate_confirm_label, + { + exact: true, + }, + ); + + await waitFor( + () => + expect(resiliateButton[resiliateButton.length - 1]).not.toHaveAttribute( + 'disabled', + ), + { timeout: 10_000 }, + ); + + await act(() => user.click(resiliateButton[resiliateButton.length - 1])); + + await waitFor( + () => { + expect( + screen.queryByText(labels.terminate.hycu_terminate_description), + ).not.toBeInTheDocument(); + }, + { timeout: 10_000 }, + ); + }); }); diff --git a/packages/manager/apps/hycu/src/pages/listing/menu/HycuActionMenu.component.tsx b/packages/manager/apps/hycu/src/pages/listing/menu/HycuActionMenu.component.tsx index 1bc6481d690f..d7f89d40c1af 100644 --- a/packages/manager/apps/hycu/src/pages/listing/menu/HycuActionMenu.component.tsx +++ b/packages/manager/apps/hycu/src/pages/listing/menu/HycuActionMenu.component.tsx @@ -1,21 +1,26 @@ import { ActionMenu, ActionMenuItem } from '@ovh-ux/manager-react-components'; import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import { useNavigate } from 'react-router-dom'; import React from 'react'; -import { ODS_ICON_NAME } from '@ovhcloud/ods-components'; +import { ODS_BUTTON_VARIANT, ODS_ICON_NAME } from '@ovhcloud/ods-components'; import { useTranslation } from 'react-i18next'; import { IHycuDetails } from '@/types/hycu.details.interface'; +import { subRoutes, urls } from '@/routes/routes.constant'; -const HycuActionMenu = ({ - serviceName: _serviceName, -}: Pick) => { +const HycuActionMenu = ({ serviceName }: Pick) => { const { t } = useTranslation('hycu/listing'); + const navigate = useNavigate(); + const openTerminateModal = () => + navigate( + urls.listing_terminate.replace(subRoutes.serviceName, serviceName), + ); const items: ActionMenuItem[] = [ { id: 1, label: t('hycu_service_listing_terminate'), color: ODS_THEME_COLOR_INTENT.error, - onClick: () => {}, + onClick: openTerminateModal, }, ]; @@ -23,6 +28,7 @@ const HycuActionMenu = ({ ); diff --git a/packages/manager/apps/hycu/src/pages/terminate/terminate-hycu.tsx b/packages/manager/apps/hycu/src/pages/terminate/terminate-hycu.tsx new file mode 100644 index 000000000000..6758a7da4de8 --- /dev/null +++ b/packages/manager/apps/hycu/src/pages/terminate/terminate-hycu.tsx @@ -0,0 +1,46 @@ +import { + DeleteServiceModal, + useNotifications, +} from '@ovh-ux/manager-react-components'; +import { AxiosError } from 'axios'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { useNavigate, useParams } from 'react-router-dom'; + +export const TerminateLicensePage = () => { + const { t } = useTranslation('hycu/terminate'); + const { serviceName } = useParams(); + const navigate = useNavigate(); + const { addSuccess, addError } = useNotifications(); + + const closeModal = () => { + navigate('..'); + }; + + const handleSuccessDelete = async () => { + addSuccess(t('hycu_terminate_success_message', { serviceName }), true); + closeModal(); + }; + + const handleErrorDelete = async (error: AxiosError) => { + addError(t('hycu_terminate_error_message', { error: error.message })); + closeModal(); + }; + + return ( + {}} + /> + ); +}; + +export default TerminateLicensePage; diff --git a/packages/manager/apps/hycu/src/routes/routes.constant.ts b/packages/manager/apps/hycu/src/routes/routes.constant.ts index a58039b86642..fb65c8e9c65b 100644 --- a/packages/manager/apps/hycu/src/routes/routes.constant.ts +++ b/packages/manager/apps/hycu/src/routes/routes.constant.ts @@ -13,4 +13,6 @@ export const urls = { activateLicense: `/${subRoutes.serviceName}/activate-license`, regenerateLicense: `/${subRoutes.serviceName}/regenerate-license`, editName: `/${subRoutes.serviceName}/edit-name`, + dashboard_terminate: `/${subRoutes.serviceName}/terminate`, + listing_terminate: `/terminate/${subRoutes.serviceName}`, } as const; diff --git a/packages/manager/apps/hycu/src/routes/routes.tsx b/packages/manager/apps/hycu/src/routes/routes.tsx index 365f964f269e..e949ce90b61d 100644 --- a/packages/manager/apps/hycu/src/routes/routes.tsx +++ b/packages/manager/apps/hycu/src/routes/routes.tsx @@ -25,6 +25,15 @@ export const Routes: any = [ id: 'listing', path: urls.listing, ...lazyRouteConfig(() => import('@/pages/listing/Listing.page')), + children: [ + { + id: 'listing_terminate', + path: urls.listing_terminate, + ...lazyRouteConfig(() => + import('@/pages/terminate/terminate-hycu'), + ), + }, + ], handle: { tracking: { pageName: 'listing', @@ -74,10 +83,17 @@ export const Routes: any = [ path: urls.editName, ...lazyRouteConfig(() => import( - '@/pages/dashboard/general-information/edit/EditHycu.page' + '@/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page' ), ), }, + { + id: 'dashboard_terminate', + path: urls.dashboard_terminate, + ...lazyRouteConfig(() => + import('@/pages/terminate/terminate-hycu'), + ), + }, ], }, ], diff --git a/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts b/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts index fd6ddc81e034..15efbe31b18f 100644 --- a/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts +++ b/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts @@ -5,6 +5,7 @@ import dashboard from '../../../public/translations/hycu/dashboard/Messages_fr_F import listing from '../../../public/translations/hycu/listing/Messages_fr_FR.json'; import onboarding from '../../../public/translations/hycu/onboarding/Messages_fr_FR.json'; import order from '../../../public/translations/hycu/order/Messages_fr_FR.json'; +import terminate from '../../../public/translations/hycu/terminate/Messages_fr_FR.json'; export const defaultLocale = 'fr_FR'; export const defaultAvailableLocales = [defaultLocale]; @@ -16,6 +17,7 @@ function addTranslations() { .addResources(defaultLocale, 'hycu/listing', listing) .addResources(defaultLocale, 'hycu/onboarding', onboarding) .addResources(defaultLocale, 'hycu/order', order) + .addResources(defaultLocale, 'hycu/terminate', terminate) .addResources(defaultLocale, 'error', error) .use({ type: 'postProcessor', @@ -56,5 +58,6 @@ export const labels = { listing, onboarding, order, + terminate, error, }; From 2c573162308d8eb8fce30f57518d27d72416ba78 Mon Sep 17 00:00:00 2001 From: Thibaud Crespin Date: Mon, 28 Oct 2024 19:44:54 +0100 Subject: [PATCH 20/43] fix(hycu): rootLabel in breadcrumb ref: MANAGER-15803 Signed-off-by: Thibaud Crespin --- .../src/components/Breadcrumb/Breadcrumb.component.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/manager/apps/hycu/src/components/Breadcrumb/Breadcrumb.component.tsx b/packages/manager/apps/hycu/src/components/Breadcrumb/Breadcrumb.component.tsx index 2e321a7de738..a3fff936d49d 100644 --- a/packages/manager/apps/hycu/src/components/Breadcrumb/Breadcrumb.component.tsx +++ b/packages/manager/apps/hycu/src/components/Breadcrumb/Breadcrumb.component.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { OsdsBreadcrumb } from '@ovhcloud/ods-components/react'; +import { useTranslation } from 'react-i18next'; import { useBreadcrumb, BreadcrumbItem, } from '@/hooks/breadcrumb/useBreadcrumb'; -import appConfig from '@/hycu.config'; export interface BreadcrumbProps { customRootLabel?: string; @@ -12,11 +12,11 @@ export interface BreadcrumbProps { items?: BreadcrumbItem[]; } -function Breadcrumb({ customRootLabel, items }: BreadcrumbProps): JSX.Element { - const label = customRootLabel || appConfig.rootLabel; +function Breadcrumb({ items }: BreadcrumbProps): JSX.Element { + const { t } = useTranslation('hycu'); const breadcrumbItems = useBreadcrumb({ - rootLabel: label, + rootLabel: t('hycu_crumb'), items, }); return ; From c4735e08ba6ebb9143b05efe6ecf574c468692b3 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Tue, 29 Oct 2024 12:32:59 +0100 Subject: [PATCH 21/43] feat(hycu): add download license action ref: 14499 Signed-off-by: Thibault Barske --- .../hycu/dashboard/Messages_fr_FR.json | 4 +- .../FileUpload/FileUpload.component.tsx | 14 ++++- packages/manager/apps/hycu/src/constants.ts | 3 + .../manager/apps/hycu/src/data/api/hycu.ts | 14 +++++ .../apps/hycu/src/hooks/api/license.ts | 34 +++++++++++ .../apps/hycu/src/mocks/iam/iam.mock.ts | 1 + .../hycu/src/mocks/licenseHycu/licenseHycu.ts | 7 +++ .../GeneralInformationsTile.spec.tsx | 61 ++++++++++++++++++- .../GeneralInformationsTile.tsx | 17 ++++-- .../ShortcutsTile/ShortcutsTile.tsx | 2 +- .../hycu/src/pages/listing/Listing.page.tsx | 1 + .../hycu/src/types/hycu.details.interface.ts | 2 +- .../apps/hycu/src/utils/downloadTextAsFile.ts | 13 ++++ .../apps/hycu/src/utils/iam.constants.ts | 1 + 14 files changed, 163 insertions(+), 11 deletions(-) create mode 100644 packages/manager/apps/hycu/src/utils/downloadTextAsFile.ts diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json index 21e7a6560142..a4f8ee193b4e 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json @@ -26,6 +26,7 @@ "hycu_dashboard_license_activate_description": "Veuillez transférer votre fichier de demande de licence. Ce fichier est à télécharger depuis votre controller HYCU une fois votre installation réalisée", "hycu_dashboard_license_more_information_link": "(plus de détails ici)", "hycu_dashboard_activation_license_success_message": "La demande d'activation de votre licence a bien été prise en compte. Votre fichier de licence sera bientôt disponible sur cette interface et vous sera également envoyé par e-mail.", + "hycu_dashboard_regenerate_success_message": "La demande d'activation de votre licence a bien été prise en compte. Votre fichier de licence sera bientôt disponible sur cette interface et vous sera également envoyé par e-mail.", "hycu_dashboard_activation_license_error_message": "Une erreur est survenue lors de la soumission de votre licence : {{error}}.", "hycu_dashboard_regenerate_error_message": "Une erreur est survenue lors de la soumission de votre licence.", "hycu_dashboard_license_regenerate_heading": "Regénérer la licence", @@ -34,7 +35,8 @@ "hycu_dashboard_regenerate_upload_confirm": "Regénérer", "hycu_dashboard_upload_cancel": "Annuler", "hycu_dashboard_upload_confirm": "Activer", - "hycu_dashboard_upload_valid_file": "Merci de sélectionner un fichier valide", + "hycu_dashboard_upload_file_too_big": "La taille du fichier ne peut pas excéder 1Mo", + "hycu_dashboard_upload_file_bad_type": "Le fichier fourni n'est pas un fichier .dat", "hycu_dashboard_upload_license_required": "Veuillez sélectionner une licence", "hycu_dashboard_drag_and_drop_attachment": "Glissez-Déposer une pièce jointe", "hycu_dashboard_accepted_formats": "Format accepté: .dat", diff --git a/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx b/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx index a16ecd78b749..7ff18a60eb2d 100644 --- a/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx +++ b/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx @@ -31,14 +31,24 @@ export const FileInputField = ({ if (file.size > MAX_FILE_SIZE) { setFileName(''); control.setError(name, { - message: t('hycu_dashboard_upload_valid_file'), + message: t('hycu_dashboard_upload_file_too_big'), + }); + return; + } + if (!file.name.endsWith('.dat')) { + setFileName(''); + control.setError(name, { + message: t('hycu_dashboard_upload_file_bad_type'), }); return; } const reader = new FileReader(); reader.onloadend = () => { - const base64String = btoa(reader.result as string); + const base64String = (reader.result as string).replace( + 'data:application/octet-stream;base64,', + '', + ); onChange(base64String); setFileName(file.name); control.setError(name, undefined); diff --git a/packages/manager/apps/hycu/src/constants.ts b/packages/manager/apps/hycu/src/constants.ts index b519834748ef..c10d50de8d3b 100644 --- a/packages/manager/apps/hycu/src/constants.ts +++ b/packages/manager/apps/hycu/src/constants.ts @@ -7,3 +7,6 @@ export const packTypeLabel = { 'hycu-cloud-vm-pack-250': '250 VMs', 'hycu-cloud-vm-pack-500': '500 VMs', } as const; + +export const PREFIX_LICENSE_FILE_NAME = 'license-hycu-' as const; +export const SUFFIX_LICENSE_FILE_NAME = '.dat' as const; diff --git a/packages/manager/apps/hycu/src/data/api/hycu.ts b/packages/manager/apps/hycu/src/data/api/hycu.ts index fd35524f7363..e34683541522 100644 --- a/packages/manager/apps/hycu/src/data/api/hycu.ts +++ b/packages/manager/apps/hycu/src/data/api/hycu.ts @@ -21,6 +21,10 @@ export const postRegenerateLicenseHycuMutationKey = () => [ 'license/hycu/refresh', 'post', ]; +export const getDownloadLicenseHycuMutationKey = () => [ + 'license/hycu/download', + 'get', +]; /** * Manage HYCU licenses : Get list of owned HYCU licenses @@ -34,6 +38,8 @@ export type GetlicenseHycuServiceParams = { serviceName?: string; }; +export type GetLicenseHycuDownloadServiceParams = { serviceName: string }; + /** * Manage HYCU licenses : Get HYCU license info */ @@ -70,6 +76,14 @@ export const postLicenseHycuRegenerateService = ( licenseRequest: params.licenseContent, }); +/** + * Regenerate HYCU licenses : Post HYCU license content + */ +export const getLicenseHycuDownloadService = ( + params: GetLicenseHycuDownloadServiceParams, +): Promise => + apiClient.v6.get(`/license/hycu/${params.serviceName}/license`); + /** * Get listing with iceberg V6 */ diff --git a/packages/manager/apps/hycu/src/hooks/api/license.ts b/packages/manager/apps/hycu/src/hooks/api/license.ts index dc53680d3dee..a5a07850d4f4 100644 --- a/packages/manager/apps/hycu/src/hooks/api/license.ts +++ b/packages/manager/apps/hycu/src/hooks/api/license.ts @@ -8,6 +8,9 @@ import { } from '@tanstack/react-query'; import { getServiceDetailsQueryKey } from '@ovh-ux/manager-react-components'; import { + getDownloadLicenseHycuMutationKey, + getLicenseHycuDownloadService, + GetLicenseHycuDownloadServiceParams, getLicenseHycuListQueryKey, getLicenseHycuQueryKey, getLicenseHycuService, @@ -18,6 +21,11 @@ import { postRegenerateLicenseHycuMutationKey, } from '@/data/api/hycu'; import { IHycuDetails } from '@/types/hycu.details.interface'; +import { downloadTextAsFile } from '@/utils/downloadTextAsFile'; +import { + PREFIX_LICENSE_FILE_NAME, + SUFFIX_LICENSE_FILE_NAME, +} from '@/constants'; export const useDetailsLicenseHYCU = ( serviceName: string, @@ -90,3 +98,29 @@ export const useRegenerateLicenseHYCUMutation = ( ...(restOptions ?? {}), }); }; + +export const useDownloadLicenseHYCUMutation = ( + options: Partial< + UseMutationOptions< + AxiosResponse<{ content: string }>, + Error, + GetLicenseHycuDownloadServiceParams + > + > = {}, +) => { + const { onSuccess, ...restOptions } = options; + + return useMutation({ + mutationKey: getDownloadLicenseHycuMutationKey(), + mutationFn: (params) => getLicenseHycuDownloadService(params), + onSuccess: (data, variables, context) => { + downloadTextAsFile( + `${PREFIX_LICENSE_FILE_NAME}${variables.serviceName}${SUFFIX_LICENSE_FILE_NAME}`, + data.data.content, + ); + + onSuccess?.(data, variables, context); + }, + ...(restOptions ?? {}), + }); +}; diff --git a/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts b/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts index b2c708bfbdbf..d35d19f16165 100644 --- a/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts +++ b/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts @@ -6,6 +6,7 @@ export const resourceList: IamCheckResponse[] = [ { urn: licensesHycu[0].iam.urn, authorizedActions: [ + IAM_ACTIONS.licenseHycuApiOvhGet, IAM_ACTIONS.licenseHycuApiOvhActivate, IAM_ACTIONS.licenseHycuApiOvhRefresh, IAM_ACTIONS.licenseHycuApiOvhTerminate, diff --git a/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts b/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts index 5c9a9bc707bd..1a0844e6d39c 100644 --- a/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts +++ b/packages/manager/apps/hycu/src/mocks/licenseHycu/licenseHycu.ts @@ -62,5 +62,12 @@ export const getLicenseHycuMocks = ({ status: isPostLicenseHycuKo ? 500 : 200, api: 'v6', }, + { + url: 'license/hycu/:serviceName/license', + response: { content: 'my license content' }, + method: 'get', + status: isPostLicenseHycuKo ? 500 : 200, + api: 'v6', + }, ]; }; diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx index 3244e8e7a6d7..8e723b56ebbf 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx @@ -1,9 +1,16 @@ -import { screen, waitFor } from '@testing-library/react'; -import { renderTestApp } from '@/utils/tests/renderTestApp'; import '@testing-library/jest-dom'; +import { userEvent } from '@testing-library/user-event'; +import { act, screen, waitFor } from '@testing-library/react'; +import { vi, vitest } from 'vitest'; +import { renderTestApp } from '@/utils/tests/renderTestApp'; import { labels } from '@/utils/tests/init.i18n'; import { LicenseStatus } from '@/types/hycu.details.interface'; import { licensesHycu } from '@/mocks/licenseHycu/licenseHycu.data'; +import { downloadTextAsFile } from '@/utils/downloadTextAsFile'; +import { + PREFIX_LICENSE_FILE_NAME, + SUFFIX_LICENSE_FILE_NAME, +} from '@/constants'; describe('License Hycu general informations tile for dashboard test suite', () => { it('should show informations of services', async () => { @@ -99,4 +106,54 @@ describe('License Hycu general informations tile for dashboard test suite', () = screen.queryByText(labels.dashboard.hycu_dashboard_download_license_file), ).not.toBeInTheDocument(); }); + + it('Can open download modal with IAM authorization', async () => { + vitest.mock('@/utils/downloadTextAsFile', () => ({ + downloadTextAsFile: vi.fn(), + })); + + const user = userEvent.setup(); + await renderTestApp(`/${licensesHycu[0].serviceName}`, { + licenseStatus: LicenseStatus.ACTIVATED, + }); + + await waitFor( + () => { + expect( + screen.getByTestId('dashboard-license-download-link'), + ).not.toHaveAttribute('disabled'); + }, + { timeout: 30_000 }, + ); + await act(() => + user.click(screen.getByTestId('dashboard-license-download-link')), + ); + + await waitFor( + () => + expect(downloadTextAsFile).toHaveBeenCalledWith( + `${PREFIX_LICENSE_FILE_NAME}${licensesHycu[0].serviceName}${SUFFIX_LICENSE_FILE_NAME}`, + 'my license content', + ), + { timeout: 20_000 }, + ); + }); + + it("Can't open download modal without IAM authorization", async () => { + await renderTestApp(`/${licensesHycu[1].serviceName}`, { + licenseStatus: LicenseStatus.ACTIVATED, + }); + + await waitFor( + () => { + expect( + screen.getByTestId('dashboard-license-download-link'), + ).toBeVisible(); + expect( + screen.getByTestId('dashboard-license-download-link'), + ).toHaveAttribute('disabled'); + }, + { timeout: 30_000 }, + ); + }); }); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx index d051b3c58bce..b9ff4eaf1910 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx @@ -24,21 +24,30 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; import { getStatusColor } from '@/utils/statusColor'; -import { useDetailsLicenseHYCU } from '@/hooks/api/license'; +import { + useDetailsLicenseHYCU, + useDownloadLicenseHYCUMutation, +} from '@/hooks/api/license'; import { LicenseStatus } from '@/types/hycu.details.interface'; import { subRoutes, urls } from '@/routes/routes.constant'; +import { ManagerLink } from '@/components/ManagerLink/ManagerLink.component'; +import { IAM_ACTIONS } from '@/utils/iam.constants'; const ActivateHycuLicense = ({ serviceName }: { serviceName: string }) => { const { t } = useTranslation('hycu/dashboard'); const { data: hycuDetail, isLoading } = useDetailsLicenseHYCU(serviceName); + const { mutate } = useDownloadLicenseHYCUMutation(); if (isLoading) return ; if (LicenseStatus.ACTIVATED !== hycuDetail?.data.licenseStatus) return <>{t('hycu_dashboard_wait_for_activation')}; return ( - mutate({ serviceName })} > {t('hycu_dashboard_download_license_file')} @@ -49,7 +58,7 @@ const ActivateHycuLicense = ({ serviceName }: { serviceName: string }) => { color={ODS_THEME_COLOR_INTENT.primary} > - + ); }; diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx index 78f4a5333b84..4389a214a92a 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx @@ -84,7 +84,7 @@ const ShortcutsTile = ({ serviceName }: { serviceName: string }) => { { return ( Date: Tue, 29 Oct 2024 15:27:09 +0100 Subject: [PATCH 22/43] feat(hycu): add error message when license is in error ref: MANAGER-14499 Signed-off-by: Thibault Barske --- .../hycu/dashboard/Messages_fr_FR.json | 3 ++- packages/manager/apps/hycu/src/constants.ts | 3 +-- .../manager/apps/hycu/src/hooks/api/license.ts | 10 +++++----- .../src/pages/dashboard/Dashboard.page.tsx | 18 +++++++++++++++++- .../GeneralInformationsTile.spec.tsx | 10 +++++----- .../apps/hycu/src/utils/downloadTextAsFile.ts | 2 -- packages/manager/apps/hycu/vitest.config.js | 1 + 7 files changed, 31 insertions(+), 16 deletions(-) diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json index a4f8ee193b4e..84a63b28b2a0 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json @@ -46,5 +46,6 @@ "hycu_dashboard_update_display_name_description": "", "hycu_dashboard_update_display_name_pattern_message": "Veuillez saisir un nom dont la longueur est comprise entre 1 et 32 caractères.", "hycu_dashboard_update_display_name_success": "La description a été modifiée avec succès.", - "hycu_dashboard_edit_modal_error": "Une erreur est survenue: {{error}}." + "hycu_dashboard_edit_modal_error": "Une erreur est survenue: {{error}}.", + "hycu_dashboard_error_license_message": "Une erreur est survenue lors de l'activation de votre licence ({{error}}). Nous vous invitons à vérifier les informations fournies et à réaliser une nouvelle tentative. Si le problème persiste, veuillez contacter notre support." } diff --git a/packages/manager/apps/hycu/src/constants.ts b/packages/manager/apps/hycu/src/constants.ts index c10d50de8d3b..853d86fd5e22 100644 --- a/packages/manager/apps/hycu/src/constants.ts +++ b/packages/manager/apps/hycu/src/constants.ts @@ -8,5 +8,4 @@ export const packTypeLabel = { 'hycu-cloud-vm-pack-500': '500 VMs', } as const; -export const PREFIX_LICENSE_FILE_NAME = 'license-hycu-' as const; -export const SUFFIX_LICENSE_FILE_NAME = '.dat' as const; +export const LICENSE_FILE_NAME_TEMPLATE = 'license-hycu-{serviceName}.dat' as const; diff --git a/packages/manager/apps/hycu/src/hooks/api/license.ts b/packages/manager/apps/hycu/src/hooks/api/license.ts index a5a07850d4f4..83dafe6acefc 100644 --- a/packages/manager/apps/hycu/src/hooks/api/license.ts +++ b/packages/manager/apps/hycu/src/hooks/api/license.ts @@ -22,10 +22,7 @@ import { } from '@/data/api/hycu'; import { IHycuDetails } from '@/types/hycu.details.interface'; import { downloadTextAsFile } from '@/utils/downloadTextAsFile'; -import { - PREFIX_LICENSE_FILE_NAME, - SUFFIX_LICENSE_FILE_NAME, -} from '@/constants'; +import { LICENSE_FILE_NAME_TEMPLATE } from '@/constants'; export const useDetailsLicenseHYCU = ( serviceName: string, @@ -115,7 +112,10 @@ export const useDownloadLicenseHYCUMutation = ( mutationFn: (params) => getLicenseHycuDownloadService(params), onSuccess: (data, variables, context) => { downloadTextAsFile( - `${PREFIX_LICENSE_FILE_NAME}${variables.serviceName}${SUFFIX_LICENSE_FILE_NAME}`, + LICENSE_FILE_NAME_TEMPLATE.replace( + '{serviceName}', + variables.serviceName, + ), data.data.content, ); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx index 2614a12a960b..2a0e7bafb0fa 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { Outlet, @@ -17,11 +17,14 @@ import { BaseLayout, useServiceDetails, Notifications, + useNotifications, } from '@ovh-ux/manager-react-components'; import Breadcrumb from '@/components/Breadcrumb/Breadcrumb.component'; import Errors from '@/components/Error/Error'; import { urls } from '@/routes/routes.constant'; +import { useDetailsLicenseHYCU } from '@/hooks/api/license'; +import { LicenseStatus } from '@/types/hycu.details.interface'; export type DashboardTabItemProps = { name: string; @@ -37,11 +40,24 @@ export default function DashboardPage() { const { serviceName } = useParams(); const navigate = useNavigate(); const { t } = useTranslation('hycu/dashboard'); + const { addError, clearNotifications } = useNotifications(); + const { data: licenseHycu } = useDetailsLicenseHYCU(serviceName); const { data: serviceDetails, error } = useServiceDetails({ resourceName: serviceName, }); + useEffect(() => { + if (licenseHycu?.data.licenseStatus === LicenseStatus.ERROR) { + clearNotifications(); + addError( + t('hycu_dashboard_error_license_message', { + error: licenseHycu.data.comment, + }), + ); + } + }, [licenseHycu]); + const tabsList = [ { name: 'general_informations', diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx index 8e723b56ebbf..9a163a247929 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.spec.tsx @@ -7,10 +7,7 @@ import { labels } from '@/utils/tests/init.i18n'; import { LicenseStatus } from '@/types/hycu.details.interface'; import { licensesHycu } from '@/mocks/licenseHycu/licenseHycu.data'; import { downloadTextAsFile } from '@/utils/downloadTextAsFile'; -import { - PREFIX_LICENSE_FILE_NAME, - SUFFIX_LICENSE_FILE_NAME, -} from '@/constants'; +import { LICENSE_FILE_NAME_TEMPLATE } from '@/constants'; describe('License Hycu general informations tile for dashboard test suite', () => { it('should show informations of services', async () => { @@ -132,7 +129,10 @@ describe('License Hycu general informations tile for dashboard test suite', () = await waitFor( () => expect(downloadTextAsFile).toHaveBeenCalledWith( - `${PREFIX_LICENSE_FILE_NAME}${licensesHycu[0].serviceName}${SUFFIX_LICENSE_FILE_NAME}`, + LICENSE_FILE_NAME_TEMPLATE.replace( + '{serviceName}', + licensesHycu[0].serviceName, + ), 'my license content', ), { timeout: 20_000 }, diff --git a/packages/manager/apps/hycu/src/utils/downloadTextAsFile.ts b/packages/manager/apps/hycu/src/utils/downloadTextAsFile.ts index 47c7749b45ac..147c702550f2 100644 --- a/packages/manager/apps/hycu/src/utils/downloadTextAsFile.ts +++ b/packages/manager/apps/hycu/src/utils/downloadTextAsFile.ts @@ -1,4 +1,3 @@ -/* c8 ignore start */ export function downloadTextAsFile(filename: string, text: string) { const blob = new Blob([text], { type: 'text/plain' }); const link = document.createElement('a'); @@ -10,4 +9,3 @@ export function downloadTextAsFile(filename: string, text: string) { document.body.removeChild(link); } -/* c8 ignore stop */ diff --git a/packages/manager/apps/hycu/vitest.config.js b/packages/manager/apps/hycu/vitest.config.js index 9075895638be..887795743e8d 100644 --- a/packages/manager/apps/hycu/vitest.config.js +++ b/packages/manager/apps/hycu/vitest.config.js @@ -19,6 +19,7 @@ export default defineConfig({ 'src/index.tsx', 'src/tracking.constant.ts', 'src/vite-hmr.ts', + 'src/utils/downloadTextAsFile.ts', ], }, testTimeout: 60000, From da3d39407200b1f5b524f8a5411546b161994027 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Tue, 29 Oct 2024 18:29:20 +0100 Subject: [PATCH 23/43] feat(hycu): change order of elements on billing component ref: MANAGER-14499 Signed-off-by: Thibault Barske --- .../BillingInformationsTile.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx index ccae46fd3c56..b75068884347 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx @@ -76,6 +76,15 @@ const BillingInformationsTile = ({ serviceName }: { serviceName: string }) => { ), }, + { + id: 'date_creation', + label: t('hycu_dashboard_field_label_date_creation'), + value: isLoading ? ( + + ) : ( + {creationDate} + ), + }, { id: 'contact', label: t('hycu_dashboard_field_label_contacts'), @@ -115,15 +124,6 @@ const BillingInformationsTile = ({ serviceName }: { serviceName: string }) => {
    ), }, - { - id: 'date_creation', - label: t('hycu_dashboard_field_label_date_creation'), - value: isLoading ? ( - - ) : ( - {creationDate} - ), - }, { id: 'link_terminated', value: ( From b1b08089a865e2d75c931583f0cba9efe8c9ce6e Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Wed, 30 Oct 2024 10:34:21 +0100 Subject: [PATCH 24/43] feat(hycu): change file extension accepted to request license ref: MANAGER-14499 Signed-off-by: Thibault Barske --- .../hycu/dashboard/Messages_fr_FR.json | 8 +-- .../FileUpload/FileUpload.component.tsx | 13 +++-- packages/manager/apps/hycu/src/constants.ts | 3 +- .../src/pages/dashboard/Dashboard.page.tsx | 53 ++++++++++--------- .../ActivationLicenseModal.page.spec.tsx | 4 +- .../ActivationLicenseModal.page.tsx | 4 +- .../EditHycuDisplayName.page.tsx | 8 +-- .../RegenerateLicenseModal.page.spec.tsx | 13 +++-- .../RegenerateLicenseModal.page.tsx | 4 +- .../src/pages/terminate/terminate-hycu.tsx | 4 +- 10 files changed, 60 insertions(+), 54 deletions(-) diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json index 84a63b28b2a0..cc7937400ab9 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json @@ -24,9 +24,9 @@ "hycu_dashboard_wait_for_activation": "En attente d'activation", "hycu_dashboard_license_activate_heading": "Activer la licence", "hycu_dashboard_license_activate_description": "Veuillez transférer votre fichier de demande de licence. Ce fichier est à télécharger depuis votre controller HYCU une fois votre installation réalisée", - "hycu_dashboard_license_more_information_link": "(plus de détails ici)", + "hycu_dashboard_license_more_information_link": "(plus de détails ici).", "hycu_dashboard_activation_license_success_message": "La demande d'activation de votre licence a bien été prise en compte. Votre fichier de licence sera bientôt disponible sur cette interface et vous sera également envoyé par e-mail.", - "hycu_dashboard_regenerate_success_message": "La demande d'activation de votre licence a bien été prise en compte. Votre fichier de licence sera bientôt disponible sur cette interface et vous sera également envoyé par e-mail.", + "hycu_dashboard_regenerate_success_message": "La demande de regénération de votre licence a bien été prise en compte. Votre fichier de licence sera bientôt disponible sur cette interface et vous sera également envoyé par e-mail.", "hycu_dashboard_activation_license_error_message": "Une erreur est survenue lors de la soumission de votre licence : {{error}}.", "hycu_dashboard_regenerate_error_message": "Une erreur est survenue lors de la soumission de votre licence.", "hycu_dashboard_license_regenerate_heading": "Regénérer la licence", @@ -36,10 +36,10 @@ "hycu_dashboard_upload_cancel": "Annuler", "hycu_dashboard_upload_confirm": "Activer", "hycu_dashboard_upload_file_too_big": "La taille du fichier ne peut pas excéder 1Mo", - "hycu_dashboard_upload_file_bad_type": "Le fichier fourni n'est pas un fichier .dat", + "hycu_dashboard_upload_file_bad_type": "Le fichier fourni n'est pas un fichier {{extension}}", "hycu_dashboard_upload_license_required": "Veuillez sélectionner une licence", "hycu_dashboard_drag_and_drop_attachment": "Glissez-Déposer une pièce jointe", - "hycu_dashboard_accepted_formats": "Format accepté: .dat", + "hycu_dashboard_accepted_formats": "Format accepté: {{extension}}", "hycu_dashboard_browse": "Parcourir", "hycu_dashboard_update_display_name_modal_headline": "Renommer la licence : {{serviceName}}", "hycu_dashboard_update_display_name_input_label": "Nom", diff --git a/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx b/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx index 7ff18a60eb2d..9350d402da0f 100644 --- a/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx +++ b/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx @@ -13,6 +13,7 @@ import { OsdsButton, OsdsIcon, OsdsText } from '@ovhcloud/ods-components/react'; import React, { ChangeEvent, useRef, useState } from 'react'; import { Controller, UseControllerProps } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; +import { LICENSE_FILE_EXT } from '@/constants'; const MAX_FILE_SIZE = 10e3; // 1 MB limit ~ @@ -35,10 +36,12 @@ export const FileInputField = ({ }); return; } - if (!file.name.endsWith('.dat')) { + if (!file.name.endsWith(LICENSE_FILE_EXT)) { setFileName(''); control.setError(name, { - message: t('hycu_dashboard_upload_file_bad_type'), + message: t('hycu_dashboard_upload_file_bad_type', { + extension: LICENSE_FILE_EXT, + }), }); return; } @@ -94,7 +97,7 @@ export const FileInputField = ({ data-testid="license-file-input" ref={fileInputRef} type="file" - accept=".dat" + accept={LICENSE_FILE_EXT} onChange={(e) => handleFileChange(e, onChange)} style={{ display: 'none' }} /> @@ -119,7 +122,9 @@ export const FileInputField = ({ {t('hycu_dashboard_drag_and_drop_attachment')} - {t('hycu_dashboard_accepted_formats')} + {t('hycu_dashboard_accepted_formats', { + extension: LICENSE_FILE_EXT, + })} } - header={header} - backLinkLabel={t('hycu_dashboard_back_link')} - onClickReturn={() => { - navigate(urls.listing); - }} - message={} - tabs={ - - - {tabsList.map((tab: DashboardTabItemProps) => ( - - - {tab.title} - - - ))} - - - } - > + <> + } + header={header} + backLinkLabel={t('hycu_dashboard_back_link')} + onClickReturn={() => { + navigate(urls.listing); + }} + message={} + tabs={ + + + {tabsList.map((tab: DashboardTabItemProps) => ( + + + {tab.title} + + + ))} + + + } + > -
    + ); } diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.spec.tsx index e19b6788fa5e..44a2548bc837 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.spec.tsx @@ -1,4 +1,4 @@ -import { Mock, vi } from 'vitest'; +import { vi } from 'vitest'; import { act, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { renderTestApp } from '@/utils/tests/renderTestApp'; @@ -12,7 +12,7 @@ const createFakeFile = () => { const blob = new Blob([content], { type: 'text/plain' }); // Convert the Blob to a File object - return new File([blob], 'license.dat', { + return new File([blob], 'license.req', { type: 'text/plain', lastModified: Date.now(), }); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.tsx index 4837a064304a..c9ac450da60f 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.tsx @@ -42,7 +42,7 @@ export const ActivationHycuLicenseModal: React.FC navigate('..'); - const { addSuccess, addError } = useNotifications(); + const { addInfo, addError } = useNotifications(); const link = useGuideUtils(); const { control, @@ -54,7 +54,7 @@ export const ActivationHycuLicenseModal: React.FC { - addSuccess(t('hycu_dashboard_activation_license_success_message'), true); + addInfo(t('hycu_dashboard_activation_license_success_message'), true); closeModal(); }, onError: (error: AxiosError<{ message: string }>) => { diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx index f5350ebc4a37..8b26b9b3e562 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx @@ -20,29 +20,29 @@ export default function EditHycuDisplayNameModal() { const invalidateCacheForLicense = useInvalidateCacheForALicenseHycu(); - const onClose = () => { + const closeModal = () => { navigate('..'); }; return ( { - navigate('..'); addSuccess( t('hycu_dashboard_update_display_name_success', { serviceName, }), ); + closeModal(); setTimeout(() => { invalidateCacheForLicense(serviceName); }, 2000); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.spec.tsx index b446e79f04b1..300342bbbf6c 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.spec.tsx @@ -12,7 +12,7 @@ const createFakeFile = () => { const blob = new Blob([content], { type: 'text/plain' }); // Convert the Blob to a File object - return new File([blob], 'license.dat', { + return new File([blob], 'license.req', { type: 'text/plain', lastModified: Date.now(), }); @@ -166,14 +166,13 @@ describe('License Hycu regenerate license route test suite', () => { await act(() => user.click(submitButton)); - expect( - screen.queryByText( - labels.dashboard.hycu_dashboard_upload_license_required, - ), - ).not.toBeInTheDocument(); - await waitFor( () => { + expect( + screen.queryByText( + labels.dashboard.hycu_dashboard_upload_license_required, + ), + ).not.toBeInTheDocument(); expect( screen.queryByText( labels.dashboard.hycu_dashboard_license_regenerate_description, diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.tsx index 5a549d630cd1..615490910b91 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.tsx @@ -37,7 +37,7 @@ export const RegenerateHycuLicenseModal: React.FC navigate('..'); - const { addSuccess, addError } = useNotifications(); + const { addInfo, addError } = useNotifications(); const { control, handleSubmit, @@ -48,7 +48,7 @@ export const RegenerateHycuLicenseModal: React.FC { - addSuccess(t('hycu_dashboard_regenerate_success_message'), true); + addInfo(t('hycu_dashboard_regenerate_success_message'), true); closeModal(); }, onError: () => { diff --git a/packages/manager/apps/hycu/src/pages/terminate/terminate-hycu.tsx b/packages/manager/apps/hycu/src/pages/terminate/terminate-hycu.tsx index 6758a7da4de8..ec643fe5da43 100644 --- a/packages/manager/apps/hycu/src/pages/terminate/terminate-hycu.tsx +++ b/packages/manager/apps/hycu/src/pages/terminate/terminate-hycu.tsx @@ -18,13 +18,13 @@ export const TerminateLicensePage = () => { }; const handleSuccessDelete = async () => { - addSuccess(t('hycu_terminate_success_message', { serviceName }), true); closeModal(); + addSuccess(t('hycu_terminate_success_message', { serviceName }), true); }; const handleErrorDelete = async (error: AxiosError) => { - addError(t('hycu_terminate_error_message', { error: error.message })); closeModal(); + addError(t('hycu_terminate_error_message', { error: error.message })); }; return ( From 1dc1f5294a18f5df768b6fad61214832c875f451 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Wed, 30 Oct 2024 12:47:52 +0100 Subject: [PATCH 25/43] feat(hycu): change pack wording ref: NTNX-1 Signed-off-by: Thibault Barske --- .../apps/hycu/public/translations/hycu/Messages_fr_FR.json | 2 +- .../hycu/public/translations/hycu/order/Messages_fr_FR.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json index 2af5c6f6460a..fe0fd5ec32d8 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json @@ -1,6 +1,6 @@ { "hycu_crumb": "HYCU", - "hycu_description": "Simplifiez vos sauvegardes, plans de reprise après sinistre et migrations de votre infrastructure Nutanix. Ce service vous propose différents packs de licences HYCU Hybrid Cloud pour protéger vos charges de travail Nutanix.", + "hycu_description": "Simplifiez vos sauvegardes, plans de reprise après sinistre et migrations de votre infrastructure Nutanix. Ce service vous propose différents packs de licences HYCU R-Cloud Hybrid Cloud Edition pour protéger vos charges de travail Nutanix.", "hycu_cloud_vm_pack_unknown": "Pack inconnu", "hycu_status_active": "Active", "hycu_status_toActivate": "À activer", diff --git a/packages/manager/apps/hycu/public/translations/hycu/order/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_fr_FR.json index f1e402e13f43..478afd731899 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/order/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_fr_FR.json @@ -1,8 +1,8 @@ { - "hycu_order_title": "Commander une licence HYCU Hybrid Cloud", - "hycu_order_description": "HYCU Hybrid Cloud est un logiciel de sauvegarde et de restauration spécialement conçu pour Nutanix. Nous vous proposons différents packs de licences selon le nombre de machines virtuelles (VM) utilisées par vos charges de travail Nutanix.", + "hycu_order_title": "Commander une licence HYCU R-Cloud Hybrid Cloud Edition", + "hycu_order_description": "HYCU R-Cloud Hybrid Cloud Edition est un logiciel de sauvegarde et de restauration spécialement conçu pour Nutanix. Nous vous proposons différents packs de licences selon le nombre de machines virtuelles (VM) utilisées par vos charges de travail Nutanix.", "hycu_order_subtitle": "Choisissez le type de pack", - "hycu_order_subtitle_description": "Sélectionnez le nombre de machines virtuelles (VM) à couvrir par la licence HYCU Hybrid Cloud. Veuillez noter qu'il vous sera impossible de sauvegarder plus de VM que le nombre prévu dans le pack. Si vous souhaitez protéger plus de 500 VM, merci de vous rapprocher de notre service commercial.", + "hycu_order_subtitle_description": "Sélectionnez le nombre de machines virtuelles (VM) à couvrir par la licence HYCU R-Cloud Hybrid Cloud Edition. Veuillez noter qu'il vous sera impossible de sauvegarder plus de VM que le nombre prévu dans le pack. Si vous souhaitez protéger plus de 500 VM, merci de vous rapprocher de notre service commercial.", "hycu_order_cta_cancel": "Annuler", "hycu_order_cta_order": "Commander", "hycu_order_initiated_title": "Commande de votre pack", From 52d7c5030423ec396c5d6ffb2318da11df2321b9 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Wed, 30 Oct 2024 12:49:01 +0100 Subject: [PATCH 26/43] fix(hycu): fix margin between tabs and dashboard content ref: MANAGER-14499 Signed-off-by: Thibault Barske --- packages/manager/apps/hycu/package.json | 1 + .../src/pages/dashboard/Dashboard.page.tsx | 53 ++--- .../DashboardGeneralInformation.page.tsx | 2 +- yarn.lock | 224 +++++++++++++----- 4 files changed, 199 insertions(+), 81 deletions(-) diff --git a/packages/manager/apps/hycu/package.json b/packages/manager/apps/hycu/package.json index eae8c67a74f6..d887f12f9989 100644 --- a/packages/manager/apps/hycu/package.json +++ b/packages/manager/apps/hycu/package.json @@ -48,6 +48,7 @@ "devDependencies": { "@cucumber/cucumber": "^10.3.1", "@ovh-ux/manager-vite-config": "^0.8.2", + "@ovh-ux/url-builder": "^1.3.0-alpha.0", "@testing-library/jest-dom": "^6.5.0", "@testing-library/react": "^16.0.1", "@testing-library/react-hooks": "^8.0.1", diff --git a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx index a9be2440f3a3..2a0e7bafb0fa 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx @@ -82,33 +82,32 @@ export default function DashboardPage() { } return ( - <> - } - header={header} - backLinkLabel={t('hycu_dashboard_back_link')} - onClickReturn={() => { - navigate(urls.listing); - }} - message={} - tabs={ - - - {tabsList.map((tab: DashboardTabItemProps) => ( - - - {tab.title} - - - ))} - - - } - > + } + header={header} + backLinkLabel={t('hycu_dashboard_back_link')} + onClickReturn={() => { + navigate(urls.listing); + }} + message={} + tabs={ + + + {tabsList.map((tab: DashboardTabItemProps) => ( + + + {tab.title} + + + ))} + + + } + > - + ); } diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/DashboardGeneralInformation.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/DashboardGeneralInformation.page.tsx index f6c2973aee8a..c6da174e55eb 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/DashboardGeneralInformation.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/DashboardGeneralInformation.page.tsx @@ -9,7 +9,7 @@ function GeneralInfos() { return ( <> -
    +
    diff --git a/yarn.lock b/yarn.lock index 621a0e38fb98..60825b0f65c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -792,11 +792,6 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz#d50e8d37b1176207b4fe9acedec386c565a44a54" integrity sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g== -"@babel/helper-string-parser@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c" - integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== - "@babel/helper-validator-identifier@^7.22.19", "@babel/helper-validator-identifier@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" @@ -812,11 +807,6 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz#77b7f60c40b15c97df735b38a66ba1d7c3e93da5" integrity sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg== -"@babel/helper-validator-identifier@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" - integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== - "@babel/helper-validator-option@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" @@ -948,20 +938,13 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.7.tgz#9a5226f92f0c5c8ead550b750f5608e766c8ce85" integrity sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw== -"@babel/parser@^7.25.4": +"@babel/parser@^7.25.4", "@babel/parser@^7.25.7": version "7.25.8" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.8.tgz#f6aaf38e80c36129460c1657c0762db584c9d5e2" integrity sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ== dependencies: "@babel/types" "^7.25.8" -"@babel/parser@^7.25.7": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.9.tgz#8fcaa079ac7458facfddc5cd705cc8005e4d3817" - integrity sha512-aI3jjAAO1fh7vY/pBGsn1i9LDbRP43+asrRlkPuTXW5yHXtd1NgTEMudbBoDDxrf1daEEfPJqR+JBMakzrR4Dg== - dependencies: - "@babel/types" "^7.25.9" - "@babel/parser@^7.7.0": version "7.10.3" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.3.tgz#7e71d892b0d6e7d04a1af4c3c79d72c1f10f5315" @@ -2103,7 +2086,7 @@ "@babel/helper-validator-identifier" "^7.24.7" to-fast-properties "^2.0.0" -"@babel/types@^7.25.4", "@babel/types@^7.25.8": +"@babel/types@^7.25.4", "@babel/types@^7.25.7", "@babel/types@^7.25.8": version "7.25.8" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.8.tgz#5cf6037258e8a9bcad533f4979025140cb9993e1" integrity sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg== @@ -2112,23 +2095,6 @@ "@babel/helper-validator-identifier" "^7.25.7" to-fast-properties "^2.0.0" -"@babel/types@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.7.tgz#1b7725c1d3a59f328cb700ce704c46371e6eef9b" - integrity sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ== - dependencies: - "@babel/helper-string-parser" "^7.25.7" - "@babel/helper-validator-identifier" "^7.25.7" - to-fast-properties "^2.0.0" - -"@babel/types@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.9.tgz#620f35ea1f4233df529ec9a2668d2db26574deee" - integrity sha512-OwS2CM5KocvQ/k7dFJa8i5bNGJP0hXWfVCfDkqRFP1IreH1JDC7wG6eCYCi0+McbfT8OR/kNqsI0UU0xP9H6PQ== - dependencies: - "@babel/helper-string-parser" "^7.25.9" - "@babel/helper-validator-identifier" "^7.25.9" - "@base2/pretty-print-object@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" @@ -9804,7 +9770,7 @@ strip-literal "^2.0.0" test-exclude "^6.0.0" -"@vitest/coverage-v8@^2.1.2", "@vitest/coverage-v8@^2.1.3": +"@vitest/coverage-v8@^2.1.2": version "2.1.3" resolved "https://registry.yarnpkg.com/@vitest/coverage-v8/-/coverage-v8-2.1.3.tgz#22d519e5e56385ec126305492f5a3cfe5b44b14d" integrity sha512-2OJ3c7UPoFSmBZwqD2VEkUw6A/tzPF0LmW0ZZhhB8PFxuc+9IBG/FaSM+RLEenc7ljzFvGN+G0nGQoZnh7sy2A== @@ -9822,6 +9788,24 @@ test-exclude "^7.0.1" tinyrainbow "^1.2.0" +"@vitest/coverage-v8@^2.1.3": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@vitest/coverage-v8/-/coverage-v8-2.1.4.tgz#c0df11cda12b3a04570e8065754917d35baa0c55" + integrity sha512-FPKQuJfR6VTfcNMcGpqInmtJuVXFSCd9HQltYncfR01AzXhLucMEtQ5SinPdZxsT5x/5BK7I5qFJ5/ApGCmyTQ== + dependencies: + "@ampproject/remapping" "^2.3.0" + "@bcoe/v8-coverage" "^0.2.3" + debug "^4.3.7" + istanbul-lib-coverage "^3.2.2" + istanbul-lib-report "^3.0.1" + istanbul-lib-source-maps "^5.0.6" + istanbul-reports "^3.1.7" + magic-string "^0.30.12" + magicast "^0.3.5" + std-env "^3.7.0" + test-exclude "^7.0.1" + tinyrainbow "^1.2.0" + "@vitest/expect@1.3.1": version "1.3.1" resolved "https://registry.npmjs.org/@vitest/expect/-/expect-1.3.1.tgz#d4c14b89c43a25fd400a6b941f51ba27fe0cb918" @@ -9869,6 +9853,16 @@ chai "^5.1.1" tinyrainbow "^1.2.0" +"@vitest/expect@2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-2.1.4.tgz#48f4f53a01092a3bdc118cff245f79ef388bdd8e" + integrity sha512-DOETT0Oh1avie/D/o2sgMHGrzYUFFo3zqESB2Hn70z6QB1HrS2IQ9z5DfyTqU8sg4Bpu13zZe9V4+UTNQlUeQA== + dependencies: + "@vitest/spy" "2.1.4" + "@vitest/utils" "2.1.4" + chai "^5.1.2" + tinyrainbow "^1.2.0" + "@vitest/mocker@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-2.1.3.tgz#a3593b426551be5715fa108faf04f8a9ddb0a9cc" @@ -9878,6 +9872,15 @@ estree-walker "^3.0.3" magic-string "^0.30.11" +"@vitest/mocker@2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-2.1.4.tgz#0dc07edb9114f7f080a0181fbcdb16cd4a2d855d" + integrity sha512-Ky/O1Lc0QBbutJdW0rqLeFNbuLEyS+mIPiNdlVlp2/yhJ0SbyYqObS5IHdhferJud8MbbwMnexg4jordE5cCoQ== + dependencies: + "@vitest/spy" "2.1.4" + estree-walker "^3.0.3" + magic-string "^0.30.12" + "@vitest/pretty-format@2.0.5", "@vitest/pretty-format@^2.0.5": version "2.0.5" resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.0.5.tgz#91d2e6d3a7235c742e1a6cc50e7786e2f2979b1e" @@ -9892,6 +9895,13 @@ dependencies: tinyrainbow "^1.2.0" +"@vitest/pretty-format@2.1.4", "@vitest/pretty-format@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.1.4.tgz#fc31993bdc1ef5a6c1a4aa6844e7ba55658a4f9f" + integrity sha512-L95zIAkEuTDbUX1IsjRl+vyBSLh3PwLLgKpghl37aCK9Jvw0iP+wKwIFhfjdUtA2myLgjrG6VU6JCFLv8q/3Ww== + dependencies: + tinyrainbow "^1.2.0" + "@vitest/runner@1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-1.4.0.tgz#907c2d17ad5975b70882c25ab7a13b73e5a28da9" @@ -9926,6 +9936,14 @@ "@vitest/utils" "2.1.3" pathe "^1.1.2" +"@vitest/runner@2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-2.1.4.tgz#f9346500bdd0be1c926daaac5d683bae87ceda2c" + integrity sha512-sKRautINI9XICAMl2bjxQM8VfCMTB0EbsBc/EDFA57V6UQevEKY/TOPOF5nzcvCALltiLfXWbq4MaAwWx/YxIA== + dependencies: + "@vitest/utils" "2.1.4" + pathe "^1.1.2" + "@vitest/snapshot@1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-1.4.0.tgz#2945b3fb53767a3f4f421919e93edfef2935b8bd" @@ -9962,16 +9980,18 @@ magic-string "^0.30.11" pathe "^1.1.2" -"@vitest/spy@1.3.1": - version "1.3.1" - resolved "https://registry.npmjs.org/@vitest/spy/-/spy-1.3.1.tgz#814245d46d011b99edd1c7528f5725c64e85a88b" - integrity sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig== +"@vitest/snapshot@2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-2.1.4.tgz#ef8c3f605fbc23a32773256d37d3fdfd9b23d353" + integrity sha512-3Kab14fn/5QZRog5BPj6Rs8dc4B+mim27XaKWFWHWA87R56AKjHTGcBFKpvZKDzC4u5Wd0w/qKsUIio3KzWW4Q== dependencies: - tinyspy "^2.2.0" + "@vitest/pretty-format" "2.1.4" + magic-string "^0.30.12" + pathe "^1.1.2" "@vitest/spy@1.3.1": version "1.3.1" - resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-1.3.1.tgz#814245d46d011b99edd1c7528f5725c64e85a88b" + resolved "https://registry.npmjs.org/@vitest/spy/-/spy-1.3.1.tgz#814245d46d011b99edd1c7528f5725c64e85a88b" integrity sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig== dependencies: tinyspy "^2.2.0" @@ -10004,6 +10024,13 @@ dependencies: tinyspy "^3.0.0" +"@vitest/spy@2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-2.1.4.tgz#4e90f9783437c5841a27c80f8fd84d7289a6100a" + integrity sha512-4JOxa+UAizJgpZfaCPKK2smq9d8mmjZVPMt2kOsg/R8QkoRzydHH1qHxIYNvr1zlEaFj4SXiaaJWxq/LPLKaLg== + dependencies: + tinyspy "^3.0.2" + "@vitest/ui@^1.4.0": version "1.6.0" resolved "https://registry.yarnpkg.com/@vitest/ui/-/ui-1.6.0.tgz#ffcc97ebcceca7fec840c29ab68632d0cd01db93" @@ -10066,6 +10093,15 @@ loupe "^3.1.1" tinyrainbow "^1.2.0" +"@vitest/utils@2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.1.4.tgz#6d67ac966647a21ce8bc497472ce230de3b64537" + integrity sha512-MXDnZn0Awl2S86PSNIim5PWXgIAx8CIkzu35mBdSApUip6RFOGXBCf3YFyeEu8n1IHk4bWD46DeYFu9mQlFIRg== + dependencies: + "@vitest/pretty-format" "2.1.4" + loupe "^3.1.2" + tinyrainbow "^1.2.0" + "@volar/language-core@1.11.1", "@volar/language-core@~1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@volar/language-core/-/language-core-1.11.1.tgz#ecdf12ea8dc35fb8549e517991abcbf449a5ad4f" @@ -12317,6 +12353,17 @@ chai@^5.1.1: loupe "^3.1.0" pathval "^2.0.0" +chai@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/chai/-/chai-5.1.2.tgz#3afbc340b994ae3610ca519a6c70ace77ad4378d" + integrity sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw== + dependencies: + assertion-error "^2.0.1" + check-error "^2.1.1" + deep-eql "^5.0.1" + loupe "^3.1.0" + pathval "^2.0.0" + chalk@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" @@ -13977,7 +14024,7 @@ debug@^3.1.0, debug@^3.2.7: dependencies: ms "^2.1.1" -debug@^4.3.5, debug@^4.3.6: +debug@^4.3.5, debug@^4.3.6, debug@^4.3.7: version "4.3.7" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== @@ -15836,6 +15883,11 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" +expect-type@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-1.1.0.tgz#a146e414250d13dfc49eafcfd1344a4060fa4c75" + integrity sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA== + expect@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/expect/-/expect-26.6.2.tgz#c6b996bf26bf3fe18b67b2d0f51fc981ba934417" @@ -21090,6 +21142,11 @@ loupe@^3.1.0, loupe@^3.1.1: dependencies: get-func-name "^2.0.1" +loupe@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.1.2.tgz#c86e0696804a02218f2206124c45d8b15291a240" + integrity sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg== + lower-case@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" @@ -21189,7 +21246,7 @@ magic-string@^0.30.10: dependencies: "@jridgewell/sourcemap-codec" "^1.5.0" -magic-string@^0.30.11: +magic-string@^0.30.11, magic-string@^0.30.12: version "0.30.12" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.12.tgz#9eb11c9d072b9bcb4940a5b2c2e1a217e4ee1a60" integrity sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw== @@ -21205,7 +21262,7 @@ magicast@^0.3.3: "@babel/types" "^7.23.6" source-map-js "^1.0.2" -magicast@^0.3.4: +magicast@^0.3.4, magicast@^0.3.5: version "0.3.5" resolved "https://registry.yarnpkg.com/magicast/-/magicast-0.3.5.tgz#8301c3c7d66704a0771eb1bad74274f0ec036739" integrity sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ== @@ -26700,7 +26757,16 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -26814,7 +26880,14 @@ stringify-entities@^3.0.0: character-entities-legacy "^1.0.0" xtend "^4.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -27542,7 +27615,7 @@ tinybench@^2.8.0, tinybench@^2.9.0: resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.9.0.tgz#103c9f8ba6d7237a47ab6dd1dcff77251863426b" integrity sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg== -tinyexec@^0.3.0: +tinyexec@^0.3.0, tinyexec@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-0.3.1.tgz#0ab0daf93b43e2c211212396bdb836b468c97c98" integrity sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ== @@ -27557,7 +27630,7 @@ tinypool@^0.8.3: resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-0.8.4.tgz#e217fe1270d941b39e98c625dcecebb1408c9aa8" integrity sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ== -tinypool@^1.0.0: +tinypool@^1.0.0, tinypool@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-1.0.1.tgz#c64233c4fac4304e109a64340178760116dbe1fe" integrity sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA== @@ -27572,7 +27645,7 @@ tinyspy@^2.2.0: resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-2.2.0.tgz#9dc04b072746520b432f77ea2c2d17933de5d6ce" integrity sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg== -tinyspy@^3.0.0: +tinyspy@^3.0.0, tinyspy@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-3.0.2.tgz#86dd3cf3d737b15adcf17d7887c84a75201df20a" integrity sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q== @@ -28947,6 +29020,16 @@ vite-node@2.1.3: pathe "^1.1.2" vite "^5.0.0" +vite-node@2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-2.1.4.tgz#97ffb6de913fd8d42253afe441f9512e9dbdfd5c" + integrity sha512-kqa9v+oi4HwkG6g8ufRnb5AeplcRw8jUF6/7/Qz1qRQOXHImG8YnLbB+LLszENwFnoBl9xIf9nVdCFzNd7GQEg== + dependencies: + cac "^6.7.14" + debug "^4.3.7" + pathe "^1.1.2" + vite "^5.0.0" + vite-plugin-dts@3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/vite-plugin-dts/-/vite-plugin-dts-3.5.1.tgz#58c225f7ecabff2ed76027e003e1ec8ca964a078" @@ -29153,7 +29236,7 @@ vitest@^2.0.5: vite-node "2.0.5" why-is-node-running "^2.3.0" -vitest@^2.1.2, vitest@^2.1.3: +vitest@^2.1.2: version "2.1.3" resolved "https://registry.yarnpkg.com/vitest/-/vitest-2.1.3.tgz#dae1055dd328621b59fc6e594fd988fbf2e5370e" integrity sha512-Zrxbg/WiIvUP2uEzelDNTXmEMJXuzJ1kCpbDvaKByFA9MNeO95V+7r/3ti0qzJzrxdyuUw5VduN7k+D3VmVOSA== @@ -29178,6 +29261,32 @@ vitest@^2.1.2, vitest@^2.1.3: vite-node "2.1.3" why-is-node-running "^2.3.0" +vitest@^2.1.3: + version "2.1.4" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-2.1.4.tgz#ba8f4589fb639cf5a9e6af54781667312b3e8230" + integrity sha512-eDjxbVAJw1UJJCHr5xr/xM86Zx+YxIEXGAR+bmnEID7z9qWfoxpHw0zdobz+TQAFOLT+nEXz3+gx6nUJ7RgmlQ== + dependencies: + "@vitest/expect" "2.1.4" + "@vitest/mocker" "2.1.4" + "@vitest/pretty-format" "^2.1.4" + "@vitest/runner" "2.1.4" + "@vitest/snapshot" "2.1.4" + "@vitest/spy" "2.1.4" + "@vitest/utils" "2.1.4" + chai "^5.1.2" + debug "^4.3.7" + expect-type "^1.1.0" + magic-string "^0.30.12" + pathe "^1.1.2" + std-env "^3.7.0" + tinybench "^2.9.0" + tinyexec "^0.3.1" + tinypool "^1.0.1" + tinyrainbow "^1.2.0" + vite "^5.0.0" + vite-node "2.1.4" + why-is-node-running "^2.3.0" + void-elements@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" @@ -29655,7 +29764,7 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -29681,6 +29790,15 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From 8ca2537290cfd03902d80e691b8f6b0ee6ef6976 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Wed, 30 Oct 2024 22:24:46 +0100 Subject: [PATCH 27/43] feat(hycu): fix hycu license format file ref: MANAGER-15874 Signed-off-by: Thibault Barske --- .../components/FileUpload/FileUpload.component.tsx | 2 +- packages/manager/apps/hycu/src/constants.ts | 2 +- .../serviceLicenseHycu/serviceLicenseHycu.data.ts | 2 +- .../ActivationLicenseModal.page.spec.tsx | 5 +---- .../ActivationLicenseModal.page.tsx | 6 +----- .../RegenerateLicenseModal.page.spec.tsx | 11 ++--------- .../RegenerateLicenseModal.page.tsx | 6 +----- 7 files changed, 8 insertions(+), 26 deletions(-) diff --git a/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx b/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx index 9350d402da0f..041808af381a 100644 --- a/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx +++ b/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx @@ -29,6 +29,7 @@ export const FileInputField = ({ const parseFile = async (file: File, onChange: (result: string) => void) => { onChange(undefined); + control.setError(name, undefined); if (file.size > MAX_FILE_SIZE) { setFileName(''); control.setError(name, { @@ -54,7 +55,6 @@ export const FileInputField = ({ ); onChange(base64String); setFileName(file.name); - control.setError(name, undefined); }; reader.readAsDataURL(file); }; diff --git a/packages/manager/apps/hycu/src/constants.ts b/packages/manager/apps/hycu/src/constants.ts index 105910700fe9..278e25a9f961 100644 --- a/packages/manager/apps/hycu/src/constants.ts +++ b/packages/manager/apps/hycu/src/constants.ts @@ -9,4 +9,4 @@ export const packTypeLabel = { } as const; export const LICENSE_FILE_EXT = '.req'; -export const LICENSE_FILE_NAME_TEMPLATE = `license-hycu-{serviceName}.${LICENSE_FILE_EXT}`; +export const LICENSE_FILE_NAME_TEMPLATE = `license-hycu-{serviceName}.dat`; diff --git a/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.data.ts b/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.data.ts index 40aa4f70141d..0f08bca14a08 100644 --- a/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.data.ts +++ b/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.data.ts @@ -19,7 +19,7 @@ export const licensesHycuService: ServiceDetails = { invoiceName: 'HYCU Hybrid Cloud - 25 VMs', }, pricing: { - capacities: 'renew', + capacities: ['renew'], description: 'rental for 1 month', interval: 1, duration: 'P1M', diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.spec.tsx index 44a2548bc837..4a2251c50a14 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.spec.tsx @@ -68,11 +68,8 @@ describe('License Hycu activate license route test suite', () => { ); const submitButton = screen.getByTestId('hycu-dashboard-upload-confirm'); - await act(() => user.click(submitButton)); - expect( - screen.getByText(labels.dashboard.hycu_dashboard_upload_license_required), - ).toBeVisible(); + expect(submitButton).toHaveAttribute('disabled'); }); it('should call mutate when form valid and submitted', async () => { diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.tsx index c9ac450da60f..aaa556e80f02 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/activation-license-modal/ActivationLicenseModal.page.tsx @@ -117,11 +117,7 @@ export const ActivationHycuLicenseModal: React.FC { const submitButton = screen.getByTestId( 'hycu-dashboard-regenerate-upload-confirm', ); - await act(() => user.click(submitButton)); - expect( - screen.getByText(labels.dashboard.hycu_dashboard_upload_license_required), - ).toBeVisible(); + expect(submitButton).toHaveAttribute('disabled'); }); it('should call mutate when form valid and submitted', async () => { @@ -168,11 +165,7 @@ describe('License Hycu regenerate license route test suite', () => { await waitFor( () => { - expect( - screen.queryByText( - labels.dashboard.hycu_dashboard_upload_license_required, - ), - ).not.toBeInTheDocument(); + expect(submitButton).toHaveAttribute('disabled'); expect( screen.queryByText( labels.dashboard.hycu_dashboard_license_regenerate_description, diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.tsx index 615490910b91..91a65959979c 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.tsx @@ -95,11 +95,7 @@ export const RegenerateHycuLicenseModal: React.FC Date: Thu, 31 Oct 2024 08:39:07 +0100 Subject: [PATCH 28/43] feat(hycu): change edit name header wording ref: MANAGER-14499 Signed-off-by: Thibault Barske --- .../public/translations/hycu/dashboard/Messages_fr_FR.json | 2 +- .../edit-display-name/EditHycuDisplayName.page.tsx | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json index cc7937400ab9..1b45ae5e40ad 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json @@ -41,7 +41,7 @@ "hycu_dashboard_drag_and_drop_attachment": "Glissez-Déposer une pièce jointe", "hycu_dashboard_accepted_formats": "Format accepté: {{extension}}", "hycu_dashboard_browse": "Parcourir", - "hycu_dashboard_update_display_name_modal_headline": "Renommer la licence : {{serviceName}}", + "hycu_dashboard_update_display_name_modal_headline": "Modifier le nom", "hycu_dashboard_update_display_name_input_label": "Nom", "hycu_dashboard_update_display_name_description": "", "hycu_dashboard_update_display_name_pattern_message": "Veuillez saisir un nom dont la longueur est comprise entre 1 et 32 caractères.", diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx index 8b26b9b3e562..6534daac28a7 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx @@ -27,9 +27,7 @@ export default function EditHycuDisplayNameModal() { return ( Date: Sun, 3 Nov 2024 22:43:59 +0100 Subject: [PATCH 29/43] feat(billing-component): add resiliation agora service for HYCU ref: MANAGER-15890 Signed-off-by: Thibault Barske --- .../components/services-actions/service-actions.constants.js | 1 + .../services-actions/services-actions.controller.js | 1 + .../services-actions/translations/Messages_fr_FR.json | 1 + .../terminate-agora-service/translations/Messages_fr_FR.json | 4 ++++ 4 files changed, 7 insertions(+) diff --git a/packages/manager/modules/billing-components/src/components/services-actions/service-actions.constants.js b/packages/manager/modules/billing-components/src/components/services-actions/service-actions.constants.js index d790b464760b..c02ae82f7fe5 100644 --- a/packages/manager/modules/billing-components/src/components/services-actions/service-actions.constants.js +++ b/packages/manager/modules/billing-components/src/components/services-actions/service-actions.constants.js @@ -4,6 +4,7 @@ export const SERVICE_TYPE = { EXCHANGE: 'EMAIL_EXCHANGE', HOSTING_PRIVATE_DATABASE: 'HOSTING_PRIVATE_DATABASE', HOSTING_WEB: 'HOSTING_WEB', + LICENSE_HYCU: 'LICENSE_HYCU', OVH_CLOUD_CONNECT: 'OVH_CLOUD_CONNECT', PACK_XDSL: 'PACK_XDSL', SMS: 'SMS', diff --git a/packages/manager/modules/billing-components/src/components/services-actions/services-actions.controller.js b/packages/manager/modules/billing-components/src/components/services-actions/services-actions.controller.js index 0fc02e097fd9..363e873f6221 100644 --- a/packages/manager/modules/billing-components/src/components/services-actions/services-actions.controller.js +++ b/packages/manager/modules/billing-components/src/components/services-actions/services-actions.controller.js @@ -116,6 +116,7 @@ export default class ServicesActionsCtrl { break; case SERVICE_TYPE.OKMS: case SERVICE_TYPE.VRACK_SERVICES: + case SERVICE_TYPE.LICENSE_HYCU: this.resiliateLink = `${this.autorenewLink}/terminate-service?id=${this.service.id}${serviceTypeParam}`; break; default: diff --git a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_fr_FR.json b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_fr_FR.json index 219001192e19..0cdbedd4c1a0 100644 --- a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_fr_FR.json +++ b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_fr_FR.json @@ -15,6 +15,7 @@ "billing_services_actions_menu_resiliate_HOSTING_WEB": "Supprimer immédiatement l'hébergement", "billing_services_actions_menu_resiliate_HOSTING_PRIVATE_DATABASE": "Supprimer mon hébergement SQL privé", "billing_services_actions_menu_resiliate_WEBCOACH": "Supprimer mon WebCoach", + "billing_services_actions_menu_resiliate_LICENSE_HYCU": "Supprimer ma license Hycu", "billing_services_actions_menu_sms_credit": "Ajouter des crédits", "billing_services_actions_menu_sms_renew": "Configurer la recharge automatique", "billing_services_actions_menu_resiliate_cancel": "Annuler la résiliation du service", diff --git a/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_fr_FR.json b/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_fr_FR.json index 538233fa726b..93ad21923a09 100644 --- a/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_fr_FR.json +++ b/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_fr_FR.json @@ -1,10 +1,14 @@ { + "autorenew_agora_terminate_service_LICENSE_HYCU": "Résilier ma licence HYCU", "autorenew_agora_terminate_service_OKMS_RESOURCE": "Résilier mon KMS", "autorenew_agora_terminate_service_VRACK_SERVICES_RESOURCE": "Résilier vRack Services", + "autorenew_agora_terminate_service_warning_LICENSE_HYCU": "Veuillez confirmer la résiliation de votre licence HYCU", "autorenew_agora_terminate_service_warning_OKMS_RESOURCE": "Veuillez confirmer la résiliation de votre KMS", "autorenew_agora_terminate_service_warning_VRACK_SERVICES_RESOURCE": "Veuillez confirmer la résiliation de vRAck Services", + "autorenew_agora_terminate_service_success_LICENSE_HYCU": "Votre demande de résiliation de votre licence HYCU a été prise en compte. Un e-mail contenant la procédure vous a été envoyé.", "autorenew_agora_terminate_service_success_OKMS_RESOURCE": "Votre demande de résiliation de votre KMS a été prise en compte. Un e-mail contenant la procédure vous a été envoyé.", "autorenew_agora_terminate_service_success_VRACK_SERVICES_RESOURCE": "Votre demande de résiliation de vRAck Services a été prise en compte. Un e-mail contenant la procédure vous a été envoyé.", + "autorenew_agora_terminate_service_error_LICENSE_HYCU": "Une erreur est survenue lors de la demande de résiliation de votre licence HYCU. {{error}}", "autorenew_agora_terminate_service_error_OKMS_RESOURCE": "Une erreur est survenue lors de la demande de résiliation de votre KMS. {{error}}", "autorenew_agora_terminate_service_DBAAS_LOGS": "Résilier mon LDP", "autorenew_agora_terminate_service_warning_DBAAS_LOGS": "Veuillez confirmer la résiliation de votre LDP", From 58883b6a55bb8d108b145bd89aaf9654c24a8307 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Sun, 3 Nov 2024 22:46:33 +0100 Subject: [PATCH 30/43] feat(hycu): remove manage contact url ref: MANAGER-15895 Signed-off-by: Thibault Barske --- .../BillingInformationsTile.tsx | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx index b75068884347..aeb0b957dacf 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx @@ -37,15 +37,6 @@ const BillingInformationsTile = ({ serviceName }: { serviceName: string }) => { format: DateFormat.display, }); - const { - data: contactUrl, - isLoading: isContactUrlLoading, - } = useNavigationGetUrl([ - 'dedicated', - '#/contacts/services', - { serviceName }, - ]); - const { data: renewUrl, isLoading: isRenewUrlLoading } = useNavigationGetUrl([ 'dedicated', '#/billing/autorenew', @@ -103,24 +94,6 @@ const BillingInformationsTile = ({ serviceName }: { serviceName: string }) => { )}`} ))}
    - -
    - - {t('hycu_dashboard_field_label_manage_contacts')} - - - - -
    ), }, From 797bf39c0a99a44f05731377a164999303542fee Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Sun, 3 Nov 2024 22:51:16 +0100 Subject: [PATCH 31/43] feat(hycu): change name rules for license hycu ref: MANAGER-15889 Signed-off-by: Thibault Barske --- .../public/translations/hycu/dashboard/Messages_fr_FR.json | 2 +- .../edit-display-name/EditHycuDisplayName.page.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json index 1b45ae5e40ad..18d1602a96e3 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json @@ -44,7 +44,7 @@ "hycu_dashboard_update_display_name_modal_headline": "Modifier le nom", "hycu_dashboard_update_display_name_input_label": "Nom", "hycu_dashboard_update_display_name_description": "", - "hycu_dashboard_update_display_name_pattern_message": "Veuillez saisir un nom dont la longueur est comprise entre 1 et 32 caractères.", + "hycu_dashboard_update_display_name_pattern_message": "Veuillez utiliser uniquement des lettres sans accent et les caractères spéciaux suivants : ! @ # $ % ^ & * ( ) - _ + = [ ] { } ; : , . ? (limité à 36 caractères).", "hycu_dashboard_update_display_name_success": "La description a été modifiée avec succès.", "hycu_dashboard_edit_modal_error": "Une erreur est survenue: {{error}}.", "hycu_dashboard_error_license_message": "Une erreur est survenue lors de l'activation de votre licence ({{error}}). Nous vous invitons à vérifier les informations fournies et à réaliser une nouvelle tentative. Si le problème persiste, veuillez contacter notre support." diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx index 6534daac28a7..a8feeb543e6a 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx @@ -30,9 +30,9 @@ export default function EditHycuDisplayNameModal() { headline={t('hycu_dashboard_update_display_name_modal_headline')} inputLabel={t('hycu_dashboard_update_display_name_input_label')} description={t('hycu_dashboard_update_display_name_description')} - resourceName={serviceDetails?.data?.resource?.displayName} + resourceName={serviceName} isLoading={isLoading} - pattern="^(\S| |\-){0,32}$" + pattern="^[\x00-\x7F]{1,36}$" patternMessage={t('hycu_dashboard_update_display_name_pattern_message')} onSuccess={() => { addSuccess( From 83d5c3f209d8baf458b32766113bdcc8e7d5918f Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Sun, 3 Nov 2024 22:51:55 +0100 Subject: [PATCH 32/43] feat(hycu): show display name instead servicename on listing page ref: MANAGER-15878 Signed-off-by: Thibault Barske --- packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx index 3d19fd76d770..767ec7fc11ef 100644 --- a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx +++ b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx @@ -50,7 +50,7 @@ const DatagridIdCell = (hycuDetail: IHycuDetails) => { ), ) } - label={hycuDetail.serviceName} + label={hycuDetail?.iam.serviceName ?? hycuDetail.serviceName} > ); From 8825e79629e31afc67ecc6b3f341ca1786b1f4ba Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Mon, 4 Nov 2024 00:14:58 +0100 Subject: [PATCH 33/43] feat(hycu): disabled action when service is suspended ref: MANAGER-15877 Signed-off-by: Thibault Barske --- .../hycu/dashboard/Messages_fr_FR.json | 3 +- .../ManagerLink/ManagerLink.component.tsx | 5 +- packages/manager/apps/hycu/src/mocks/index.ts | 1 - .../serviceLicenseHycu.data.ts | 2 +- .../serviceLicenseHycu/serviceLicenseHycu.ts | 25 ---- .../pages/dashboard/Dashboard.page.spec.tsx | 50 +++++++- .../src/pages/dashboard/Dashboard.page.tsx | 9 +- .../BillingInformationsTile.tsx | 35 +++--- .../GeneralInformationsTile.tsx | 7 +- .../ShortcutsTile/ShortcutsTile.tsx | 117 ++++++++++-------- .../ActivationLicenseModal.page.spec.tsx | 2 +- .../RegenerateLicenseModal.page.spec.tsx | 2 +- .../listing/menu/HycuActionMenu.component.tsx | 11 +- .../hycu/src/utils/tests/renderTestApp.tsx | 13 +- 14 files changed, 170 insertions(+), 112 deletions(-) delete mode 100644 packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.ts diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json index 18d1602a96e3..0fa47ef96733 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json @@ -47,5 +47,6 @@ "hycu_dashboard_update_display_name_pattern_message": "Veuillez utiliser uniquement des lettres sans accent et les caractères spéciaux suivants : ! @ # $ % ^ & * ( ) - _ + = [ ] { } ; : , . ? (limité à 36 caractères).", "hycu_dashboard_update_display_name_success": "La description a été modifiée avec succès.", "hycu_dashboard_edit_modal_error": "Une erreur est survenue: {{error}}.", - "hycu_dashboard_error_license_message": "Une erreur est survenue lors de l'activation de votre licence ({{error}}). Nous vous invitons à vérifier les informations fournies et à réaliser une nouvelle tentative. Si le problème persiste, veuillez contacter notre support." + "hycu_dashboard_error_license_message": "Une erreur est survenue lors de l'activation de votre licence ({{error}}). Nous vous invitons à vérifier les informations fournies et à réaliser une nouvelle tentative. Si le problème persiste, veuillez contacter notre support.", + "hycu_dashboard_warning_license_suspended_message": "Le service a été résilié." } diff --git a/packages/manager/apps/hycu/src/components/ManagerLink/ManagerLink.component.tsx b/packages/manager/apps/hycu/src/components/ManagerLink/ManagerLink.component.tsx index 43a57f0c9e27..4456ea74ea60 100644 --- a/packages/manager/apps/hycu/src/components/ManagerLink/ManagerLink.component.tsx +++ b/packages/manager/apps/hycu/src/components/ManagerLink/ManagerLink.component.tsx @@ -20,16 +20,17 @@ export const ManagerLink = ({ urn, displayTooltip = true, isIamTrigger = true, + disabled, ...restProps }: ManagerLinkProps) => { const { t } = useTranslation('hycu'); const { isAuthorized } = useAuthorizationIam(iamActions, urn, isIamTrigger); - if (isAuthorized || iamActions === undefined) { + if (!disabled && (isAuthorized || iamActions === undefined)) { return {children}; } - return !displayTooltip ? ( + return !displayTooltip || disabled ? ( {children} diff --git a/packages/manager/apps/hycu/src/mocks/index.ts b/packages/manager/apps/hycu/src/mocks/index.ts index 9f1d845c7ee4..e42f84434767 100644 --- a/packages/manager/apps/hycu/src/mocks/index.ts +++ b/packages/manager/apps/hycu/src/mocks/index.ts @@ -1,3 +1,2 @@ export * from './licenseHycu/licenseHycu'; -export * from './serviceLicenseHycu/serviceLicenseHycu'; export * from './catalogHycu/catalogHycu'; diff --git a/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.data.ts b/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.data.ts index 0f08bca14a08..62df588c40ad 100644 --- a/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.data.ts +++ b/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.data.ts @@ -1,4 +1,4 @@ -import { CurrencyCode, ServiceDetails } from '@ovh-ux/manager-react-components'; +import { ServiceDetails, CurrencyCode } from '@ovh-ux/manager-react-components'; export const licensesHycuService: ServiceDetails = { route: { diff --git a/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.ts b/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.ts deleted file mode 100644 index 27ea5e1218e6..000000000000 --- a/packages/manager/apps/hycu/src/mocks/serviceLicenseHycu/serviceLicenseHycu.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { LicenseStatus } from '@/types/hycu.details.interface'; -import { Handler } from '../../../../../../../playwright-helpers'; -import { licensesHycuService } from './serviceLicenseHycu.data'; - -export type GetServiceLicenseHycuMocksParams = { - isGetServiceLicenseHycuKo?: boolean; - licenseStatus?: LicenseStatus; -}; - -export const getServiceLicenseHycuMocks = ({ - isGetServiceLicenseHycuKo, -}: GetServiceLicenseHycuMocksParams): Handler[] => { - return [ - { - url: 'services/:id', - response: isGetServiceLicenseHycuKo - ? { - message: 'Backup error', - } - : licensesHycuService, - status: isGetServiceLicenseHycuKo ? 500 : 200, - api: 'v6', - }, - ]; -}; diff --git a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.spec.tsx index 25b14fa90f82..48fc82686fba 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.spec.tsx @@ -2,6 +2,9 @@ import { screen, waitFor } from '@testing-library/react'; import { renderTestApp } from '@/utils/tests/renderTestApp'; import '@testing-library/jest-dom'; import { licensesHycu } from '@/mocks/licenseHycu/licenseHycu.data'; +import { LicenseStatus } from '@/types/hycu.details.interface'; +import { labels } from '@/utils/tests/init.i18n'; +import { licensesHycuService } from '@/mocks/serviceLicenseHycu/serviceLicenseHycu.data'; describe('License Hycu Dashboard route test suite', () => { it('should show informations of services', async () => { @@ -22,11 +25,56 @@ describe('License Hycu Dashboard route test suite', () => { await renderTestApp(`/${licensesHycu[0].serviceName}`, { getServicesKo: true, isGetLicenseHycuKo: true, - isGetServiceLicenseHycuKo: true, + getDetailsServicesKo: true, }); await waitFor(() => expect(screen.getByAltText('OOPS')).toBeVisible(), { timeout: 30_000, }); }); + + it('should show error if license activation is in error', async () => { + await renderTestApp(`/${licensesHycu[0].serviceName}`, { + licenseStatus: LicenseStatus.ERROR, + }); + + await waitFor( + () => + expect( + screen.getByText( + labels.dashboard.hycu_dashboard_error_license_message.replace( + '{{error}}', + '', + ), + ), + ).toBeVisible(), + { + timeout: 30_000, + }, + ); + }); + + it('should show info if service is suspended', async () => { + await renderTestApp(`/${licensesHycu[0].serviceName}`, { + serviceResponse: { + ...licensesHycuService, + resource: { + ...licensesHycuService.resource, + ...{ state: 'suspended' }, + }, + }, + }); + + await waitFor( + () => + expect( + screen.getByText( + labels.dashboard.hycu_dashboard_warning_license_suspended_message, + ), + ).toBeVisible(), + { + timeout: 30_000, + }, + ); + }); }); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx index 2a0e7bafb0fa..53108b55ed4c 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx @@ -40,7 +40,7 @@ export default function DashboardPage() { const { serviceName } = useParams(); const navigate = useNavigate(); const { t } = useTranslation('hycu/dashboard'); - const { addError, clearNotifications } = useNotifications(); + const { addError, addWarning, clearNotifications } = useNotifications(); const { data: licenseHycu } = useDetailsLicenseHYCU(serviceName); const { data: serviceDetails, error } = useServiceDetails({ @@ -48,7 +48,10 @@ export default function DashboardPage() { }); useEffect(() => { - if (licenseHycu?.data.licenseStatus === LicenseStatus.ERROR) { + if (serviceDetails?.data.resource.state === 'suspended') { + clearNotifications(); + addWarning(t('hycu_dashboard_warning_license_suspended_message')); + } else if (licenseHycu?.data.licenseStatus === LicenseStatus.ERROR) { clearNotifications(); addError( t('hycu_dashboard_error_license_message', { @@ -56,7 +59,7 @@ export default function DashboardPage() { }), ); } - }, [licenseHycu]); + }, [licenseHycu, serviceDetails]); const tabsList = [ { diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx index aeb0b957dacf..c742cd18a5cd 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/BillingInformations/BillingInformationsTile.tsx @@ -76,6 +76,24 @@ const BillingInformationsTile = ({ serviceName }: { serviceName: string }) => { {creationDate} ), }, + { + id: 'link_terminated', + value: ( + +
    +
    {t('hycu_dashboard_link_terminate')}
    + +
    +
    + ), + }, { id: 'contact', label: t('hycu_dashboard_field_label_contacts'), @@ -97,23 +115,6 @@ const BillingInformationsTile = ({ serviceName }: { serviceName: string }) => {
    ), }, - { - id: 'link_terminated', - value: ( - -
    -
    {t('hycu_dashboard_link_terminate')}
    - -
    -
    - ), - }, ]} > ); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx index b9ff4eaf1910..388de427684d 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/GeneralInformationsTiles/GeneralInformationsTile.tsx @@ -8,7 +8,6 @@ import { OsdsIcon, OsdsButton, OsdsSkeleton, - OsdsLink, } from '@ovhcloud/ods-components/react'; import { ODS_BUTTON_SIZE, @@ -99,10 +98,14 @@ const GeneralInformationsTile = ({ serviceName }: { serviceName: string }) => { ( const ShortcutsTile = ({ serviceName }: { serviceName: string }) => { const navigate = useNavigate(); const { data: hycuDetail } = useDetailsLicenseHYCU(serviceName); + const { data: serviceDetails } = useServiceDetails({ + resourceName: serviceName, + }); const { t } = useTranslation('hycu/dashboard'); - const links = { - linkActivated: { - id: 'link_activated', - value: ( - { - navigate( - urls.activateLicense.replace(subRoutes.serviceName, serviceName), - ); - }} - > - {t('hycu_dashboard_link_activate')} - - ), - }, - linkReactivated: { - id: 'link_regenerate', - value: ( - { - navigate( - urls.regenerateLicense.replace( - subRoutes.serviceName, - serviceName, - ), - ); - }} - > - {t('hycu_dashboard_link_regenerate')} - - ), - }, - linkChangePackType: { - id: 'link_change_pack_type', - value: ( - - {t('hycu_dashboard_link_change_pack_type')} - - ), - }, - } as const; + const isServiceSuspended = useMemo( + () => serviceDetails?.data.resource.state === 'suspended', + [serviceDetails], + ); + + const links = useMemo( + () => ({ + linkActivated: { + id: 'link_activated', + value: ( + { + navigate( + urls.activateLicense.replace( + subRoutes.serviceName, + serviceName, + ), + ); + }} + > + {t('hycu_dashboard_link_activate')} + + ), + }, + linkReactivated: { + id: 'link_regenerate', + value: ( + { + navigate( + urls.regenerateLicense.replace( + subRoutes.serviceName, + serviceName, + ), + ); + }} + > + {t('hycu_dashboard_link_regenerate')} + + ), + }, + linkChangePackType: { + id: 'link_change_pack_type', + value: ( + + {t('hycu_dashboard_link_change_pack_type')} + + ), + }, + }), + [isServiceSuspended, hycuDetail], + ); return ( { await renderTestApp(`/${licensesHycu[0].serviceName}/activate-license`, { getServicesKo: true, isGetLicenseHycuKo: true, - isGetServiceLicenseHycuKo: true, + getDetailsServicesKo: true, }); await waitFor(() => expect(screen.getByAltText('OOPS')).toBeVisible(), { diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.spec.tsx index d61d0661fafa..11de882312fd 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/regenerate-license-modal/RegenerateLicenseModal.page.spec.tsx @@ -47,7 +47,7 @@ describe('License Hycu regenerate license route test suite', () => { await renderTestApp(`/${licensesHycu[0].serviceName}/regenerate-license`, { getServicesKo: true, isGetLicenseHycuKo: true, - isGetServiceLicenseHycuKo: true, + getDetailsServicesKo: true, }); await waitFor(() => expect(screen.getByAltText('OOPS')).toBeVisible(), { diff --git a/packages/manager/apps/hycu/src/pages/listing/menu/HycuActionMenu.component.tsx b/packages/manager/apps/hycu/src/pages/listing/menu/HycuActionMenu.component.tsx index d7f89d40c1af..1b758a0071fb 100644 --- a/packages/manager/apps/hycu/src/pages/listing/menu/HycuActionMenu.component.tsx +++ b/packages/manager/apps/hycu/src/pages/listing/menu/HycuActionMenu.component.tsx @@ -1,4 +1,8 @@ -import { ActionMenu, ActionMenuItem } from '@ovh-ux/manager-react-components'; +import { + ActionMenu, + ActionMenuItem, + useServiceDetails, +} from '@ovh-ux/manager-react-components'; import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; import { useNavigate } from 'react-router-dom'; import React from 'react'; @@ -14,6 +18,9 @@ const HycuActionMenu = ({ serviceName }: Pick) => { navigate( urls.listing_terminate.replace(subRoutes.serviceName, serviceName), ); + const { data: serviceDetails } = useServiceDetails({ + resourceName: serviceName, + }); const items: ActionMenuItem[] = [ { @@ -21,6 +28,8 @@ const HycuActionMenu = ({ serviceName }: Pick) => { label: t('hycu_service_listing_terminate'), color: ODS_THEME_COLOR_INTENT.error, onClick: openTerminateModal, + disabled: + serviceDetails?.data.resource.state === 'suspended' || undefined, }, ]; diff --git a/packages/manager/apps/hycu/src/utils/tests/renderTestApp.tsx b/packages/manager/apps/hycu/src/utils/tests/renderTestApp.tsx index 14a0ccf4610e..1ada82284418 100644 --- a/packages/manager/apps/hycu/src/utils/tests/renderTestApp.tsx +++ b/packages/manager/apps/hycu/src/utils/tests/renderTestApp.tsx @@ -20,10 +20,9 @@ import { getCatalogHycuMocks, getLicenseHycuMocks, GetLicenseHycuMocksParams, - getServiceLicenseHycuMocks, - GetServiceLicenseHycuMocksParams, } from '@/mocks'; import { getIamMocks } from '@/mocks/iam/iam.handler'; +import { licensesHycuService } from '@/mocks/serviceLicenseHycu/serviceLicenseHycu.data'; let context: ShellContextType; let i18nValue: i18n; @@ -32,17 +31,17 @@ export const renderTestApp = async ( initialRoute = '/', mockParams: GetServicesMocksParams & GetLicenseHycuMocksParams & - GetServicesMocksParams & - CatalogHycuMocksParams & - GetServiceLicenseHycuMocksParams = {}, + CatalogHycuMocksParams = {}, ) => { global.server?.resetHandlers( ...toMswHandlers([ ...getAuthenticationMocks({ isAuthMocked: true }), ...getIamMocks(), ...getLicenseHycuMocks(mockParams), - ...getServiceLicenseHycuMocks(mockParams), - ...getServicesMocks(mockParams), + ...getServicesMocks({ + ...mockParams, + serviceResponse: mockParams.serviceResponse ?? licensesHycuService, + }), ...getCatalogHycuMocks(mockParams), ]), ); From 27d9446743556803467b831ac7ed1e5bb436f6e2 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Mon, 4 Nov 2024 20:24:16 +0100 Subject: [PATCH 34/43] fix(hycu): fix display name on listing page ref: MANAGER-15878 Signed-off-by: Thibault Barske --- packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx | 2 +- packages/manager/apps/hycu/src/types/hycu.details.interface.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx index 767ec7fc11ef..204a9936f964 100644 --- a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx +++ b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx @@ -50,7 +50,7 @@ const DatagridIdCell = (hycuDetail: IHycuDetails) => { ), ) } - label={hycuDetail?.iam.serviceName ?? hycuDetail.serviceName} + label={hycuDetail?.iam.displayName ?? hycuDetail.serviceName} > ); diff --git a/packages/manager/apps/hycu/src/types/hycu.details.interface.ts b/packages/manager/apps/hycu/src/types/hycu.details.interface.ts index 7418a462be89..3008a8a8de38 100644 --- a/packages/manager/apps/hycu/src/types/hycu.details.interface.ts +++ b/packages/manager/apps/hycu/src/types/hycu.details.interface.ts @@ -8,7 +8,7 @@ export enum LicenseStatus { export interface IamDetails { id: string; urn: string; - serviceName?: string; + displayName?: string; } export interface IHycuDetails { From 2715eaeb846f35e36e39587894e7488da9519328 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Tue, 5 Nov 2024 13:56:09 +0100 Subject: [PATCH 35/43] fix(hycu): fix the value of max file size of license ref: MANAGER-15877 Signed-off-by: Thibault Barske --- .../hycu/src/components/FileUpload/FileUpload.component.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx b/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx index 041808af381a..4186836f60b6 100644 --- a/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx +++ b/packages/manager/apps/hycu/src/components/FileUpload/FileUpload.component.tsx @@ -15,7 +15,7 @@ import { Controller, UseControllerProps } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { LICENSE_FILE_EXT } from '@/constants'; -const MAX_FILE_SIZE = 10e3; // 1 MB limit ~ +const MAX_FILE_SIZE = 1e6; // 1 MB limit ~ export const FileInputField = ({ name, From 7778c7d079094b5e4f4037b5c7dd830d12566cbb Mon Sep 17 00:00:00 2001 From: Thibaud Crespin Date: Tue, 29 Oct 2024 17:05:11 +0100 Subject: [PATCH 36/43] feat(hycu): add edit license page ref: MANAGER-14815 Signed-off-by: Thibaud Crespin --- .../translations/hycu/Messages_fr_FR.json | 3 + .../hycu/edit-pack/Messages_fr_FR.json | 9 + .../hycu/order/Messages_fr_FR.json | 5 +- .../components/Order/OrderConfirmation.tsx | 96 ------- .../components/Order/OrderTile.component.tsx | 55 ++++ .../src/components/Order/PackSelection.tsx | 140 ---------- .../apps/hycu/src/mocks/iam/iam.mock.ts | 3 +- .../ShortcutsTile/ShortcutsTile.spec.tsx | 47 ++++ .../ShortcutsTile/ShortcutsTile.tsx | 12 +- .../src/pages/edit-pack/EditPack.page.tsx | 240 ++++++++++++++++++ .../src/pages/edit-pack/EditPack.spec.tsx | 88 +++++++ .../apps/hycu/src/pages/order/Order.page.tsx | 194 ++++++++++++-- .../apps/hycu/src/pages/order/Order.spec.tsx | 6 +- .../apps/hycu/src/routes/routes.constant.ts | 2 + .../manager/apps/hycu/src/routes/routes.tsx | 11 + .../apps/hycu/src/utils/iam.constants.ts | 1 + .../apps/hycu/src/utils/tests/init.i18n.ts | 3 + 17 files changed, 649 insertions(+), 266 deletions(-) create mode 100644 packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_fr_FR.json delete mode 100644 packages/manager/apps/hycu/src/components/Order/OrderConfirmation.tsx create mode 100644 packages/manager/apps/hycu/src/components/Order/OrderTile.component.tsx delete mode 100644 packages/manager/apps/hycu/src/components/Order/PackSelection.tsx create mode 100644 packages/manager/apps/hycu/src/pages/edit-pack/EditPack.page.tsx create mode 100644 packages/manager/apps/hycu/src/pages/edit-pack/EditPack.spec.tsx diff --git a/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json index fe0fd5ec32d8..0fbcac9a8230 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_FR.json @@ -6,5 +6,8 @@ "hycu_status_toActivate": "À activer", "hycu_status_processing": "En cours d'activation", "hycu_status_error": "Erreur d'activation", + "hycu_cta_cancel": "Annuler", + "hycu_cta_order": "Commander", + "hycu_cta_done": "Terminer", "common_iam_actions_message": "Vous ne disposez pas des permissions nécessaires pour effectuer cette action, veuillez contacter votre administrateur" } diff --git a/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_fr_FR.json new file mode 100644 index 000000000000..b2880ac6bcde --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_fr_FR.json @@ -0,0 +1,9 @@ +{ + "hycu_edit_pack_title": "Modifier une licence HYCU R-Cloud Hybrid Cloud Edition", + "hycu_edit_pack_description": "HYCU R-Cloud Hybrid Cloud Edition est un logiciel de sauvegarde et de restauration spécialement conçu pour Nutanix. Nous vous proposons différents packs de licences selon le nombre de machines virtuelles (VM) utilisées par vos charges de travail Nutanix.", + "hycu_edit_pack_subtitle": "Modifier le type de pack pour la licence {{displayName}}", + "hycu_edit_pack_subtitle_description": "Si le pack de VM initialement sélectionné ne correspond plus à vos besoins, veuillez choisir un autre type de pack et finaliser votre commande. Le nouveau pack de VM sélectionné remplacera automatiquement votre souscription précédente.", + "hycu_edit_pack_initiated_title": "Modification de votre licence HYCU R-Cloud Hybrid Cloud Edition", + "hycu_edit_pack_initiated_description": "Si vous n'avez pas encore finalisé votre commande, vous pouvez la compléter en cliquant sur le lien suivant :", + "hycu_edit_pack_initiated_info": "Nous vous informerons de la disponibilité de votre licence par e-mail." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/order/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_fr_FR.json index 478afd731899..f372e64baee5 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/order/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_fr_FR.json @@ -3,10 +3,7 @@ "hycu_order_description": "HYCU R-Cloud Hybrid Cloud Edition est un logiciel de sauvegarde et de restauration spécialement conçu pour Nutanix. Nous vous proposons différents packs de licences selon le nombre de machines virtuelles (VM) utilisées par vos charges de travail Nutanix.", "hycu_order_subtitle": "Choisissez le type de pack", "hycu_order_subtitle_description": "Sélectionnez le nombre de machines virtuelles (VM) à couvrir par la licence HYCU R-Cloud Hybrid Cloud Edition. Veuillez noter qu'il vous sera impossible de sauvegarder plus de VM que le nombre prévu dans le pack. Si vous souhaitez protéger plus de 500 VM, merci de vous rapprocher de notre service commercial.", - "hycu_order_cta_cancel": "Annuler", - "hycu_order_cta_order": "Commander", "hycu_order_initiated_title": "Commande de votre pack", "hycu_order_initiated_description": "Si vous n'avez pas encore finalisé votre commande, vous pouvez la compléter en cliquant sur le lien suivant :", - "hycu_order_initiated_info": "Nous vous informerons de la disponibilité de votre licence par e-mail.", - "hycu_order_initiated_cta_done": "Terminer" + "hycu_order_initiated_info": "Nous vous informerons de la disponibilité de votre licence par e-mail." } diff --git a/packages/manager/apps/hycu/src/components/Order/OrderConfirmation.tsx b/packages/manager/apps/hycu/src/components/Order/OrderConfirmation.tsx deleted file mode 100644 index 91bb69910917..000000000000 --- a/packages/manager/apps/hycu/src/components/Order/OrderConfirmation.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import React from 'react'; -import { - OsdsText, - OsdsButton, - OsdsLink, - OsdsIcon, - OsdsTile, -} from '@ovhcloud/ods-components/react'; -import { - ODS_BUTTON_SIZE, - ODS_BUTTON_VARIANT, - ODS_ICON_SIZE, - ODS_ICON_NAME, - ODS_LINK_REFERRER_POLICY, -} from '@ovhcloud/ods-components'; -import { - ODS_THEME_COLOR_INTENT, - ODS_THEME_TYPOGRAPHY_SIZE, - ODS_THEME_TYPOGRAPHY_LEVEL, -} from '@ovhcloud/ods-common-theming'; -import { OdsHTMLAnchorElementTarget } from '@ovhcloud/ods-common-core'; -import { useNavigate } from 'react-router-dom'; -import { useTranslation } from 'react-i18next'; -import { urls } from '@/routes/routes.constant'; - -type OrderConfirmationProps = { - orderLink: string; -}; - -const OrderConfirmation = ({ orderLink }: OrderConfirmationProps) => { - const { t } = useTranslation('hycu/order'); - const navigate = useNavigate(); - - return ( - <> - - -
    - - {t('hycu_order_initiated_title')} - - - {t('hycu_order_initiated_description')} - - - {orderLink} - - - - - - {t('hycu_order_initiated_info')} - -
    -
    -
    - { - navigate(urls.listing); - }} - > - {t('hycu_order_initiated_cta_done')} - - - ); -}; - -export default OrderConfirmation; diff --git a/packages/manager/apps/hycu/src/components/Order/OrderTile.component.tsx b/packages/manager/apps/hycu/src/components/Order/OrderTile.component.tsx new file mode 100644 index 000000000000..11858d1a6ff3 --- /dev/null +++ b/packages/manager/apps/hycu/src/components/Order/OrderTile.component.tsx @@ -0,0 +1,55 @@ +import React, { ReactNode } from 'react'; + +import { Price } from '@ovh-ux/manager-react-components'; +import { OvhSubsidiary } from '@ovh-ux/manager-react-components/src/enumTypes'; +import { OsdsText, OsdsTile } from '@ovhcloud/ods-components/react'; +import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import { ODS_TEXT_LEVEL, ODS_TEXT_SIZE } from '@ovhcloud/ods-components'; + +import { HYCUCatalogPlanPricing } from '@/types/orderCatalogHYCU.type'; + +export type OrderTileProps = React.ComponentProps & { + label: string; + pricing: HYCUCatalogPlanPricing; + subsidiary: OvhSubsidiary; +}; + +export const OrderTile = ({ + label, + pricing, + subsidiary, + ...otherProps +}: OrderTileProps) => { + return ( + +
    + + {label} + + +
    +
    + ); +}; + +export const OrderTileWrapper = ({ children }: { children: ReactNode }) => ( +
    + {children} +
    +); diff --git a/packages/manager/apps/hycu/src/components/Order/PackSelection.tsx b/packages/manager/apps/hycu/src/components/Order/PackSelection.tsx deleted file mode 100644 index d8d7fc375e19..000000000000 --- a/packages/manager/apps/hycu/src/components/Order/PackSelection.tsx +++ /dev/null @@ -1,140 +0,0 @@ -import React, { Dispatch, SetStateAction } from 'react'; -import { useNavigate } from 'react-router-dom'; -import { Trans, useTranslation } from 'react-i18next'; - -import { OdsHTMLAnchorElementTarget } from '@ovhcloud/ods-common-core'; -import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; -import { - ODS_BUTTON_VARIANT, - ODS_TEXT_LEVEL, - ODS_TEXT_SIZE, -} from '@ovhcloud/ods-components'; -import { - OsdsText, - OsdsButton, - OsdsTile, - OsdsLink, -} from '@ovhcloud/ods-components/react'; -import { - Description, - OvhSubsidiary, - Price, - Subtitle, -} from '@ovh-ux/manager-react-components'; - -import Error from '@/components/Error/Error'; -import Loading from '@/components/Loading/Loading.component'; -import { useOrderCatalogHYCU } from '@/hooks/order/useOrderCatalogHYCU'; -import { urls } from '@/routes/routes.constant'; -import { sortPacksByPrice } from '@/utils/sortPacks'; -import { getRenewPrice } from '@/utils/getRenewPrice'; -import { CONTACT_URL_BY_SUBSIDIARY } from '@/utils/contactList'; - -type PackSelectionProps = { - selectPack: Dispatch>; - setOrderInitiated: () => void; - orderLink: string; - selectedPack: string; - subsidiary: OvhSubsidiary; -}; - -const PackSelection = ({ - selectPack, - setOrderInitiated, - orderLink, - selectedPack, - subsidiary, -}: PackSelectionProps) => { - const { t } = useTranslation('hycu/order'); - const navigate = useNavigate(); - - const { data: orderCatalogHYCU, isLoading, error } = useOrderCatalogHYCU( - subsidiary, - { - refetchOnWindowFocus: false, - keepPreviousData: true, - }, - ); - - if (!isLoading && error) return ; - - return ( - <> - {t('hycu_order_subtitle')} - - - ), - }} - > - - {isLoading && } - {orderCatalogHYCU && !isLoading && ( -
    - {sortPacksByPrice(orderCatalogHYCU.plans).map((product) => ( - { - selectPack(product.planCode); - }} - rounded - > -
    - - {product.invoiceName} - - -
    -
    - ))} -
    - )} -
    - { - navigate(urls.listing); - }} - slot="actions" - variant={ODS_BUTTON_VARIANT.ghost} - > - {t('hycu_order_cta_cancel')} - - { - setOrderInitiated(); - }} - slot="actions" - > - {t('hycu_order_cta_order')} - -
    - - ); -}; - -export default PackSelection; diff --git a/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts b/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts index d35d19f16165..3ed40ac64d24 100644 --- a/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts +++ b/packages/manager/apps/hycu/src/mocks/iam/iam.mock.ts @@ -10,12 +10,13 @@ export const resourceList: IamCheckResponse[] = [ IAM_ACTIONS.licenseHycuApiOvhActivate, IAM_ACTIONS.licenseHycuApiOvhRefresh, IAM_ACTIONS.licenseHycuApiOvhTerminate, + IAM_ACTIONS.licenseHycuApiOvhEdit, ], unauthorizedActions: [], }, { urn: licensesHycu[1].iam.urn, authorizedActions: [], - unauthorizedActions: [], + unauthorizedActions: [IAM_ACTIONS.licenseHycuApiOvhEdit], }, ]; diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx index 0364df135033..140cdc45935e 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx @@ -213,4 +213,51 @@ describe('License Hycu shortcuts tile for dashboard test suite', () => { { timeout: 20_000 }, ); }); + + it('Can open edit page with IAM authorization', async () => { + const user = userEvent.setup(); + await renderTestApp(`/${licensesHycu[0].serviceName}`, { + licenseStatus: LicenseStatus.ACTIVATED, + }); + + await waitFor( + () => { + expect( + screen.getByTestId('hycu_link_edit_test_id'), + ).not.toHaveAttribute('disabled'); + }, + { timeout: 30_000 }, + ); + await act(() => user.click(screen.getByTestId('hycu_link_edit_test_id'))); + + await waitFor( + () => + expect( + screen.getByText(labels.editPack.hycu_edit_pack_description), + ).toBeVisible(), + { timeout: 20_000 }, + ); + }); + + it("Can't open edit page without IAM authorization", async () => { + const user = userEvent.setup(); + await renderTestApp(`/${licensesHycu[1].serviceName}`, { + licenseStatus: LicenseStatus.ACTIVATED, + }); + + await waitFor( + () => expect(screen.getByTestId('hycu_link_edit_test_id')).toBeVisible(), + { timeout: 30_000 }, + ); + + await act(() => user.click(screen.getByTestId('hycu_link_edit_test_id'))); + + await waitFor( + () => + expect( + screen.queryByText(labels.editPack.hycu_edit_pack_description), + ).not.toBeInTheDocument(), + { timeout: 20_000 }, + ); + }); }); diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx index f620d92b7931..b689884432ca 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx @@ -90,7 +90,17 @@ const ShortcutsTile = ({ serviceName }: { serviceName: string }) => { linkChangePackType: { id: 'link_change_pack_type', value: ( - + { + navigate( + urls.editPack.replace(subRoutes.serviceName, serviceName), + ); + }} + > {t('hycu_dashboard_link_change_pack_type')} ), diff --git a/packages/manager/apps/hycu/src/pages/edit-pack/EditPack.page.tsx b/packages/manager/apps/hycu/src/pages/edit-pack/EditPack.page.tsx new file mode 100644 index 000000000000..e9b1ae3e7d2d --- /dev/null +++ b/packages/manager/apps/hycu/src/pages/edit-pack/EditPack.page.tsx @@ -0,0 +1,240 @@ +import React, { useContext, useMemo, useState } from 'react'; +import { Trans, useTranslation } from 'react-i18next'; +import { useNavigate, useParams } from 'react-router-dom'; + +import { + BaseLayout, + Description, + OvhSubsidiary, + Subtitle, + useServiceDetails, +} from '@ovh-ux/manager-react-components'; +import { ShellContext } from '@ovh-ux/manager-react-shell-client'; +import { + ODS_THEME_COLOR_INTENT, + ODS_THEME_TYPOGRAPHY_LEVEL, + ODS_THEME_TYPOGRAPHY_SIZE, +} from '@ovhcloud/ods-common-theming'; +import { OdsHTMLAnchorElementTarget } from '@ovhcloud/ods-common-core'; +import { + ODS_BUTTON_SIZE, + ODS_BUTTON_VARIANT, + ODS_ICON_NAME, + ODS_ICON_SIZE, + ODS_LINK_REFERRER_POLICY, +} from '@ovhcloud/ods-components'; +import { + OsdsButton, + OsdsIcon, + OsdsLink, + OsdsText, + OsdsTile, +} from '@ovhcloud/ods-components/react'; + +import Breadcrumb from '@/components/Breadcrumb/Breadcrumb.component'; +import Errors from '@/components/Error/Error'; +import Loading from '@/components/Loading/Loading.component'; +import { + OrderTile, + OrderTileWrapper, +} from '@/components/Order/OrderTile.component'; + +import { BreadcrumbItem } from '@/hooks/breadcrumb/useBreadcrumb'; +import { useOrderCatalogHYCU } from '@/hooks/order/useOrderCatalogHYCU'; +import useOrderHYCU from '@/hooks/order/useOrderHYCU'; +import { subRoutes, urls } from '@/routes/routes.constant'; +import { CONTACT_URL_BY_SUBSIDIARY } from '@/utils/contactList'; +import { sortPacksByPrice } from '@/utils/sortPacks'; +import { getRenewPrice } from '@/utils/getRenewPrice'; + +export default function EditPack() { + const { serviceName } = useParams(); + const { t } = useTranslation('hycu/edit-pack'); + const { t: tCommon } = useTranslation('hycu'); + const { t: tError } = useTranslation('hycu/error'); + const navigate = useNavigate(); + + const { environment } = useContext(ShellContext); + const subsidiary = environment.getUser().ovhSubsidiary as OvhSubsidiary; + const { data: serviceDetails, error } = useServiceDetails({ + resourceName: serviceName, + }); + + const [selectedPack, setSelectedPack] = useState(null); + const [isOrderInitiated, setIsOrderInitiated] = useState(false); + const [currentPack, displayName] = useMemo( + () => [ + serviceDetails?.data.billing.plan.code ?? null, + serviceDetails?.data.resource.displayName ?? 'N/A', + ], + [serviceDetails], + ); + + const { data: orderCatalogHYCU, isLoading, isError } = useOrderCatalogHYCU( + subsidiary, + { + refetchOnWindowFocus: false, + keepPreviousData: true, + }, + ); + const { orderLink, redirectToOrder } = useOrderHYCU({ + planCode: selectedPack, + region: subsidiary, + }); + + const header = { + title: t('hycu_edit_pack_title'), + }; + const description: string = t('hycu_edit_pack_description'); + + const breadcrumbItems: BreadcrumbItem[] = [ + { + id: serviceName, + label: serviceName, + }, + { + id: 'edit-pack', + label: t('hycu_edit_pack_title'), + }, + ]; + + if (isError || error) + return {tError('manager_error_page_default')}; + + if (isLoading) return ; + + return ( + } + description={description} + header={header} + > + {!isOrderInitiated ? ( + <> + + {t('hycu_edit_pack_subtitle', { + displayName, + })} + + + + ), + }} + > + + + {sortPacksByPrice(orderCatalogHYCU?.plans).map((product) => ( + { + setSelectedPack(product.planCode); + }} + > + ))} + +
    + { + navigate( + urls.dashboard.replace(subRoutes.serviceName, serviceName), + ); + }} + slot="actions" + variant={ODS_BUTTON_VARIANT.ghost} + > + {tCommon('hycu_cta_cancel')} + + { + setIsOrderInitiated(true); + redirectToOrder(); + }} + slot="actions" + > + {tCommon('hycu_cta_order')} + +
    + + ) : ( + <> + + +
    + + {t('hycu_edit_pack_initiated_title')} + + + {t('hycu_edit_pack_initiated_description')} + + + {orderLink} + + + + + + {t('hycu_edit_pack_initiated_info')} + +
    +
    +
    + { + navigate( + urls.dashboard.replace(subRoutes.serviceName, serviceName), + ); + }} + > + {tCommon('hycu_cta_done')} + + + )} +
    + ); +} diff --git a/packages/manager/apps/hycu/src/pages/edit-pack/EditPack.spec.tsx b/packages/manager/apps/hycu/src/pages/edit-pack/EditPack.spec.tsx new file mode 100644 index 000000000000..44fa4a52579f --- /dev/null +++ b/packages/manager/apps/hycu/src/pages/edit-pack/EditPack.spec.tsx @@ -0,0 +1,88 @@ +import { act, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { vi } from 'vitest'; +import { renderTestApp } from '@/utils/tests/renderTestApp'; +import '@testing-library/jest-dom'; +import { labels } from '@/utils/tests/init.i18n'; +import { catalog } from '@/mocks/catalogHycu/catalogHycu.data'; +import { licensesHycu } from '@/mocks/licenseHycu/licenseHycu.data'; + +describe('License Hycu edit test suite', () => { + it('should display the hycu edit page', async () => { + await renderTestApp(`/${licensesHycu[0].serviceName}/edit-pack`); + + await waitFor( + () => screen.getByText(labels.editPack.hycu_edit_pack_title), + { + timeout: 10_000, + }, + ); + + expect( + screen.getByText(labels.editPack.hycu_edit_pack_title), + ).toBeVisible(); + expect( + screen.getByText(labels.editPack.hycu_edit_pack_description), + ).toBeVisible(); + expect( + screen.getByText( + labels.editPack.hycu_edit_pack_subtitle.replace( + '{{displayName}}', + 'N/A', + ), + ), + ).toBeVisible(); + + expect( + screen.queryByText(labels.editPack.hycu_edit_pack_initiated_title), + ).not.toBeInTheDocument(); + }); + + it('should enable order button when different pack is selected', async () => { + await renderTestApp(`/${licensesHycu[0].serviceName}/edit-pack`); + + await waitFor(() => screen.getByText(catalog.plans[0].invoiceName), { + timeout: 10_000, + }); + + expect(screen.getByText(labels.common.hycu_cta_order)).toBeDisabled(); + + await act(() => + userEvent.click(screen.getByText(catalog.plans[1].invoiceName)), + ); + + expect(screen.getByText(labels.common.hycu_cta_order)).toBeEnabled(); + }); + + it('should redirect to express order and change page informations', async () => { + const closeSpy = vi.fn(); + window.open = vi.fn().mockReturnValue({ close: closeSpy }); + + await renderTestApp(`/${licensesHycu[0].serviceName}/edit-pack`); + + await waitFor(() => screen.getByText(catalog.plans[1].invoiceName), { + timeout: 10_000, + }); + + // Pack selection + await act(() => + userEvent.click(screen.getByText(catalog.plans[1].invoiceName)), + ); + + // Click on order button + await act(() => + userEvent.click(screen.getByText(labels.common.hycu_cta_order)), + ); + + expect(window.open).toHaveBeenCalled(); + + // Check page has changed to display express order info + expect( + screen.getByText(labels.editPack.hycu_edit_pack_initiated_title), + ).toBeVisible(); + + expect( + screen.queryByText(labels.editPack.hycu_edit_pack_subtitle), + ).not.toBeInTheDocument(); + }); +}); diff --git a/packages/manager/apps/hycu/src/pages/order/Order.page.tsx b/packages/manager/apps/hycu/src/pages/order/Order.page.tsx index 706b2114d653..6591e7d62ef1 100644 --- a/packages/manager/apps/hycu/src/pages/order/Order.page.tsx +++ b/packages/manager/apps/hycu/src/pages/order/Order.page.tsx @@ -1,35 +1,80 @@ import React, { useContext, useState } from 'react'; -import { useTranslation } from 'react-i18next'; +import { Trans, useTranslation } from 'react-i18next'; +import { useNavigate } from 'react-router-dom'; -import { BaseLayout, OvhSubsidiary } from '@ovh-ux/manager-react-components'; +import { + BaseLayout, + Description, + OvhSubsidiary, + Subtitle, +} from '@ovh-ux/manager-react-components'; import { ShellContext } from '@ovh-ux/manager-react-shell-client'; +import { + ODS_THEME_COLOR_INTENT, + ODS_THEME_TYPOGRAPHY_LEVEL, + ODS_THEME_TYPOGRAPHY_SIZE, +} from '@ovhcloud/ods-common-theming'; +import { OdsHTMLAnchorElementTarget } from '@ovhcloud/ods-common-core'; +import { + ODS_BUTTON_SIZE, + ODS_BUTTON_VARIANT, + ODS_ICON_NAME, + ODS_ICON_SIZE, + ODS_LINK_REFERRER_POLICY, +} from '@ovhcloud/ods-components'; +import { + OsdsButton, + OsdsIcon, + OsdsLink, + OsdsText, + OsdsTile, +} from '@ovhcloud/ods-components/react'; import Breadcrumb from '@/components/Breadcrumb/Breadcrumb.component'; -import OrderConfirmation from '@/components/Order/OrderConfirmation'; -import PackSelection from '@/components/Order/PackSelection'; -import useOrderHYCU from '@/hooks/order/useOrderHYCU'; +import Errors from '@/components/Error/Error'; +import Loading from '@/components/Loading/Loading.component'; +import { + OrderTile, + OrderTileWrapper, +} from '@/components/Order/OrderTile.component'; import { BreadcrumbItem } from '@/hooks/breadcrumb/useBreadcrumb'; +import { useOrderCatalogHYCU } from '@/hooks/order/useOrderCatalogHYCU'; +import useOrderHYCU from '@/hooks/order/useOrderHYCU'; +import { urls } from '@/routes/routes.constant'; +import { CONTACT_URL_BY_SUBSIDIARY } from '@/utils/contactList'; +import { sortPacksByPrice } from '@/utils/sortPacks'; +import { getRenewPrice } from '@/utils/getRenewPrice'; export default function Order() { const { t } = useTranslation('hycu/order'); + const { t: tCommon } = useTranslation('hycu'); + const { t: tError } = useTranslation('hycu/error'); + const navigate = useNavigate(); const { environment } = useContext(ShellContext); const subsidiary: OvhSubsidiary = environment.getUser() .ovhSubsidiary as OvhSubsidiary; - const header = { - title: t('hycu_order_title'), - }; - const description: string = t('hycu_order_description'); - const [selectedPack, setSelectedPack] = useState(null); const [isOrderInitiated, setIsOrderInitiated] = useState(false); + const { data: orderCatalogHYCU, isLoading, isError } = useOrderCatalogHYCU( + subsidiary, + { + refetchOnWindowFocus: false, + keepPreviousData: true, + }, + ); const { orderLink, redirectToOrder } = useOrderHYCU({ planCode: selectedPack, region: subsidiary, }); + const header = { + title: t('hycu_order_title'), + }; + const description: string = t('hycu_order_description'); + const breadcrumbItems: BreadcrumbItem[] = [ { id: 'order', @@ -37,6 +82,10 @@ export default function Order() { }, ]; + if (isError) return {tError('manager_error_page_default')}; + + if (isLoading) return ; + return ( } @@ -44,18 +93,121 @@ export default function Order() { header={header} > {!isOrderInitiated ? ( - setSelectedPack(pack)} - selectedPack={selectedPack} - setOrderInitiated={() => { - setIsOrderInitiated(true); - redirectToOrder(); - }} - > + <> + {t('hycu_order_subtitle')} + + + ), + }} + > + + + {sortPacksByPrice(orderCatalogHYCU?.plans).map((product) => ( + { + setSelectedPack(product.planCode); + }} + > + ))} + +
    + { + navigate(urls.listing); + }} + slot="actions" + variant={ODS_BUTTON_VARIANT.ghost} + > + {tCommon('hycu_cta_cancel')} + + { + setIsOrderInitiated(true); + redirectToOrder(); + }} + slot="actions" + > + {tCommon('hycu_cta_order')} + +
    + ) : ( - + <> + + +
    + + {t('hycu_order_initiated_title')} + + + {t('hycu_order_initiated_description')} + + + {orderLink} + + + + + + {t('hycu_order_initiated_info')} + +
    +
    +
    + { + navigate(urls.listing); + }} + > + {tCommon('hycu_cta_done')} + + )}
    ); diff --git a/packages/manager/apps/hycu/src/pages/order/Order.spec.tsx b/packages/manager/apps/hycu/src/pages/order/Order.spec.tsx index 1919ae5cb930..e5c9acfa4e30 100644 --- a/packages/manager/apps/hycu/src/pages/order/Order.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/order/Order.spec.tsx @@ -30,13 +30,13 @@ describe('License Hycu order test suite', () => { timeout: 10_000, }); - expect(screen.getByText(labels.order.hycu_order_cta_order)).toBeDisabled(); + expect(screen.getByText(labels.common.hycu_cta_order)).toBeDisabled(); await act(() => userEvent.click(screen.getByText(catalog.plans[0].invoiceName)), ); - expect(screen.getByText(labels.order.hycu_order_cta_order)).toBeEnabled(); + expect(screen.getByText(labels.common.hycu_cta_order)).toBeEnabled(); }); it('should redirect to express order and change page informations', async () => { @@ -56,7 +56,7 @@ describe('License Hycu order test suite', () => { // Click on order button await act(() => - userEvent.click(screen.getByText(labels.order.hycu_order_cta_order)), + userEvent.click(screen.getByText(labels.common.hycu_cta_order)), ); expect(window.open).toHaveBeenCalled(); diff --git a/packages/manager/apps/hycu/src/routes/routes.constant.ts b/packages/manager/apps/hycu/src/routes/routes.constant.ts index fb65c8e9c65b..a89e3c902c13 100644 --- a/packages/manager/apps/hycu/src/routes/routes.constant.ts +++ b/packages/manager/apps/hycu/src/routes/routes.constant.ts @@ -1,4 +1,5 @@ export const subRoutes = { + editPack: 'edit-pack', onboarding: 'onboarding', order: 'order', serviceName: ':serviceName', @@ -10,6 +11,7 @@ export const urls = { onboarding: `/${subRoutes.onboarding}`, order: `/${subRoutes.order}`, dashboard: `/${subRoutes.serviceName}`, + editPack: `/${subRoutes.serviceName}/${subRoutes.editPack}`, activateLicense: `/${subRoutes.serviceName}/activate-license`, regenerateLicense: `/${subRoutes.serviceName}/regenerate-license`, editName: `/${subRoutes.serviceName}/edit-name`, diff --git a/packages/manager/apps/hycu/src/routes/routes.tsx b/packages/manager/apps/hycu/src/routes/routes.tsx index e949ce90b61d..bd1f9e683ecd 100644 --- a/packages/manager/apps/hycu/src/routes/routes.tsx +++ b/packages/manager/apps/hycu/src/routes/routes.tsx @@ -120,6 +120,17 @@ export const Routes: any = [ }, }, }, + { + id: 'edit-pack', + path: urls.editPack, + ...lazyRouteConfig(() => import('@/pages/edit-pack/EditPack.page')), + handle: { + tracking: { + pageName: 'edit-pack', + pageType: PageType.dashboard, + }, + }, + }, ], }, { diff --git a/packages/manager/apps/hycu/src/utils/iam.constants.ts b/packages/manager/apps/hycu/src/utils/iam.constants.ts index 0ba111dd5f0f..6e0eae2d410b 100644 --- a/packages/manager/apps/hycu/src/utils/iam.constants.ts +++ b/packages/manager/apps/hycu/src/utils/iam.constants.ts @@ -2,6 +2,7 @@ export const IAM_ACTIONS = { licenseHycuApiOvhGet: 'licenseHycu:apiovh:license/get', licenseHycuApiOvhActivate: 'licenseHycu:apiovh:activate', licenseHycuApiOvhRefresh: 'licenseHycu:apiovh:refresh', + licenseHycuApiOvhEdit: 'licenseHycu:apiovh:edit', licenseHycuApiOvhServiceEdit: 'account:apiovh:service/edit', licenseHycuApiOvhTerminate: 'account:apiovh:services/terminate', } as const; diff --git a/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts b/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts index 15efbe31b18f..b7fe5979dc7a 100644 --- a/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts +++ b/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts @@ -6,6 +6,7 @@ import listing from '../../../public/translations/hycu/listing/Messages_fr_FR.js import onboarding from '../../../public/translations/hycu/onboarding/Messages_fr_FR.json'; import order from '../../../public/translations/hycu/order/Messages_fr_FR.json'; import terminate from '../../../public/translations/hycu/terminate/Messages_fr_FR.json'; +import editPack from '../../../public/translations/hycu/edit-pack/Messages_fr_FR.json'; export const defaultLocale = 'fr_FR'; export const defaultAvailableLocales = [defaultLocale]; @@ -18,6 +19,7 @@ function addTranslations() { .addResources(defaultLocale, 'hycu/onboarding', onboarding) .addResources(defaultLocale, 'hycu/order', order) .addResources(defaultLocale, 'hycu/terminate', terminate) + .addResources(defaultLocale, 'hycu/edit-pack', editPack) .addResources(defaultLocale, 'error', error) .use({ type: 'postProcessor', @@ -59,5 +61,6 @@ export const labels = { onboarding, order, terminate, + editPack, error, }; From bc8c8ded86d50f7101ab5c411c7fadb6f84dddea Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Tue, 5 Nov 2024 15:54:56 +0100 Subject: [PATCH 37/43] feat(hycu): add error handling on listing page ref: MANAGER-14497 Signed-off-by: Thibault Barske --- .../hycu/listing/Messages_fr_FR.json | 3 ++- .../hycu/src/pages/listing/Listing.page.tsx | 27 ++++++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_fr_FR.json index 0a8af73eb2b5..dfe0b0c1f0e4 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_fr_FR.json @@ -6,5 +6,6 @@ "hycu_commercial_name": "Type de pack", "hycu_subscribed_date": "Date de souscription", "hycu_order": "Commander", - "hycu_service_listing_terminate": "Résilier" + "hycu_service_listing_terminate": "Résilier", + "hycu_listing_error_loading_data": "Erreur de chargement" } diff --git a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx index 204a9936f964..41ac304b411d 100644 --- a/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx +++ b/packages/manager/apps/hycu/src/pages/listing/Listing.page.tsx @@ -7,6 +7,7 @@ import { OsdsChip, OsdsMessage, OsdsSkeleton, + OsdsText, } from '@ovhcloud/ods-components/react'; import { Datagrid, @@ -36,6 +37,16 @@ import HycuActionMenu from './menu/HycuActionMenu.component'; import { getStatusColor } from '@/utils/statusColor'; /* ========= datagrid cells ========= */ +const DatagridErrorCell = () => { + const { t } = useTranslation('hycu/listing'); + + return ( + + {t('hycu_listing_error_loading_data')} + + ); +}; + const DatagridIdCell = (hycuDetail: IHycuDetails) => { const navigate = useNavigate(); @@ -84,10 +95,12 @@ const DatagridStatusCell = (hycuDetail: IHycuDetails) => { }; const DatagridCommercialNameCell = (hycuDetail: IHycuDetails) => { - const { data: serviceDetails, isLoading } = useServiceDetails({ + const { data: serviceDetails, isLoading, isError } = useServiceDetails({ resourceName: hycuDetail.serviceName, }); + if (isError) return ; + return ( {isLoading ? ( @@ -100,7 +113,7 @@ const DatagridCommercialNameCell = (hycuDetail: IHycuDetails) => { }; const DatagridCreatedDateCell = (hycuDetail: IHycuDetails) => { - const { data: serviceDetails, isLoading } = useServiceDetails({ + const { data: serviceDetails, isLoading, isError } = useServiceDetails({ resourceName: hycuDetail.serviceName, }); const creationDate = @@ -110,6 +123,8 @@ const DatagridCreatedDateCell = (hycuDetail: IHycuDetails) => { format: DateFormat.compact, }); + if (isError) return ; + return ( {isLoading ? : formattedDate} @@ -150,31 +165,35 @@ export default function Listing() { { id: 'name', label: t('hycu_name'), + isSortable: false, cell: DatagridIdCell, }, { - id: 'controller_id', + id: 'controllerId', label: t('hycu_controller_id'), cell: DatagridControllerIdCell, }, { - id: 'status', + id: 'licenseStatus', label: t('hycu_status'), cell: DatagridStatusCell, }, { id: 'commercial_name', label: t('hycu_commercial_name'), + isSortable: false, cell: DatagridCommercialNameCell, }, { id: 'subscribed_date', label: t('hycu_subscribed_date'), + isSortable: false, cell: DatagridCreatedDateCell, }, { id: 'action', label: '', + isSortable: false, cell: DatagridActionCell, }, ]; From b313b56e9af0c2501faf770c450cbdc790b3c066 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Tue, 5 Nov 2024 17:17:48 +0100 Subject: [PATCH 38/43] feat(hycu): add alert banner without notification hook to avoid problem ref: MANAGER-14499 Signed-off-by: Thibault Barske --- .../src/pages/dashboard/Dashboard.page.tsx | 77 +++++++++++++++---- 1 file changed, 60 insertions(+), 17 deletions(-) diff --git a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx index 53108b55ed4c..c5d8f57d1e37 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/Dashboard.page.tsx @@ -1,13 +1,20 @@ -import React, { useEffect } from 'react'; +import React, { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { - Outlet, - NavLink, useNavigate, useResolvedPath, useParams, + NavLink, + Outlet, } from 'react-router-dom'; +import { ODS_THEME_TYPOGRAPHY_SIZE } from '@ovhcloud/ods-common-theming'; +import { + ODS_MESSAGE_TYPE, + ODS_TEXT_COLOR_INTENT, +} from '@ovhcloud/ods-components'; import { + OsdsMessage, + OsdsText, OsdsTabs, OsdsTabBar, OsdsTabBarItem, @@ -17,14 +24,13 @@ import { BaseLayout, useServiceDetails, Notifications, - useNotifications, } from '@ovh-ux/manager-react-components'; import Breadcrumb from '@/components/Breadcrumb/Breadcrumb.component'; import Errors from '@/components/Error/Error'; import { urls } from '@/routes/routes.constant'; import { useDetailsLicenseHYCU } from '@/hooks/api/license'; -import { LicenseStatus } from '@/types/hycu.details.interface'; +import { IHycuDetails, LicenseStatus } from '@/types/hycu.details.interface'; export type DashboardTabItemProps = { name: string; @@ -36,29 +42,61 @@ export type DashboardLayoutProps = { tabs: DashboardTabItemProps[]; }; +const ServiceSuspendedBanner = () => { + const { t } = useTranslation('hycu/dashboard'); + + return ( + + + {t('hycu_dashboard_warning_license_suspended_message')} + + + ); +}; + +const LicenseErrorActivationBanner = ({ + licenseHycu, +}: { + licenseHycu: IHycuDetails; +}) => { + const { t } = useTranslation('hycu/dashboard'); + + return ( + + + {t('hycu_dashboard_error_license_message', { + error: licenseHycu.comment, + })} + + + ); +}; + export default function DashboardPage() { const { serviceName } = useParams(); const navigate = useNavigate(); const { t } = useTranslation('hycu/dashboard'); - const { addError, addWarning, clearNotifications } = useNotifications(); const { data: licenseHycu } = useDetailsLicenseHYCU(serviceName); const { data: serviceDetails, error } = useServiceDetails({ resourceName: serviceName, }); - useEffect(() => { + const dashboardBanner = useMemo(() => { if (serviceDetails?.data.resource.state === 'suspended') { - clearNotifications(); - addWarning(t('hycu_dashboard_warning_license_suspended_message')); - } else if (licenseHycu?.data.licenseStatus === LicenseStatus.ERROR) { - clearNotifications(); - addError( - t('hycu_dashboard_error_license_message', { - error: licenseHycu.data.comment, - }), - ); + return ; + } + if (licenseHycu?.data.licenseStatus === LicenseStatus.ERROR) { + return ; } + + return null; }, [licenseHycu, serviceDetails]); const tabsList = [ @@ -92,7 +130,12 @@ export default function DashboardPage() { onClickReturn={() => { navigate(urls.listing); }} - message={} + message={ + <> + {dashboardBanner} + + + } tabs={ From 334b709426ef463e36fdcc27fbbdb6ec91f3412b Mon Sep 17 00:00:00 2001 From: Thibaud Crespin Date: Thu, 7 Nov 2024 16:27:57 +0100 Subject: [PATCH 39/43] fix(hycu): express order URLs and edit pack parameters ref: MANAGER-15953 Signed-off-by: Thibaud Crespin --- .../manager/apps/hycu/src/hooks/order/useOrderHYCU.ts | 4 +++- .../apps/hycu/src/pages/edit-pack/EditPack.page.tsx | 1 + packages/manager/modules/order/src/order.constant.ts | 11 +++++++---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/manager/apps/hycu/src/hooks/order/useOrderHYCU.ts b/packages/manager/apps/hycu/src/hooks/order/useOrderHYCU.ts index 00b562cef8b8..a3f716802590 100644 --- a/packages/manager/apps/hycu/src/hooks/order/useOrderHYCU.ts +++ b/packages/manager/apps/hycu/src/hooks/order/useOrderHYCU.ts @@ -8,14 +8,16 @@ import { useMemo } from 'react'; interface HYCUOrder { planCode: string; region: OvhSubsidiary; + serviceName?: string; } -const useOrderHYCU = ({ planCode, region }: HYCUOrder) => { +const useOrderHYCU = ({ planCode, region, serviceName = '' }: HYCUOrder) => { const orderBaseUrl = useOrderURL('express_review_base'); const orderLink = useMemo(() => { const HYCUProductSettings = getHYCUProductSettings({ planCode, region, + serviceName, }); if (planCode) return `${orderBaseUrl}?products=~(${HYCUProductSettings})`; return null; diff --git a/packages/manager/apps/hycu/src/pages/edit-pack/EditPack.page.tsx b/packages/manager/apps/hycu/src/pages/edit-pack/EditPack.page.tsx index e9b1ae3e7d2d..33379e9a7677 100644 --- a/packages/manager/apps/hycu/src/pages/edit-pack/EditPack.page.tsx +++ b/packages/manager/apps/hycu/src/pages/edit-pack/EditPack.page.tsx @@ -80,6 +80,7 @@ export default function EditPack() { const { orderLink, redirectToOrder } = useOrderHYCU({ planCode: selectedPack, region: subsidiary, + serviceName, }); const header = { diff --git a/packages/manager/modules/order/src/order.constant.ts b/packages/manager/modules/order/src/order.constant.ts index 35a00b0014c6..c93cd220c4cb 100644 --- a/packages/manager/modules/order/src/order.constant.ts +++ b/packages/manager/modules/order/src/order.constant.ts @@ -59,12 +59,15 @@ export const getVcdProductSettings = ({ export const getHYCUProductSettings = ({ planCode, region, + serviceName = '', }: { planCode: string; region: string; + serviceName?: string; }) => JSURL.stringify({ productId: 'licenseHycu', + serviceName, planCode, duration: 'P1M', pricingMode: 'default', @@ -203,19 +206,19 @@ export const ORDER_URLS = { TN: 'https://eco.ovhcloud.com/fr-tn/', }, express_review_base: { - CZ: 'https://www.ovh.cz/order/express/#/express/review', + CZ: 'https://www.ovh.ie/order/express/#/express/review', DE: 'https://www.ovh.de/order/express/#/express/review', ES: 'https://www.ovh.es/order/express/#/express/review', - FI: 'https://www.ovh-hosting.fi/order/express/#/express/review', + FI: 'https://www.ovh.ie/order/express/#/express/review', FR: 'https://www.ovh.com/fr/order/express/#/express/review', GB: 'https://www.ovh.co.uk/order/express/#/express/review', IE: 'https://www.ovh.ie/order/express/#/express/review', IT: 'https://www.ovh.it/order/express/#/express/review', - LT: 'https://www.ovh.lt/order/express/#/express/review', + LT: 'https://www.ovh.ie/order/express/#/express/review', NL: 'https://www.ovh.nl/order/express/#/express/review', PL: 'https://www.ovh.pl/order/express/#/express/review', PT: 'https://www.ovh.pt/order/express/#/express/review', - MA: 'https://www.ovh.ma/order/express/#/express/review', + MA: 'https://www.ovh.com/ma/order/express/#/express/review', SN: 'https://www.ovh.sn/order/express/#/express/review', TN: 'https://www.ovh.com/tn/order/express/#/express/review', }, From aac3ac117ad57989e0b46acb6ea895ce8982d7b4 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Fri, 8 Nov 2024 16:11:10 +0100 Subject: [PATCH 40/43] fix(hycu): fix translations on dashboard ref: MANAGER-14488 Signed-off-by: Thibault Barske --- .../hycu/public/translations/hycu/dashboard/Messages_fr_FR.json | 1 - .../edit-display-name/EditHycuDisplayName.page.tsx | 1 - packages/manager/apps/hycu/src/utils/tests/init.i18n.ts | 2 +- .../services-actions/translations/Messages_fr_FR.json | 2 +- 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json index 0fa47ef96733..c108de86a216 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_FR.json @@ -43,7 +43,6 @@ "hycu_dashboard_browse": "Parcourir", "hycu_dashboard_update_display_name_modal_headline": "Modifier le nom", "hycu_dashboard_update_display_name_input_label": "Nom", - "hycu_dashboard_update_display_name_description": "", "hycu_dashboard_update_display_name_pattern_message": "Veuillez utiliser uniquement des lettres sans accent et les caractères spéciaux suivants : ! @ # $ % ^ & * ( ) - _ + = [ ] { } ; : , . ? (limité à 36 caractères).", "hycu_dashboard_update_display_name_success": "La description a été modifiée avec succès.", "hycu_dashboard_edit_modal_error": "Une erreur est survenue: {{error}}.", diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx index a8feeb543e6a..55a6bcbd310e 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/edit-display-name/EditHycuDisplayName.page.tsx @@ -29,7 +29,6 @@ export default function EditHycuDisplayNameModal() { closeModal={closeModal} headline={t('hycu_dashboard_update_display_name_modal_headline')} inputLabel={t('hycu_dashboard_update_display_name_input_label')} - description={t('hycu_dashboard_update_display_name_description')} resourceName={serviceName} isLoading={isLoading} pattern="^[\x00-\x7F]{1,36}$" diff --git a/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts b/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts index b7fe5979dc7a..e52f9bda6765 100644 --- a/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts +++ b/packages/manager/apps/hycu/src/utils/tests/init.i18n.ts @@ -1,5 +1,5 @@ import i18next, { i18n, InitOptions } from 'i18next'; -import error from '@ovh-ux/manager-react-components/src/components/templates/error/translations/Messages_fr_FR.json'; +import error from '@ovh-ux/manager-react-components/dist/src/components/templates/error/translations/Messages_fr_FR.json'; import common from '../../../public/translations/hycu/Messages_fr_FR.json'; import dashboard from '../../../public/translations/hycu/dashboard/Messages_fr_FR.json'; import listing from '../../../public/translations/hycu/listing/Messages_fr_FR.json'; diff --git a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_fr_FR.json b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_fr_FR.json index 0cdbedd4c1a0..1b81a70ca451 100644 --- a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_fr_FR.json +++ b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_fr_FR.json @@ -15,7 +15,7 @@ "billing_services_actions_menu_resiliate_HOSTING_WEB": "Supprimer immédiatement l'hébergement", "billing_services_actions_menu_resiliate_HOSTING_PRIVATE_DATABASE": "Supprimer mon hébergement SQL privé", "billing_services_actions_menu_resiliate_WEBCOACH": "Supprimer mon WebCoach", - "billing_services_actions_menu_resiliate_LICENSE_HYCU": "Supprimer ma license Hycu", + "billing_services_actions_menu_resiliate_LICENSE_HYCU": "Supprimer ma licence Hycu", "billing_services_actions_menu_sms_credit": "Ajouter des crédits", "billing_services_actions_menu_sms_renew": "Configurer la recharge automatique", "billing_services_actions_menu_resiliate_cancel": "Annuler la résiliation du service", From 92fc3958622d1e1f6133963a4cdc000aad65ace7 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Thu, 14 Nov 2024 17:31:04 +0100 Subject: [PATCH 41/43] feat(hycu): disabled change pack ref: MANAGER-16039 Signed-off-by: Thibault Barske --- packages/manager/apps/hycu/src/constants.ts | 2 + .../ShortcutsTile/ShortcutsTile.spec.tsx | 58 +++++-------------- .../ShortcutsTile/ShortcutsTile.tsx | 5 +- 3 files changed, 20 insertions(+), 45 deletions(-) diff --git a/packages/manager/apps/hycu/src/constants.ts b/packages/manager/apps/hycu/src/constants.ts index 278e25a9f961..719f255a8eba 100644 --- a/packages/manager/apps/hycu/src/constants.ts +++ b/packages/manager/apps/hycu/src/constants.ts @@ -8,5 +8,7 @@ export const packTypeLabel = { 'hycu-cloud-vm-pack-500': '500 VMs', } as const; +export const HYCU_CHANGE_PACK_FEATURE_ACTIVATED = false; + export const LICENSE_FILE_EXT = '.req'; export const LICENSE_FILE_NAME_TEMPLATE = `license-hycu-{serviceName}.dat`; diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx index 140cdc45935e..3fe01ab37fc9 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.spec.tsx @@ -56,48 +56,16 @@ describe('License Hycu shortcuts tile for dashboard test suite', () => { ).toBeVisible(), { timeout: 20_000 }, ); - await waitFor( - () => - expect( - screen.getByText( - labels.dashboard.hycu_dashboard_link_change_pack_type, - ), - ).toBeVisible(), - { timeout: 20_000 }, - ); - }); - - it('should show links of services activated', async () => { - await renderTestApp(`/${licensesHycu[0].serviceName}`, { - licenseStatus: LicenseStatus.ACTIVATED, - }); - - await waitFor( - () => - expect( - screen.getAllByText( - labels.dashboard.hycu_dashboard_shortcuts_title, - )[0], - ).toBeVisible(), - { timeout: 30_000 }, - ); - - await waitFor( - () => - expect( - screen.getByText(labels.dashboard.hycu_dashboard_link_regenerate), - ).toBeVisible(), - { timeout: 20_000 }, - ); - await waitFor( - () => - expect( - screen.getByText( - labels.dashboard.hycu_dashboard_link_change_pack_type, - ), - ).toBeVisible(), - { timeout: 20_000 }, - ); + // See: MANAGER-16039. Will be decommented on near future + // await waitFor( + // () => + // expect( + // screen.getByText( + // labels.dashboard.hycu_dashboard_link_change_pack_type, + // ), + // ).toBeVisible(), + // { timeout: 20_000 }, + // ); }); it('Can open activate modal with IAM authorization', async () => { @@ -214,7 +182,8 @@ describe('License Hycu shortcuts tile for dashboard test suite', () => { ); }); - it('Can open edit page with IAM authorization', async () => { + // Skip Because: MANAGER-16039. Will be uncommented on near future + it.skip('Can open edit page with IAM authorization', async () => { const user = userEvent.setup(); await renderTestApp(`/${licensesHycu[0].serviceName}`, { licenseStatus: LicenseStatus.ACTIVATED, @@ -239,7 +208,8 @@ describe('License Hycu shortcuts tile for dashboard test suite', () => { ); }); - it("Can't open edit page without IAM authorization", async () => { + // Skip because: MANAGER-16039. Will be decommented on near future + it.skip("Can't open edit page without IAM authorization", async () => { const user = userEvent.setup(); await renderTestApp(`/${licensesHycu[1].serviceName}`, { licenseStatus: LicenseStatus.ACTIVATED, diff --git a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx index b689884432ca..4afeae1e6b2e 100644 --- a/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx +++ b/packages/manager/apps/hycu/src/pages/dashboard/general-information/ShortcutsTile/ShortcutsTile.tsx @@ -17,6 +17,7 @@ import { ManagerLinkProps, } from '@/components/ManagerLink/ManagerLink.component'; import { IAM_ACTIONS } from '@/utils/iam.constants'; +import { HYCU_CHANGE_PACK_FEATURE_ACTIVATED } from '@/constants'; const ShortcutsItem = ({ children, ...rest }: ManagerLinkProps) => ( @@ -116,7 +117,9 @@ const ShortcutsTile = ({ serviceName }: { serviceName: string }) => { !hycuDetail?.data.controllerId ? links.linkActivated : links.linkReactivated, - hycuDetail?.data.licenseStatus === LicenseStatus.ACTIVATED && + ((HYCU_CHANGE_PACK_FEATURE_ACTIVATED && + hycuDetail?.data.licenseStatus === LicenseStatus.ACTIVATED) || + undefined) && links.linkChangePackType, ].filter(Boolean)} >
    From 7fc50223643dfa11a5032ab0372bd9adf570ee3b Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Wed, 20 Nov 2024 09:00:15 +0100 Subject: [PATCH 42/43] feat(hycu): update mrc package ref: MANAGER-14488 Signed-off-by: Thibault Barske --- packages/manager/apps/hycu/package.json | 3 +- yarn.lock | 67 +++++++++++++------------ 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/packages/manager/apps/hycu/package.json b/packages/manager/apps/hycu/package.json index d887f12f9989..376d1a3d5224 100644 --- a/packages/manager/apps/hycu/package.json +++ b/packages/manager/apps/hycu/package.json @@ -23,7 +23,8 @@ "@ovh-ux/manager-config": "^8.0.0", "@ovh-ux/manager-core-api": "^0.9.0", "@ovh-ux/manager-core-utils": "*", - "@ovh-ux/manager-react-components": "^1.41.1", + "@ovh-ux/manager-module-order": "^0.7.1", + "@ovh-ux/manager-react-components": "^1.41.2", "@ovh-ux/manager-react-core-application": "^0.11.1", "@ovh-ux/manager-react-shell-client": "^0.8.1", "@ovh-ux/manager-tailwind-config": "*", diff --git a/yarn.lock b/yarn.lock index 60825b0f65c5..e490461f7ce6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3198,7 +3198,22 @@ dependencies: "@floating-ui/utils" "^0.2.5" -"@floating-ui/dom@1.6.3", "@floating-ui/dom@^1.0.1", "@floating-ui/dom@^1.6.1": +"@floating-ui/core@^1.6.0": + version "1.6.8" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.8.tgz#aa43561be075815879305965020f492cdb43da12" + integrity sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA== + dependencies: + "@floating-ui/utils" "^0.2.8" + +"@floating-ui/dom@1.6.11": + version "1.6.11" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.11.tgz#8631857838d34ee5712339eb7cbdfb8ad34da723" + integrity sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ== + dependencies: + "@floating-ui/core" "^1.6.0" + "@floating-ui/utils" "^0.2.8" + +"@floating-ui/dom@^1.0.1", "@floating-ui/dom@^1.6.1": version "1.6.3" resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.3.tgz#954e46c1dd3ad48e49db9ada7218b0985cee75ef" integrity sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw== @@ -3223,6 +3238,11 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.5.tgz#105c37d9d9620ce69b7f692a20c821bf1ad2cbf9" integrity sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ== +"@floating-ui/utils@^0.2.8": + version "0.2.8" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.8.tgz#21a907684723bbbaa5f0974cf7730bd797eb8e62" + integrity sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig== + "@fortawesome/fontawesome-free@^5.11.2": version "5.15.4" resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz#ecda5712b61ac852c760d8b3c79c96adca5554e5" @@ -5307,6 +5327,11 @@ resolved "https://registry.yarnpkg.com/@ovh-ux/ui-kit/-/ui-kit-6.10.5.tgz#cdde47452edb326aa1224eb447ed40ae2b169b81" integrity sha512-0PrFAOM0/ylPlVeC6hsJMHGe+pWB/ooMrjQySH5ytqsPYZrvzuiLoecEZHmX8VbnAJ6nF63sFLGp/DuicaSiCQ== +"@ovh-ux/url-builder@^1.3.0-alpha.0": + version "1.3.0-alpha.0" + resolved "https://registry.yarnpkg.com/@ovh-ux/url-builder/-/url-builder-1.3.0-alpha.0.tgz#4627fd845c97cdabc7e78e78bbf00e45d094555a" + integrity sha512-2454x+qlS+vnpc+c/L829RG/BlNmjBAymcciNx5ZEW4ivYhY1gZ9m2QxGO6tO1AH2FD5fzlskIVTOM7iaAlm7Q== + "@ovhcloud/ods-common-core@17.2.1": version "17.2.1" resolved "https://registry.yarnpkg.com/@ovhcloud/ods-common-core/-/ods-common-core-17.2.1.tgz#c5cc5ec6dede4ddf7b8e45a52bbc3eeab5bd6812" @@ -5363,12 +5388,12 @@ "@ovhcloud/ods-common-stencil" "17.2.2" "@ovhcloud/ods-common-theming" "17.2.2" -"@ovhcloud/ods-components@18.0.0": - version "18.0.0" - resolved "https://registry.npmjs.org/@ovhcloud/ods-components/-/ods-components-18.0.0.tgz#b0e4da6c35c19004f35bac6b34abb1f78c6d1af0" - integrity sha512-Nhgi8iMX/+tWJb6D8WSN8qNqC32XEwdDL0rc7o9V0OwcXPwSqu7QtTYKB+1s1kGTDxfyl7HGrSDYbqgUI0niMw== +"@ovhcloud/ods-components@^18.3.0": + version "18.3.0" + resolved "https://registry.yarnpkg.com/@ovhcloud/ods-components/-/ods-components-18.3.0.tgz#f5fa856bb45ad7df3ebe421d64ab334f41c7206c" + integrity sha512-E2bDV7RDnNty8fR7Fbvkxug2pySmsy4BQIt9rY0VTZWtcbaUlazmKbr+l+TjeL7vRxiPR4+9xLidI1kwt26O9A== dependencies: - "@floating-ui/dom" "1.6.3" + "@floating-ui/dom" "1.6.11" "@stencil/core" "4.16.0" google-libphonenumber "3.2.35" tom-select "2.3.1" @@ -5389,10 +5414,10 @@ dependencies: "@ovhcloud/ods-common-theming" "17.2.2" -"@ovhcloud/ods-themes@18.0.0": - version "18.0.0" - resolved "https://registry.npmjs.org/@ovhcloud/ods-themes/-/ods-themes-18.0.0.tgz#0a7c658e0e9d572262ed41896fee4819c2764167" - integrity sha512-0PfXUyF6bX9emb/a6S16QThKsSXyvrNYT3n1zQF/le8tMXP7292TGKIgqXhsZmkcD9tCdD6VLXuJTS8Zv3a5Yg== +"@ovhcloud/ods-themes@^18.3.0": + version "18.3.0" + resolved "https://registry.yarnpkg.com/@ovhcloud/ods-themes/-/ods-themes-18.3.0.tgz#804e3502e6791f7ec2efc24abb107d27cd4e02e0" + integrity sha512-mTxtcM4tCUPk98x65PeslXqGONJraTryXgkbgbZuvtOYf9SgVl+zFJfyisD2sYGuJvVf6hJP1NvJkyrxOUqtSw== "@ovhcloud/reket-axios-client@^0.2.1": version "0.2.1" @@ -6827,14 +6852,6 @@ resolved "https://registry.npmjs.org/@stencil/core/-/core-4.16.0.tgz#79c430d5875e0ce3a7666607b6fb53512890577b" integrity sha512-gXaC5IrquV/Hw5JIZTCWkM5lJEbBQtnvHLhDebjar6A6+YBqxah04dardS+YUNVuRbnE6Hcja7KKiAXT3oVsvw== -"@storybook/addon-a11y@8.0.4": - version "8.0.4" - resolved "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-8.0.4.tgz#2e62ab86a016a9ed6e4b52d61e0549c2568b0923" - integrity sha512-5OyZNzjNXjNUD9vBfjxFnJjMMcBFYWyI4zy5qmJcbAvBv/COiXNfNg2cr2YPNtU5WfA6nsaIESfHFGBHI3GDAg== - dependencies: - "@storybook/addon-highlight" "8.0.4" - axe-core "^4.2.0" - "@storybook/addon-actions@7.5.3": version "7.5.3" resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-7.5.3.tgz#e0d0d819488d1d19918b23469b3ea6610fee5f07" @@ -6970,13 +6987,6 @@ "@storybook/global" "^5.0.0" "@storybook/preview-api" "7.5.3" -"@storybook/addon-highlight@8.0.4": - version "8.0.4" - resolved "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.0.4.tgz#32f21a1f850394e83277a1cd553a33c86cb603f4" - integrity sha512-tnEiVaJlXL07v8JBox+QtRPVruoy0YovOTAOWY7fKDiKzF1I9wLaJjQF3wOsvwspHTHu00OZw2gsazgXiH4wLQ== - dependencies: - "@storybook/global" "^5.0.0" - "@storybook/addon-interactions@7.5.3": version "7.5.3" resolved "https://registry.yarnpkg.com/@storybook/addon-interactions/-/addon-interactions-7.5.3.tgz#5aef96b3fa24aaafb88c0fc501f6a7e8cfa2a342" @@ -11437,11 +11447,6 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== -axe-core@^4.2.0: - version "4.10.0" - resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.10.0.tgz#d9e56ab0147278272739a000880196cdfe113b59" - integrity sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g== - axios@^0.21.1: version "0.21.4" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" @@ -30150,4 +30155,4 @@ zustand@^4.5.5: zwitch@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" - integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== \ No newline at end of file + integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== From cafbeb3760646da4ea18528ad3f94f0fd490d0d3 Mon Sep 17 00:00:00 2001 From: CDS Translator Agent Date: Wed, 20 Nov 2024 08:38:40 +0000 Subject: [PATCH 43/43] fix(i18n): add missing translations [CDS 3494] Signed-off-by: CDS Translator Agent --- .../translations/hycu/Messages_de_DE.json | 12 ++++- .../translations/hycu/Messages_en_GB.json | 12 ++++- .../translations/hycu/Messages_es_ES.json | 12 ++++- .../translations/hycu/Messages_fr_CA.json | 13 +++-- .../translations/hycu/Messages_it_IT.json | 12 ++++- .../translations/hycu/Messages_pl_PL.json | 12 ++++- .../translations/hycu/Messages_pt_PT.json | 12 ++++- .../hycu/dashboard/Messages_de_DE.json | 51 +++++++++++++++++++ .../hycu/dashboard/Messages_en_GB.json | 51 +++++++++++++++++++ .../hycu/dashboard/Messages_es_ES.json | 51 +++++++++++++++++++ .../hycu/dashboard/Messages_fr_CA.json | 51 +++++++++++++++++++ .../hycu/dashboard/Messages_it_IT.json | 51 +++++++++++++++++++ .../hycu/dashboard/Messages_pl_PL.json | 51 +++++++++++++++++++ .../hycu/dashboard/Messages_pt_PT.json | 51 +++++++++++++++++++ .../hycu/edit-pack/Messages_de_DE.json | 9 ++++ .../hycu/edit-pack/Messages_en_GB.json | 9 ++++ .../hycu/edit-pack/Messages_es_ES.json | 9 ++++ .../hycu/edit-pack/Messages_fr_CA.json | 9 ++++ .../hycu/edit-pack/Messages_it_IT.json | 9 ++++ .../hycu/edit-pack/Messages_pl_PL.json | 9 ++++ .../hycu/edit-pack/Messages_pt_PT.json | 9 ++++ .../hycu/listing/Messages_de_DE.json | 3 +- .../hycu/listing/Messages_en_GB.json | 3 +- .../hycu/listing/Messages_es_ES.json | 3 +- .../hycu/listing/Messages_fr_CA.json | 7 +-- .../hycu/listing/Messages_it_IT.json | 3 +- .../hycu/listing/Messages_pl_PL.json | 3 +- .../hycu/listing/Messages_pt_PT.json | 3 +- .../hycu/onboarding/Messages_de_DE.json | 4 +- .../hycu/onboarding/Messages_en_GB.json | 2 +- .../hycu/onboarding/Messages_es_ES.json | 4 +- .../hycu/onboarding/Messages_fr_CA.json | 6 +-- .../hycu/onboarding/Messages_it_IT.json | 4 +- .../hycu/onboarding/Messages_pl_PL.json | 2 +- .../hycu/onboarding/Messages_pt_PT.json | 4 +- .../hycu/order/Messages_de_DE.json | 9 ++++ .../hycu/order/Messages_en_GB.json | 9 ++++ .../hycu/order/Messages_es_ES.json | 9 ++++ .../hycu/order/Messages_fr_CA.json | 9 ++++ .../hycu/order/Messages_it_IT.json | 9 ++++ .../hycu/order/Messages_pl_PL.json | 9 ++++ .../hycu/order/Messages_pt_PT.json | 9 ++++ .../hycu/terminate/Messages_de_DE.json | 9 ++++ .../hycu/terminate/Messages_en_GB.json | 9 ++++ .../hycu/terminate/Messages_es_ES.json | 9 ++++ .../hycu/terminate/Messages_fr_CA.json | 9 ++++ .../hycu/terminate/Messages_it_IT.json | 9 ++++ .../hycu/terminate/Messages_pl_PL.json | 9 ++++ .../hycu/terminate/Messages_pt_PT.json | 9 ++++ .../translations/Messages_de_DE.json | 3 +- .../translations/Messages_en_GB.json | 3 +- .../translations/Messages_es_ES.json | 3 +- .../translations/Messages_fr_CA.json | 1 + .../translations/Messages_it_IT.json | 3 +- .../translations/Messages_pl_PL.json | 3 +- .../translations/Messages_pt_PT.json | 3 +- .../translations/Messages_de_DE.json | 6 ++- .../translations/Messages_en_GB.json | 6 ++- .../translations/Messages_es_ES.json | 6 ++- .../translations/Messages_fr_CA.json | 4 ++ .../translations/Messages_it_IT.json | 6 ++- .../translations/Messages_pl_PL.json | 6 ++- .../translations/Messages_pt_PT.json | 6 ++- .../translations/Messages_de_DE.json | 3 +- .../translations/Messages_en_GB.json | 3 +- .../translations/Messages_es_ES.json | 3 +- .../translations/Messages_fr_CA.json | 1 + .../translations/Messages_it_IT.json | 3 +- .../translations/Messages_pl_PL.json | 3 +- .../translations/Messages_pt_PT.json | 3 +- .../products/translations/Messages_de_DE.json | 3 +- .../products/translations/Messages_en_GB.json | 3 +- .../products/translations/Messages_es_ES.json | 3 +- .../products/translations/Messages_fr_CA.json | 1 + .../products/translations/Messages_it_IT.json | 3 +- .../products/translations/Messages_pl_PL.json | 3 +- .../products/translations/Messages_pt_PT.json | 3 +- 77 files changed, 716 insertions(+), 63 deletions(-) create mode 100644 packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_de_DE.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_en_GB.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_es_ES.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_CA.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_it_IT.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_pl_PL.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_pt_PT.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_de_DE.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_en_GB.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_es_ES.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_fr_CA.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_it_IT.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_pl_PL.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_pt_PT.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/order/Messages_de_DE.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/order/Messages_en_GB.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/order/Messages_es_ES.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/order/Messages_fr_CA.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/order/Messages_it_IT.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/order/Messages_pl_PL.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/order/Messages_pt_PT.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_de_DE.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_en_GB.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_es_ES.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_fr_CA.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_it_IT.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_pl_PL.json create mode 100644 packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_pt_PT.json diff --git a/packages/manager/apps/hycu/public/translations/hycu/Messages_de_DE.json b/packages/manager/apps/hycu/public/translations/hycu/Messages_de_DE.json index b679b7e2b9d5..ad68fa34793d 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/Messages_de_DE.json +++ b/packages/manager/apps/hycu/public/translations/hycu/Messages_de_DE.json @@ -1,6 +1,14 @@ { "hycu_crumb": "HYCU", "tabs_2": "Tabs 2", - "hycu_description": "Vereinfachen Sie die Backups, Disaster-Recovery-Pläne und Migrationen Ihrer Nutanix-Infrastruktur. Dieser Dienst bietet verschiedene HYCU Hybrid Cloud-Lizenzpakete zum Schutz Ihrer Nutanix-Workloads.", - "hycu_cloud_vm_pack_unknown": "Unbekanntes Paket" + "hycu_description": "Vereinfachen Sie die Backups, Disaster-Recovery-Pläne und Migrationen Ihrer Nutanix-Infrastruktur. Dieser Dienst bietet verschiedene Lizenzpakete der HYCU R-Cloud Hybrid Cloud Edition zum Schutz Ihrer Nutanix-Workloads.", + "hycu_cloud_vm_pack_unknown": "Unbekanntes Paket", + "hycu_status_active": "Aktiv", + "hycu_status_toActivate": "Zu aktivieren", + "hycu_status_processing": "Wird aktiviert", + "hycu_status_error": "Aktivierungsfehler", + "hycu_cta_cancel": "Abbrechen", + "hycu_cta_order": "Bestellen", + "hycu_cta_done": "Beenden", + "common_iam_actions_message": "Sie sind nicht berechtigt, diese Aktion auszuführen. Wenden Sie sich an Ihren Administrator." } diff --git a/packages/manager/apps/hycu/public/translations/hycu/Messages_en_GB.json b/packages/manager/apps/hycu/public/translations/hycu/Messages_en_GB.json index 9cd1d4ee43c2..be93898b5f3d 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/Messages_en_GB.json +++ b/packages/manager/apps/hycu/public/translations/hycu/Messages_en_GB.json @@ -1,6 +1,14 @@ { "hycu_crumb": "HYCU", "tabs_2": "Tabs 2", - "hycu_description": "Simplify your backups, disaster recovery plans, and migrations for your Nutanix infrastructure. This service offers different Hybrid Cloud HYCU license packs to protect your Nutanix workloads.", - "hycu_cloud_vm_pack_unknown": "Unknown pack" + "hycu_description": "Simplify your backups, disaster recovery plans, and migrations for your Nutanix infrastructure. This service offers different HYCU R-Cloud Hybrid Cloud Edition licence packs to protect your Nutanix workloads.", + "hycu_cloud_vm_pack_unknown": "Unknown pack", + "hycu_status_active": "Active", + "hycu_status_toActivate": "Enabling required", + "hycu_status_processing": "Enabling...", + "hycu_status_error": "Activation error", + "hycu_cta_cancel": "Cancel", + "hycu_cta_order": "Order", + "hycu_cta_done": "Finish", + "common_iam_actions_message": "You do not have the necessary permissions to perform this action, please contact your administrator" } diff --git a/packages/manager/apps/hycu/public/translations/hycu/Messages_es_ES.json b/packages/manager/apps/hycu/public/translations/hycu/Messages_es_ES.json index effb4b1d0b44..0007cf786fc7 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/Messages_es_ES.json +++ b/packages/manager/apps/hycu/public/translations/hycu/Messages_es_ES.json @@ -1,6 +1,14 @@ { "hycu_crumb": "HYCU", "tabs_2": "Tabs 2", - "hycu_description": "Simplifique sus copias de seguridad, planes de recuperación ante desastres y migraciones de su infraestructura Nutanix. Este servicio le ofrece diferentes packs de licencias HYCU Hybrid Cloud para proteger sus cargas de trabajo Nutanix.", - "hycu_cloud_vm_pack_unknown": "Pack desconocido" + "hycu_description": "Simplifique sus copias de seguridad, planes de recuperación ante desastres y migraciones de su infraestructura Nutanix. Este servicio ofrece diferentes packs de licencias HYCU R-Cloud Hybrid Cloud Edition para proteger sus cargas de trabajo Nutanix.", + "hycu_cloud_vm_pack_unknown": "Pack desconocido", + "hycu_status_active": "Activo", + "hycu_status_toActivate": "Pendiente de activar", + "hycu_status_processing": "En proceso de activación", + "hycu_status_error": "Error de activación", + "hycu_cta_cancel": "Cancelar", + "hycu_cta_order": "Contratar", + "hycu_cta_done": "Finalizar", + "common_iam_actions_message": "Si no dispone de los permisos necesarios para realizar esta acción, póngase en contacto con su administrador." } diff --git a/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_CA.json b/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_CA.json index 36d8b913e6d9..0fbcac9a8230 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_CA.json +++ b/packages/manager/apps/hycu/public/translations/hycu/Messages_fr_CA.json @@ -1,6 +1,13 @@ { "hycu_crumb": "HYCU", - "tabs_2": "Tabs 2", - "hycu_description": "Simplifiez vos sauvegardes, plans de reprise après sinistre et migrations de votre infrastructure Nutanix. Ce service vous propose différents packs de licences HYCU Hybrid Cloud pour protéger vos charges de travail Nutanix.", - "hycu_cloud_vm_pack_unknown": "Pack inconnu" + "hycu_description": "Simplifiez vos sauvegardes, plans de reprise après sinistre et migrations de votre infrastructure Nutanix. Ce service vous propose différents packs de licences HYCU R-Cloud Hybrid Cloud Edition pour protéger vos charges de travail Nutanix.", + "hycu_cloud_vm_pack_unknown": "Pack inconnu", + "hycu_status_active": "Active", + "hycu_status_toActivate": "À activer", + "hycu_status_processing": "En cours d'activation", + "hycu_status_error": "Erreur d'activation", + "hycu_cta_cancel": "Annuler", + "hycu_cta_order": "Commander", + "hycu_cta_done": "Terminer", + "common_iam_actions_message": "Vous ne disposez pas des permissions nécessaires pour effectuer cette action, veuillez contacter votre administrateur" } diff --git a/packages/manager/apps/hycu/public/translations/hycu/Messages_it_IT.json b/packages/manager/apps/hycu/public/translations/hycu/Messages_it_IT.json index c5dd5921224c..1babaab248a6 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/Messages_it_IT.json +++ b/packages/manager/apps/hycu/public/translations/hycu/Messages_it_IT.json @@ -1,6 +1,14 @@ { "hycu_crumb": "HYCU", "tabs_2": "Tabs 2", - "hycu_description": "Semplifica i tuoi backup, piani di disaster recovery e migrazioni dell'infrastruttura Nutanix. Questo servizio propone diversi pacchetti di licenze HYCU Hybrid Cloud per proteggere i tuoi carichi di lavoro Nutanix.", - "hycu_cloud_vm_pack_unknown": "Pack sconosciuto" + "hycu_description": "Semplifica i tuoi backup, piani di disaster recovery e migrazioni dell'infrastruttura Nutanix. Questo servizio propone diversi pack di licenze HYCU R-Cloud Hybrid Cloud Edition per proteggere i tuoi carichi di lavoro Nutanix.", + "hycu_cloud_vm_pack_unknown": "Pack sconosciuto", + "hycu_status_active": "Attivo", + "hycu_status_toActivate": "Da attivare", + "hycu_status_processing": "Attivazione in corso...", + "hycu_status_error": "Errore di attivazione", + "hycu_cta_cancel": "Annullare", + "hycu_cta_order": "Ordinare", + "hycu_cta_done": "Terminare", + "common_iam_actions_message": "Non disponi dei permessi necessari per effettuare questa azione, contatta l'amministratore." } diff --git a/packages/manager/apps/hycu/public/translations/hycu/Messages_pl_PL.json b/packages/manager/apps/hycu/public/translations/hycu/Messages_pl_PL.json index 01f8a9dfd55b..c74caaba9ad9 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/Messages_pl_PL.json +++ b/packages/manager/apps/hycu/public/translations/hycu/Messages_pl_PL.json @@ -1,6 +1,14 @@ { "hycu_crumb": "HYCU", "tabs_2": "Tabs 2", - "hycu_description": "Uprość tworzenie kopii zapasowych, odzyskiwanie danych po awarii i migrację infrastruktury Nutanix. Usługa ta zawiera różne pakiety licencji HYCU Hybrid Cloud, które chronią obciążenia Nutanix.", - "hycu_cloud_vm_pack_unknown": "Nieznany pakiet" + "hycu_description": "Uprość tworzenie kopii zapasowych, odzyskiwanie danych po awarii i migrację infrastruktury Nutanix. Usługa zawiera różne pakiety licencji HYCU R-Cloud Hybrid Cloud Edition przeznaczone do ochrony obciążeń Nutanix.", + "hycu_cloud_vm_pack_unknown": "Nieznany pakiet", + "hycu_status_active": "Aktywny", + "hycu_status_toActivate": "Do aktywacji", + "hycu_status_processing": "Trwa aktywacja", + "hycu_status_error": "Błąd aktywacji", + "hycu_cta_cancel": "Anuluj", + "hycu_cta_order": "Zamów", + "hycu_cta_done": "Zakończ", + "common_iam_actions_message": "Nie masz wystarczających uprawnień, aby wykonać tę operację. Skontaktuj się z administratorem" } diff --git a/packages/manager/apps/hycu/public/translations/hycu/Messages_pt_PT.json b/packages/manager/apps/hycu/public/translations/hycu/Messages_pt_PT.json index d0a43fb5f55c..33d86f1b08c7 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/Messages_pt_PT.json +++ b/packages/manager/apps/hycu/public/translations/hycu/Messages_pt_PT.json @@ -1,6 +1,14 @@ { "hycu_crumb": "HYCU", "tabs_2": "Tabs 2", - "hycu_description": "Simplifique backups, planos de recuperação de desastres e migrações da sua infraestrutura Nutanix. Este serviço disponibiliza diferentes pacotes de licenças HYCU Hybrid Cloud para proteger as suas cargas de trabalho Nutanix.", - "hycu_cloud_vm_pack_unknown": "Pack desconhecido" + "hycu_description": "Simplifique backups, planos de recuperação de desastres e migrações da sua infraestrutura Nutanix. Este serviço propõe-lhe diferentes packs de licenças HYCU R-Cloud Hybrid Cloud Edition para proteger as suas cargas de trabalho Nutanix.", + "hycu_cloud_vm_pack_unknown": "Pack desconhecido", + "hycu_status_active": "Ativo", + "hycu_status_toActivate": "A ativar", + "hycu_status_processing": "Ativação em curso", + "hycu_status_error": "Erro de ativação", + "hycu_cta_cancel": "Anular", + "hycu_cta_order": "Encomendar", + "hycu_cta_done": "Concluir", + "common_iam_actions_message": "Não tem as permissões necessárias para efetuar esta ação, contacte o seu administrador." } diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_de_DE.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_de_DE.json new file mode 100644 index 000000000000..52259e752e7d --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_de_DE.json @@ -0,0 +1,51 @@ +{ + "hycu_dashboard_generals_informations_title": "Allgemeine Informationen", + "hycu_dashboard_label_name": "Name", + "hycu_dashboard_label_status": "Status", + "hycu_dashboard_label_pack_type": "Paket-Typ", + "hycu_dashboard_label_controller_id": "Controller-ID", + "hycu_dashboard_label_license_key": "Lizenzschlüssel", + "hycu_dashboard_shortcuts_title": "Shortcuts", + "hycu_dashboard_link_activate": "Lizenz aktivieren", + "hycu_dashboard_link_regenerate": "Lizenz neu generieren", + "hycu_dashboard_link_terminate": "Lizenz kündigen", + "hycu_dashboard_link_change_pack_type": "Pakettyp ändern", + "hycu_dashboard_field_label_contacts": "Kontakte", + "hycu_dashboard_contact_type_administrator": "Administrator", + "hycu_dashboard_contact_type_technical": "Technisch", + "hycu_dashboard_contact_type_billing": "Abrechnung", + "hycu_dashboard_action_billing_terminate": "Kündigen", + "hycu_dashboard_field_label_manage_contacts": "Kontakte verwalten", + "hycu_dashboard_label_renew": "Automatische Verlängerung", + "hycu_dashboard_subscription_title": "Abonnement", + "hycu_dashboard_field_label_date_creation": "Erstellungsdatum", + "hycu_dashboard_download_license_file": "Lizenz herunterladen", + "hycu_dashboard_back_link": "Zurück zur Liste", + "hycu_dashboard_wait_for_activation": "Warten auf Aktivierung", + "hycu_dashboard_license_activate_heading": "Lizenz aktivieren", + "hycu_dashboard_license_activate_description": "Bitte übermitteln Sie Ihre Lizenzanforderungsdatei. Diese Datei kann nach der Installation über Ihren HYCU-Controller heruntergeladen werden", + "hycu_dashboard_license_more_information_link": "(weitere Informationen finden Sie hier).", + "hycu_dashboard_activation_license_success_message": "Die Anfrage zur Aktivierung Ihrer Lizenz wurde registriert. Ihre Lizenzdatei wird in Kürze auf diesem Interface verfügbar sein und Ihnen auch per E-Mail zugesandt.", + "hycu_dashboard_regenerate_success_message": "Die Anfrage zur Erneuerung Ihrer Lizenz wurde registriert. Ihre Lizenzdatei wird in Kürze auf diesem Interface verfügbar sein und Ihnen auch per E-Mail zugesandt.", + "hycu_dashboard_activation_license_error_message": "Bei der Einreichung Ihrer Lizenz ist ein Fehler aufgetreten: {{error}}.", + "hycu_dashboard_regenerate_error_message": "Bei der Einreichung Ihrer Lizenz ist ein Fehler aufgetreten.", + "hycu_dashboard_license_regenerate_heading": "Lizenz neu generieren", + "hycu_dashboard_license_regenerate_description": "Wenn sich Ihre technische HYCU-Umgebung geändert hat, müssen Sie eine neue Lizenzdatei anfordern, die mit Ihrem HYCU-Controller kompatibel ist. Bitte übermitteln Sie Ihre neue Lizenzanforderungsdatei. Mit dieser Aktion erklären Sie sich außerdem damit einverstanden, die zuvor bereitgestellte Lizenzdatei nicht mehr zu verwenden.", + "hycu_dashboard_license_upload": "Upload", + "hycu_dashboard_regenerate_upload_confirm": "Neu generieren", + "hycu_dashboard_upload_cancel": "Abbrechen", + "hycu_dashboard_upload_confirm": "Aktivieren", + "hycu_dashboard_upload_file_too_big": "Die Datei darf nicht größer als 1 MB sein.", + "hycu_dashboard_upload_file_bad_type": "Die bereitgestellte Datei ist keine{{extension}}-Datei.", + "hycu_dashboard_upload_license_required": "Bitte wählen Sie eine Lizenz aus.", + "hycu_dashboard_drag_and_drop_attachment": "Anhang ziehen und ablegen", + "hycu_dashboard_accepted_formats": "Akzeptiertes Format: {{extension}}", + "hycu_dashboard_browse": "Durchsuchen", + "hycu_dashboard_update_display_name_modal_headline": "Namen ändern", + "hycu_dashboard_update_display_name_input_label": "Name", + "hycu_dashboard_update_display_name_pattern_message": "Bitte verwenden Sie nur Buchstaben ohne Akzent und die folgenden Sonderzeichen:! @ # $ % ^ & * ( ) - _ + = [ ] { } ; : , . ? (auf 36 Zeichen begrenzt).", + "hycu_dashboard_update_display_name_success": "Die Beschreibung wurde erfolgreich geändert.", + "hycu_dashboard_edit_modal_error": "Es ist ein Fehler aufgetreten: {{error}}.", + "hycu_dashboard_error_license_message": "Bei der Aktivierung Ihrer Lizenz ist ein Fehler aufgetreten ({{error}}). Bitte überprüfen Sie Ihre Angaben und versuchen Sie es erneut. Sollte das Problem weiterhin bestehen, kontaktieren Sie bitte unseren Support.", + "hycu_dashboard_warning_license_suspended_message": "Der Dienst wurde gekündigt." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_en_GB.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_en_GB.json new file mode 100644 index 000000000000..58efa2f434ad --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_en_GB.json @@ -0,0 +1,51 @@ +{ + "hycu_dashboard_generals_informations_title": "General information", + "hycu_dashboard_label_name": "Name", + "hycu_dashboard_label_status": "Status", + "hycu_dashboard_label_pack_type": "Pack type", + "hycu_dashboard_label_controller_id": "Controller ID", + "hycu_dashboard_label_license_key": "Licence key", + "hycu_dashboard_shortcuts_title": "Shortcuts", + "hycu_dashboard_link_activate": "Activate licence", + "hycu_dashboard_link_regenerate": "Re-generate licence", + "hycu_dashboard_link_terminate": "Cancel licence", + "hycu_dashboard_link_change_pack_type": "Change pack type", + "hycu_dashboard_field_label_contacts": "Contacts", + "hycu_dashboard_contact_type_administrator": "Administrator", + "hycu_dashboard_contact_type_technical": "Technical", + "hycu_dashboard_contact_type_billing": "Billing", + "hycu_dashboard_action_billing_terminate": "Terminate", + "hycu_dashboard_field_label_manage_contacts": "Manage contacts", + "hycu_dashboard_label_renew": "Automatic renewal", + "hycu_dashboard_subscription_title": "Subscription", + "hycu_dashboard_field_label_date_creation": "Created on", + "hycu_dashboard_download_license_file": "Download licence", + "hycu_dashboard_back_link": "Back to list", + "hycu_dashboard_wait_for_activation": "Pending activation", + "hycu_dashboard_license_activate_heading": "Activate licence", + "hycu_dashboard_license_activate_description": "Please upload your licence request file. After installation is complete, you can download this file from your HYCU controller.", + "hycu_dashboard_license_more_information_link": "(more details here).", + "hycu_dashboard_activation_license_success_message": "Your licence activation request has been processed. Your licence file will be available on this interface shortly. It will also be sent to you via email.", + "hycu_dashboard_regenerate_success_message": "Your licence re-generation request has been processed. Your licence file will be available on this interface shortly. It will also be sent to you via email.", + "hycu_dashboard_activation_license_error_message": "An error has occurred submitting your licence: {{error}}.", + "hycu_dashboard_regenerate_error_message": "An error has occurred submitting your licence.", + "hycu_dashboard_license_regenerate_heading": "Re-generate licence", + "hycu_dashboard_license_regenerate_description": "If your HYCU technical setup has changed, you will need to submit a new request to obtain a new licence file that is compatible with your HYCU controller. Please upload a new licence request file. By performing this action, you also agree to no longer use the previously provided licence file.", + "hycu_dashboard_license_upload": "Upload", + "hycu_dashboard_regenerate_upload_confirm": "Regenerate ", + "hycu_dashboard_upload_cancel": "Cancel", + "hycu_dashboard_upload_confirm": "Enable", + "hycu_dashboard_upload_file_too_big": "File size limit: 1 MB", + "hycu_dashboard_upload_file_bad_type": "The file provided is not a {{extension}} file", + "hycu_dashboard_upload_license_required": "Please select a licence", + "hycu_dashboard_drag_and_drop_attachment": "Drag and drop an attachment", + "hycu_dashboard_accepted_formats": "Supported format: {{extension}}", + "hycu_dashboard_browse": "Browse", + "hycu_dashboard_update_display_name_modal_headline": "Change name", + "hycu_dashboard_update_display_name_input_label": "Name", + "hycu_dashboard_update_display_name_pattern_message": "Must contain unaccented letters and the following special characters: ! @ # $ % ^ & * ( ) - _ + = [ ] { } ; : , . ? (limited to 36 characters).", + "hycu_dashboard_update_display_name_success": "The description has been modified.", + "hycu_dashboard_edit_modal_error": "An error has occurred: {{error}}.", + "hycu_dashboard_error_license_message": "An error has occurred activating your licence ({{error}}). Please check the information provided and try again. If the problem persists, please contact our support team.", + "hycu_dashboard_warning_license_suspended_message": "The service has been cancelled." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_es_ES.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_es_ES.json new file mode 100644 index 000000000000..dc051b6152a6 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_es_ES.json @@ -0,0 +1,51 @@ +{ + "hycu_dashboard_generals_informations_title": "Información general", + "hycu_dashboard_label_name": "Apellido", + "hycu_dashboard_label_status": "Estado", + "hycu_dashboard_label_pack_type": "Tipo de pack", + "hycu_dashboard_label_controller_id": "Controller ID", + "hycu_dashboard_label_license_key": "Clave de licencia", + "hycu_dashboard_shortcuts_title": "Atajos", + "hycu_dashboard_link_activate": "Activar la licencia", + "hycu_dashboard_link_regenerate": "Regenerar la licencia", + "hycu_dashboard_link_terminate": "Dar de baja la licencia", + "hycu_dashboard_link_change_pack_type": "Cambiar el tipo de pack", + "hycu_dashboard_field_label_contacts": "Contactos", + "hycu_dashboard_contact_type_administrator": "Administrador", + "hycu_dashboard_contact_type_technical": "Técnico", + "hycu_dashboard_contact_type_billing": "Facturación", + "hycu_dashboard_action_billing_terminate": "Dar de baja", + "hycu_dashboard_field_label_manage_contacts": "Editar los contactos", + "hycu_dashboard_label_renew": "Renovación automática", + "hycu_dashboard_subscription_title": "Suscripción", + "hycu_dashboard_field_label_date_creation": "Fecha de creación", + "hycu_dashboard_download_license_file": "Descargar la licencia", + "hycu_dashboard_back_link": "Volver a la lista", + "hycu_dashboard_wait_for_activation": "Pendiente de activación", + "hycu_dashboard_license_activate_heading": "Activar la licencia", + "hycu_dashboard_license_activate_description": "Por favor, transfiera su archivo de solicitud de licencia. Una vez completada la instalación, deberá descargar este archivo desde el controlador HYCU", + "hycu_dashboard_license_more_information_link": "(más información aquí).", + "hycu_dashboard_activation_license_success_message": "La solicitud de activación de su licencia se ha enviado. Su archivo de licencia estará disponible dentro de poco en esta interfaz. También lo recibirá por correo electrónico.", + "hycu_dashboard_regenerate_success_message": "La solicitud de regeneración de la licencia se ha enviado. Su archivo de licencia estará disponible dentro de poco en esta interfaz. También lo recibirá por correo electrónico.", + "hycu_dashboard_activation_license_error_message": "Se ha producido un error al enviar la licencia: {{error}}.", + "hycu_dashboard_regenerate_error_message": "Se ha producido un error al enviar la licencia.", + "hycu_dashboard_license_regenerate_heading": "Regenerar la licencia", + "hycu_dashboard_license_regenerate_description": "Si el entorno técnico HYCU ha cambiado, deberá enviar una nueva solicitud para obtener un nuevo archivo de licencia compatible con su controlador HYCU. Por favor, transfiera su nuevo archivo de solicitud de licencia. Al realizar esta acción, se compromete a no utilizar el archivo de licencia anteriormente proporcionado.", + "hycu_dashboard_license_upload": "Subida", + "hycu_dashboard_regenerate_upload_confirm": "Regenerar", + "hycu_dashboard_upload_cancel": "Cancelar", + "hycu_dashboard_upload_confirm": "Activar", + "hycu_dashboard_upload_file_too_big": "El tamaño del archivo no puede superar 1 MB", + "hycu_dashboard_upload_file_bad_type": "El archivo proporcionado no es un archivo {{extension}}", + "hycu_dashboard_upload_license_required": "Seleccione una licencia", + "hycu_dashboard_drag_and_drop_attachment": "Arrastrar y soltar un archivo adjunto", + "hycu_dashboard_accepted_formats": "Formato aceptado: {{extension}}", + "hycu_dashboard_browse": "Examinar", + "hycu_dashboard_update_display_name_modal_headline": "Editar el nombre", + "hycu_dashboard_update_display_name_input_label": "Apellido", + "hycu_dashboard_update_display_name_pattern_message": "Por favor, utilice solo letras sin acento y los siguientes caracteres especiales: ! @ # $ % ^ & * ( ) - _ + = [ ] { } ; : , . ? (máximo 36 caracteres).", + "hycu_dashboard_update_display_name_success": "La descripción se ha modificado correctamente.", + "hycu_dashboard_edit_modal_error": "Se ha producido un error: {{error}}.", + "hycu_dashboard_error_license_message": "Se ha producido un error al activar la licencia ({{error}}). Por favor, compruebe la información proporcionada y vuelva a intentarlo. Si el problema persiste, contacte con nuestro equipo de soporte.", + "hycu_dashboard_warning_license_suspended_message": "El servicio se ha dado de baja." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_CA.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_CA.json new file mode 100644 index 000000000000..c108de86a216 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_fr_CA.json @@ -0,0 +1,51 @@ +{ + "hycu_dashboard_generals_informations_title": "Informations générales", + "hycu_dashboard_label_name": "Nom", + "hycu_dashboard_label_status": "Statut", + "hycu_dashboard_label_pack_type": "Type de pack", + "hycu_dashboard_label_controller_id": "Controller ID", + "hycu_dashboard_label_license_key": "Clé de licence", + "hycu_dashboard_shortcuts_title": "Raccourcis", + "hycu_dashboard_link_activate": "Activer la licence", + "hycu_dashboard_link_regenerate": "Regénérer la licence", + "hycu_dashboard_link_terminate": "Résilier la licence", + "hycu_dashboard_link_change_pack_type": "Modifier le type de pack", + "hycu_dashboard_field_label_contacts": "Contacts", + "hycu_dashboard_contact_type_administrator": "Administrateur", + "hycu_dashboard_contact_type_technical": "Technique", + "hycu_dashboard_contact_type_billing": "Facturation", + "hycu_dashboard_action_billing_terminate": "Résilier", + "hycu_dashboard_field_label_manage_contacts": "Gérer les contacts", + "hycu_dashboard_label_renew": "Renouvellement automatique", + "hycu_dashboard_subscription_title": "Abonnement", + "hycu_dashboard_field_label_date_creation": "Date de création", + "hycu_dashboard_download_license_file": "Télécharger la licence", + "hycu_dashboard_back_link": "Retour à la liste", + "hycu_dashboard_wait_for_activation": "En attente d'activation", + "hycu_dashboard_license_activate_heading": "Activer la licence", + "hycu_dashboard_license_activate_description": "Veuillez transférer votre fichier de demande de licence. Ce fichier est à télécharger depuis votre controller HYCU une fois votre installation réalisée", + "hycu_dashboard_license_more_information_link": "(plus de détails ici).", + "hycu_dashboard_activation_license_success_message": "La demande d'activation de votre licence a bien été prise en compte. Votre fichier de licence sera bientôt disponible sur cette interface et vous sera également envoyé par e-mail.", + "hycu_dashboard_regenerate_success_message": "La demande de regénération de votre licence a bien été prise en compte. Votre fichier de licence sera bientôt disponible sur cette interface et vous sera également envoyé par e-mail.", + "hycu_dashboard_activation_license_error_message": "Une erreur est survenue lors de la soumission de votre licence : {{error}}.", + "hycu_dashboard_regenerate_error_message": "Une erreur est survenue lors de la soumission de votre licence.", + "hycu_dashboard_license_regenerate_heading": "Regénérer la licence", + "hycu_dashboard_license_regenerate_description": "Si votre environnement technique HYCU a changé, il est nécessaire de soumettre une nouvelle demande afin d'obtenir un nouveau fichier de licence compatible avec votre controller HYCU. Veuillez transférer votre nouveau fichier de demande de licence. En réalisant cette action, vous vous engagez également à ne plus utiliser le fichier de licence précédemment fourni.", + "hycu_dashboard_license_upload": "Upload", + "hycu_dashboard_regenerate_upload_confirm": "Regénérer", + "hycu_dashboard_upload_cancel": "Annuler", + "hycu_dashboard_upload_confirm": "Activer", + "hycu_dashboard_upload_file_too_big": "La taille du fichier ne peut pas excéder 1Mo", + "hycu_dashboard_upload_file_bad_type": "Le fichier fourni n'est pas un fichier {{extension}}", + "hycu_dashboard_upload_license_required": "Veuillez sélectionner une licence", + "hycu_dashboard_drag_and_drop_attachment": "Glissez-Déposer une pièce jointe", + "hycu_dashboard_accepted_formats": "Format accepté: {{extension}}", + "hycu_dashboard_browse": "Parcourir", + "hycu_dashboard_update_display_name_modal_headline": "Modifier le nom", + "hycu_dashboard_update_display_name_input_label": "Nom", + "hycu_dashboard_update_display_name_pattern_message": "Veuillez utiliser uniquement des lettres sans accent et les caractères spéciaux suivants : ! @ # $ % ^ & * ( ) - _ + = [ ] { } ; : , . ? (limité à 36 caractères).", + "hycu_dashboard_update_display_name_success": "La description a été modifiée avec succès.", + "hycu_dashboard_edit_modal_error": "Une erreur est survenue: {{error}}.", + "hycu_dashboard_error_license_message": "Une erreur est survenue lors de l'activation de votre licence ({{error}}). Nous vous invitons à vérifier les informations fournies et à réaliser une nouvelle tentative. Si le problème persiste, veuillez contacter notre support.", + "hycu_dashboard_warning_license_suspended_message": "Le service a été résilié." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_it_IT.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_it_IT.json new file mode 100644 index 000000000000..a3645a8b0043 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_it_IT.json @@ -0,0 +1,51 @@ +{ + "hycu_dashboard_generals_informations_title": "Informazioni generali", + "hycu_dashboard_label_name": "Cognome", + "hycu_dashboard_label_status": "Stato", + "hycu_dashboard_label_pack_type": "Tipo di pack", + "hycu_dashboard_label_controller_id": "Controller ID", + "hycu_dashboard_label_license_key": "Chiave di licenza", + "hycu_dashboard_shortcuts_title": "Scelte rapide", + "hycu_dashboard_link_activate": "Attivare la licenza", + "hycu_dashboard_link_regenerate": "Rigenerare la licenza", + "hycu_dashboard_link_terminate": "Disattivare la licenza", + "hycu_dashboard_link_change_pack_type": "Modificare il tipo di pack", + "hycu_dashboard_field_label_contacts": "Contatti", + "hycu_dashboard_contact_type_administrator": "Amministratore", + "hycu_dashboard_contact_type_technical": "Tecnico", + "hycu_dashboard_contact_type_billing": "Fatturazione", + "hycu_dashboard_action_billing_terminate": "Disattivare", + "hycu_dashboard_field_label_manage_contacts": "Gestisci i contatti", + "hycu_dashboard_label_renew": "Rinnovo automatico", + "hycu_dashboard_subscription_title": "Abbonamento", + "hycu_dashboard_field_label_date_creation": "Data di creazione", + "hycu_dashboard_download_license_file": "Scaricare la licenza", + "hycu_dashboard_back_link": "Torna alla lista", + "hycu_dashboard_wait_for_activation": "In attesa di attivazione", + "hycu_dashboard_license_activate_heading": "Attivare la licenza", + "hycu_dashboard_license_activate_description": "Trasferisci il tuo file di richiesta della licenza. Una volta realizzata l’installazione, questo file deve essere scaricato dal controller HYCU", + "hycu_dashboard_license_more_information_link": "(più dettagli qui).", + "hycu_dashboard_activation_license_success_message": "La richiesta di attivazione della tua licenza è stata presa in carico. Il tuo file di licenza sarà presto disponibile in questa interfaccia e verrà inviato anche tramite email.", + "hycu_dashboard_regenerate_success_message": "La richiesta di rigenerazione della tua licenza è stata presa in carico. Il tuo file di licenza sarà presto disponibile in questa interfaccia e verrà inviato anche tramite email.", + "hycu_dashboard_activation_license_error_message": "Si è verificato un errore durante l'invio della tua licenza: {{error}}.", + "hycu_dashboard_regenerate_error_message": "Si è verificato un errore durante l'invio della tua licenza.", + "hycu_dashboard_license_regenerate_heading": "Rigenerare la licenza", + "hycu_dashboard_license_regenerate_description": "Se il tuo ambiente tecnico HYCU è cambiato, è necessario inviare un’altra richiesta per ottenere un nuovo file di licenza compatibile con il tuo controller HYCU. Trasferisci il tuo nuovo file di richiesta della licenza. Effettuando questa azione, ti impegni anche a non utilizzare più il file di licenza fornito precedentemente.", + "hycu_dashboard_license_upload": "Upload", + "hycu_dashboard_regenerate_upload_confirm": "Rigenerare", + "hycu_dashboard_upload_cancel": "Annullare", + "hycu_dashboard_upload_confirm": "Attivare", + "hycu_dashboard_upload_file_too_big": "La dimensione del file non può superare 1 MB", + "hycu_dashboard_upload_file_bad_type": "Il file fornito non è un file {{extension}}", + "hycu_dashboard_upload_license_required": "Seleziona una licenza", + "hycu_dashboard_drag_and_drop_attachment": "Trascinare un allegato", + "hycu_dashboard_accepted_formats": "Formato accettato: {{extension}}", + "hycu_dashboard_browse": "Selezionare", + "hycu_dashboard_update_display_name_modal_headline": "Modifica il nome", + "hycu_dashboard_update_display_name_input_label": "Cognome", + "hycu_dashboard_update_display_name_pattern_message": "Utilizza esclusivamente lettere senza accento e i seguenti caratteri speciali:! @ # $ % ^ & * ( ) - _ + = [ ] { } ; : , . ? (limitato a 36 caratteri).", + "hycu_dashboard_update_display_name_success": "La descrizione è stata modificata correttamente.", + "hycu_dashboard_edit_modal_error": "Si è verificato un errore: {{error}}.", + "hycu_dashboard_error_license_message": "Si è verificato un errore durante l'attivazione della tua licenza ({{error}}). Ti invitiamo a verificare le informazioni fornite e a ripetere l’operazione. Se il problema persiste, contatta il nostro supporto.", + "hycu_dashboard_warning_license_suspended_message": "Il servizio è stato disattivato." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_pl_PL.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_pl_PL.json new file mode 100644 index 000000000000..09f32436fcb1 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_pl_PL.json @@ -0,0 +1,51 @@ +{ + "hycu_dashboard_generals_informations_title": "Informacje ogólne", + "hycu_dashboard_label_name": "Nazwisko", + "hycu_dashboard_label_status": "Status", + "hycu_dashboard_label_pack_type": "Typ pakietu", + "hycu_dashboard_label_controller_id": "Controller ID", + "hycu_dashboard_label_license_key": "Klucz licencji", + "hycu_dashboard_shortcuts_title": "Szybki dostęp", + "hycu_dashboard_link_activate": "Aktywuj licencję", + "hycu_dashboard_link_regenerate": "Wygeneruj ponownie licencję", + "hycu_dashboard_link_terminate": "Anuluj licencję", + "hycu_dashboard_link_change_pack_type": "Zmień typ pakietu", + "hycu_dashboard_field_label_contacts": "Kontakty", + "hycu_dashboard_contact_type_administrator": "Administrator", + "hycu_dashboard_contact_type_technical": "Kontakt techniczny", + "hycu_dashboard_contact_type_billing": "Płatności", + "hycu_dashboard_action_billing_terminate": "Rezygnacja", + "hycu_dashboard_field_label_manage_contacts": "Zarządzanie kontaktami", + "hycu_dashboard_label_renew": "Automatyczne odnowienie", + "hycu_dashboard_subscription_title": "Abonament", + "hycu_dashboard_field_label_date_creation": "Data utworzenia", + "hycu_dashboard_download_license_file": "Pobierz licencję", + "hycu_dashboard_back_link": "Powrót do listy", + "hycu_dashboard_wait_for_activation": "Trwa aktywacja", + "hycu_dashboard_license_activate_heading": "Aktywuj licencję", + "hycu_dashboard_license_activate_description": "Prześlij plik wniosku o licencję. Plik ten pobierzesz z kontrolera HYCU po zakończeniu instalacji", + "hycu_dashboard_license_more_information_link": "(więcej szczegółów znajdziesz tutaj).", + "hycu_dashboard_activation_license_success_message": "Dyspozycja aktywacji licencji została przyjęta. Twój plik licencyjny będzie wkrótce dostępny w tym interfejsie i zostanie również wysłany na Twój adres e-mail.", + "hycu_dashboard_regenerate_success_message": "Dyspozycja ponownego wygenerowania licencji została zarejestrowana. Twój plik licencyjny będzie wkrótce dostępny w tym interfejsie i zostanie również wysłany na Twój adres e-mail.", + "hycu_dashboard_activation_license_error_message": "Wystąpił błąd w trakcie przesyłania wniosku o licencję: {{error}}.", + "hycu_dashboard_regenerate_error_message": "Wystąpił błąd w trakcie przesyłania wniosku o licencję.", + "hycu_dashboard_license_regenerate_heading": "Wygeneruj ponownie licencję", + "hycu_dashboard_license_regenerate_description": "Jeśli zmieniło się środowisko techniczne HYCU, należy przesłać nowy wniosek, aby otrzymać nowy plik licencji kompatybilny z kontrolerem HYCU. Prześlij nowy plik wniosku o licencję. Wykonując tę ​​czynność, zobowiązujesz się również do zaprzestania używania wcześniej dostarczonego pliku licencji.", + "hycu_dashboard_license_upload": "Upload", + "hycu_dashboard_regenerate_upload_confirm": "Wygeneruj ponownie", + "hycu_dashboard_upload_cancel": "Anuluj", + "hycu_dashboard_upload_confirm": "Włącz", + "hycu_dashboard_upload_file_too_big": "Rozmiar pliku nie może przekroczyć 1MB", + "hycu_dashboard_upload_file_bad_type": "Dostarczony plik nie jest plikiem {{extension}}", + "hycu_dashboard_upload_license_required": "Wybierz licencję", + "hycu_dashboard_drag_and_drop_attachment": "Przeciągnij i upuść załącznik", + "hycu_dashboard_accepted_formats": "Akceptowany format: {{extension}}", + "hycu_dashboard_browse": "Wyszukaj", + "hycu_dashboard_update_display_name_modal_headline": "Zmień nazwę", + "hycu_dashboard_update_display_name_input_label": "Nazwisko", + "hycu_dashboard_update_display_name_pattern_message": "Należy używać tylko liter bez następujących znaków specjalnych: ! @ # $ % ^ & * ( ) - _ + = [ ] { } ; : , . ? (maksymalna liczba znaków: 36).", + "hycu_dashboard_update_display_name_success": "Opis został zmieniony.", + "hycu_dashboard_edit_modal_error": "Wystąpił błąd: {{error}}", + "hycu_dashboard_error_license_message": "Wystąpił błąd podczas aktywacji Twojej licencji ({{error}}). Sprawdź podane informacje i spróbuj ponownie. Jeśli problem się powtórzy, skontaktuj się z pomocą techniczną.", + "hycu_dashboard_warning_license_suspended_message": "Usługa została zakończona." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_pt_PT.json b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_pt_PT.json new file mode 100644 index 000000000000..575663f1f249 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/dashboard/Messages_pt_PT.json @@ -0,0 +1,51 @@ +{ + "hycu_dashboard_generals_informations_title": "Informações gerais", + "hycu_dashboard_label_name": "Nome", + "hycu_dashboard_label_status": "Estado", + "hycu_dashboard_label_pack_type": "Tipo de pack", + "hycu_dashboard_label_controller_id": "Controller ID", + "hycu_dashboard_label_license_key": "Chave de licença", + "hycu_dashboard_shortcuts_title": "Atalhos", + "hycu_dashboard_link_activate": "Ativar a licença", + "hycu_dashboard_link_regenerate": "Gerar nova licença", + "hycu_dashboard_link_terminate": "Cancelar a licença", + "hycu_dashboard_link_change_pack_type": "Modificar o tipo de pack", + "hycu_dashboard_field_label_contacts": "Contactos", + "hycu_dashboard_contact_type_administrator": "Administrador", + "hycu_dashboard_contact_type_technical": "Técnico", + "hycu_dashboard_contact_type_billing": "Faturação", + "hycu_dashboard_action_billing_terminate": "Rescindir", + "hycu_dashboard_field_label_manage_contacts": "Gerir os contactos", + "hycu_dashboard_label_renew": "Renovação automática", + "hycu_dashboard_subscription_title": "Subscrição", + "hycu_dashboard_field_label_date_creation": "Data de criação", + "hycu_dashboard_download_license_file": "Descarregar a licença", + "hycu_dashboard_back_link": "Voltar à lista", + "hycu_dashboard_wait_for_activation": "Aguardar ativação", + "hycu_dashboard_license_activate_heading": "Ativar a licença", + "hycu_dashboard_license_activate_description": "Queira transferir o seu ficheiro de pedido de licença. Este ficheiro deve ser transferido a partir do seu controlador HYCU após a instalação", + "hycu_dashboard_license_more_information_link": "(mais informações aqui).", + "hycu_dashboard_activation_license_success_message": "O pedido de ativação da sua licença foi registado. O seu ficheiro de licença estará brevemente disponível nesta interface e irá também recebê-lo por e-mail.", + "hycu_dashboard_regenerate_success_message": "O pedido de geração de uma nova licença foi registado. O seu ficheiro de licença estará brevemente disponível nesta interface e irá também recebê-lo por e-mail.", + "hycu_dashboard_activation_license_error_message": "Ocorreu um erro aquando do pedido da sua licença: {{error}}.", + "hycu_dashboard_regenerate_error_message": "Ocorreu um erro aquando do pedido da sua licença.", + "hycu_dashboard_license_regenerate_heading": "Gerar nova licença", + "hycu_dashboard_license_regenerate_description": "Se o seu ambiente técnico da HYCU tiver sido alterado, é necessário efetuar um novo pedido para obter um novo ficheiro de licença compatível com o seu controlador HYCU. Queira transferir o seu novo ficheiro de pedido de licença. Ao realizar esta ação, compromete-se também a não voltar a utilizar o ficheiro de licença que lhe foi anteriormente fornecido.", + "hycu_dashboard_license_upload": "Upload", + "hycu_dashboard_regenerate_upload_confirm": "Regenerar", + "hycu_dashboard_upload_cancel": "Anular", + "hycu_dashboard_upload_confirm": "Ativar", + "hycu_dashboard_upload_file_too_big": "O tamanho do ficheiro não pode exceder 1MB", + "hycu_dashboard_upload_file_bad_type": "O ficheiro fornecido não é um ficheiro {{extension}}", + "hycu_dashboard_upload_license_required": "Selecione uma licença", + "hycu_dashboard_drag_and_drop_attachment": "Arrastar e soltar um anexo", + "hycu_dashboard_accepted_formats": "Formato aceite: {{extension}}", + "hycu_dashboard_browse": "Procurar", + "hycu_dashboard_update_display_name_modal_headline": "Alterar o nome", + "hycu_dashboard_update_display_name_input_label": "Nome", + "hycu_dashboard_update_display_name_pattern_message": "Utilize apenas letras sem acento e os seguintes caracteres especiais: ! @ # $ % ^ & * ( ) - _ + = [ ] { } ; : , . ? (limitado a 36 caracteres).", + "hycu_dashboard_update_display_name_success": "A descrição foi modificada com sucesso.", + "hycu_dashboard_edit_modal_error": "Ocorreu um erro: {{error}}.", + "hycu_dashboard_error_license_message": "Ocorreu um erro ao ativar a sua licença {{error}}. Sugerimos que verifique as informações fornecidas e tente novamente. Se o problema persistir, queira contactar o nosso suporte.", + "hycu_dashboard_warning_license_suspended_message": "O serviço foi rescindido." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_de_DE.json b/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_de_DE.json new file mode 100644 index 000000000000..f8c1d6915384 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_de_DE.json @@ -0,0 +1,9 @@ +{ + "hycu_edit_pack_title": "Eine HYCU R-Cloud Hybrid Cloud Edition Lizenz ändern", + "hycu_edit_pack_description": "HYCU R-Cloud Hybrid Cloud Edition ist eine speziell für Nutanix entwickelte Backup- und Wiederherstellungssoftware. Wir bieten Ihnen verschiedene Lizenzpakete je nach Anzahl der von Ihren Nutanix-Workloads verwendeten virtuellen Maschinen (VMs).", + "hycu_edit_pack_subtitle": "Pakettyp für Lizenz {{displayName}} ändern", + "hycu_edit_pack_subtitle_description": "Wenn das anfangs ausgewählte VM-Paket Ihren Anforderungen nicht mehr entspricht, wählen Sie bitte einen anderen Pakettyp aus und schließen Sie Ihre Bestellung ab. Ihr vorheriges Abonnement wird automatisch durch das neue VM-Paket ersetzt.", + "hycu_edit_pack_initiated_title": "Änderung Ihrer HYCU R-Cloud Hybrid Cloud Edition Lizenz", + "hycu_edit_pack_initiated_description": "Wenn Sie Ihre Bestellung noch nicht abgeschlossen haben, können Sie diese durch Klicken auf den folgenden Link vervollständigen:", + "hycu_edit_pack_initiated_info": "Wir werden Sie per E-Mail über die Verfügbarkeit Ihrer Lizenz informieren." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_en_GB.json b/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_en_GB.json new file mode 100644 index 000000000000..aa605440ac63 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_en_GB.json @@ -0,0 +1,9 @@ +{ + "hycu_edit_pack_title": "Change HYCU R-Cloud Hybrid Cloud Edition licence", + "hycu_edit_pack_description": "HYCU R-Cloud Hybrid Cloud Edition is a backup and restore software specifically designed for Nutanix. We offer different licence packs, depending on the number of virtual machines (VMs) used by your Nutanix workloads.", + "hycu_edit_pack_subtitle": "Change pack type for the {{displayName}} licence", + "hycu_edit_pack_subtitle_description": "If your chosen VM pack is no longer suitable, please select another pack type to complete your order. Choosing the new VM pack will automatically replace your current subscription.", + "hycu_edit_pack_initiated_title": "Change HYCU R-Cloud Hybrid Cloud Edition licence", + "hycu_edit_pack_initiated_description": "If you haven’t completed your order, you can do so by clicking this link:", + "hycu_edit_pack_initiated_info": "We will notify you via email once your licence is ready." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_es_ES.json b/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_es_ES.json new file mode 100644 index 000000000000..04d45b8eb0ae --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_es_ES.json @@ -0,0 +1,9 @@ +{ + "hycu_edit_pack_title": "Modificar una licencia HYCU R-Cloud Hybrid Cloud Edition", + "hycu_edit_pack_description": "HYCU R-Cloud Hybrid Cloud Edition es un software de backup y restauración especialmente diseñado para Nutanix. OVHcloud ofrece diferentes packs de licencias en función del número de máquinas virtuales (MV) utilizadas por sus cargas de trabajo Nutanix.", + "hycu_edit_pack_subtitle": "Modificar el tipo de pack para la licencia {{displayName}}", + "hycu_edit_pack_subtitle_description": "Si el pack de MV seleccionado inicialmente ya no se ajusta a sus necesidades, puede seleccionar otro pack y completar el pedido. El nuevo pack de MV seleccionado sustituirá automáticamente al servicio anterior.", + "hycu_edit_pack_initiated_title": "Modificación de la licencia HYCU R-Cloud Hybrid Cloud Edition", + "hycu_edit_pack_initiated_description": "Si todavía no ha finalizado el pedido, puede completarlo haciendo clic en el siguiente enlace:", + "hycu_edit_pack_initiated_info": "Le informaremos de la disponibilidad de su licencia por correo electrónico." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_fr_CA.json b/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_fr_CA.json new file mode 100644 index 000000000000..b2880ac6bcde --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_fr_CA.json @@ -0,0 +1,9 @@ +{ + "hycu_edit_pack_title": "Modifier une licence HYCU R-Cloud Hybrid Cloud Edition", + "hycu_edit_pack_description": "HYCU R-Cloud Hybrid Cloud Edition est un logiciel de sauvegarde et de restauration spécialement conçu pour Nutanix. Nous vous proposons différents packs de licences selon le nombre de machines virtuelles (VM) utilisées par vos charges de travail Nutanix.", + "hycu_edit_pack_subtitle": "Modifier le type de pack pour la licence {{displayName}}", + "hycu_edit_pack_subtitle_description": "Si le pack de VM initialement sélectionné ne correspond plus à vos besoins, veuillez choisir un autre type de pack et finaliser votre commande. Le nouveau pack de VM sélectionné remplacera automatiquement votre souscription précédente.", + "hycu_edit_pack_initiated_title": "Modification de votre licence HYCU R-Cloud Hybrid Cloud Edition", + "hycu_edit_pack_initiated_description": "Si vous n'avez pas encore finalisé votre commande, vous pouvez la compléter en cliquant sur le lien suivant :", + "hycu_edit_pack_initiated_info": "Nous vous informerons de la disponibilité de votre licence par e-mail." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_it_IT.json b/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_it_IT.json new file mode 100644 index 000000000000..3c4ba76a46ef --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_it_IT.json @@ -0,0 +1,9 @@ +{ + "hycu_edit_pack_title": "Modificare una licenza HYCU R-Cloud Hybrid Cloud Edition", + "hycu_edit_pack_description": "HYCU R-Cloud Hybrid Cloud Edition è un software di backup e ripristino sviluppato appositamente per Nutanix. Proponiamo diversi pack di licenze in base al numero di macchine virtuali (VM) utilizzate dai tuoi carichi di lavoro Nutanix.", + "hycu_edit_pack_subtitle": "Modificare il tipo di pack per la licenza {{displayName}}", + "hycu_edit_pack_subtitle_description": "Se il pack di VM selezionato inizialmente non risponde più alle tue esigenze, scegli un altro tipo di pack e completa il tuo ordine. Il nuovo pack di VM selezionato sostituirà automaticamente la sottoscrizione precedente.", + "hycu_edit_pack_initiated_title": "Modifica della tua licenza HYCU R-Cloud Hybrid Cloud Edition", + "hycu_edit_pack_initiated_description": "Se non hai ancora finalizzato il tuo ordine, puoi completarlo cliccando sul seguente link:", + "hycu_edit_pack_initiated_info": "Ti informeremo della disponibilità della tua licenza via email." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_pl_PL.json b/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_pl_PL.json new file mode 100644 index 000000000000..c818e0c1b9f0 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_pl_PL.json @@ -0,0 +1,9 @@ +{ + "hycu_edit_pack_title": "Zmień licencję HYCU R-Cloud Hybrid Cloud Edition", + "hycu_edit_pack_description": "HYCU R-Cloud Hybrid Cloud Edition to oprogramowanie do tworzenia kopii zapasowych i odzyskiwania danych zaprojektowane specjalnie dla Nutanix. Wybierz odpowiedni pakiet licencji w zależności od liczby wirtualnych maszyn (VM) obsługujących obciążenia Nutanix.", + "hycu_edit_pack_subtitle": "Zmień typ pakietu dla licencji {{displayName}}", + "hycu_edit_pack_subtitle_description": "Jeśli wybrany pakiet VM nie odpowiada Twoim potrzebom, wybierz inny pakiet i dokończ zamówienie. Nowy pakiet VM automatycznie zastąpi poprzedni abonament.", + "hycu_edit_pack_initiated_title": "Zmiana licencji HYCU R-Cloud Hybrid Cloud Edition", + "hycu_edit_pack_initiated_description": "Jeśli jeszcze nie sfinalizowałeś zamówienia, możesz to zrobić, klikając link:", + "hycu_edit_pack_initiated_info": "O dostępności licencji powiadomimy Cię e-mailem." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_pt_PT.json b/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_pt_PT.json new file mode 100644 index 000000000000..8e030b8427e8 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/edit-pack/Messages_pt_PT.json @@ -0,0 +1,9 @@ +{ + "hycu_edit_pack_title": "Alterar uma licença HYCU R-Cloud Hybrid Cloud Edition", + "hycu_edit_pack_description": "O HYCU R-Cloud Hybrid Cloud Edition é um software de backup e restauro especialmente concebido para o Nutanix Propomos-lhe diferentes packs de licenças em função do número de máquinas virtuais (VM) utilizadas pelas suas cargas de trabalho Nutanix.", + "hycu_edit_pack_subtitle": "Modificar o tipo de pack para a licença {{displayName}}", + "hycu_edit_pack_subtitle_description": "Se o pack de VM inicialmente selecionado já não corresponde às suas necessidades, escolha outro tipo de pack e finalize a sua encomenda. O novo pack de VM selecionado substituirá automaticamente a sua subscrição anterior.", + "hycu_edit_pack_initiated_title": "Alteração da sua licença HYCU R-Cloud Hybrid Cloud Edition", + "hycu_edit_pack_initiated_description": "Se ainda não finalizou a sua encomenda, pode concluí-la ao clicar no seguinte link:", + "hycu_edit_pack_initiated_info": "Receberá por e-mail a informação da disponibilidade da sua licença." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_de_DE.json b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_de_DE.json index ec3b7ee67f2f..95bcd7756fa5 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_de_DE.json +++ b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_de_DE.json @@ -10,5 +10,6 @@ "hycu_commercial_name": "Paket-Typ", "hycu_subscribed_date": "Anmeldungsdatum", "hycu_order": "Bestellen", - "hycu_service_listing_terminate": "Kündigen" + "hycu_service_listing_terminate": "Kündigen", + "hycu_listing_error_loading_data": "Fehler beim Laden" } diff --git a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_en_GB.json b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_en_GB.json index 1cd96b740873..c961afe647a6 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_en_GB.json +++ b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_en_GB.json @@ -10,5 +10,6 @@ "hycu_commercial_name": "Pack type", "hycu_subscribed_date": "Subscription date", "hycu_order": "Order", - "hycu_service_listing_terminate": "Terminate" + "hycu_service_listing_terminate": "Terminate", + "hycu_listing_error_loading_data": "Loading error" } diff --git a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_es_ES.json b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_es_ES.json index 9afb94c7055b..1aa94ebec4bd 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_es_ES.json +++ b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_es_ES.json @@ -10,5 +10,6 @@ "hycu_commercial_name": "Tipo de pack", "hycu_subscribed_date": "Fecha de contratación", "hycu_order": "Contratar", - "hycu_service_listing_terminate": "Dar de baja" + "hycu_service_listing_terminate": "Dar de baja", + "hycu_listing_error_loading_data": "Error de carga" } diff --git a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_fr_CA.json b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_fr_CA.json index ea668aab4db9..dfe0b0c1f0e4 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_fr_CA.json +++ b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_fr_CA.json @@ -1,8 +1,4 @@ { - "hycu_status_activated": "Active", - "hycu_status_toActivate": "À activer", - "hycu_status_pending": "En cours d'activation", - "hycu_status_error": "Erreur d'activation", "hycu_cloud_vm_pack_unknown": "Pack inconnu", "hycu_name": "Nom", "hycu_controller_id": "Controller ID", @@ -10,5 +6,6 @@ "hycu_commercial_name": "Type de pack", "hycu_subscribed_date": "Date de souscription", "hycu_order": "Commander", - "hycu_service_listing_terminate": "Résilier" + "hycu_service_listing_terminate": "Résilier", + "hycu_listing_error_loading_data": "Erreur de chargement" } diff --git a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_it_IT.json b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_it_IT.json index 379f73a88247..57d5838754c7 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_it_IT.json +++ b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_it_IT.json @@ -10,5 +10,6 @@ "hycu_commercial_name": "Tipo di pack", "hycu_subscribed_date": "Data di sottoscrizione", "hycu_order": "Ordinare", - "hycu_service_listing_terminate": "Disattivare" + "hycu_service_listing_terminate": "Disattivare", + "hycu_listing_error_loading_data": "Errore di caricamento" } diff --git a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_pl_PL.json b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_pl_PL.json index a353d094ce56..9dfc61a453d7 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_pl_PL.json +++ b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_pl_PL.json @@ -10,5 +10,6 @@ "hycu_commercial_name": "Typ pakietu", "hycu_subscribed_date": "Data subskrypcji", "hycu_order": "Zamów", - "hycu_service_listing_terminate": "Rezygnacja" + "hycu_service_listing_terminate": "Rezygnacja", + "hycu_listing_error_loading_data": "Wystąpił błąd podczas pobierania informacji" } diff --git a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_pt_PT.json b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_pt_PT.json index 725f4a41ce6f..68c949c28879 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_pt_PT.json +++ b/packages/manager/apps/hycu/public/translations/hycu/listing/Messages_pt_PT.json @@ -10,5 +10,6 @@ "hycu_commercial_name": "Tipo de pack", "hycu_subscribed_date": "Data de subscrição", "hycu_order": "Encomendar", - "hycu_service_listing_terminate": "Rescindir" + "hycu_service_listing_terminate": "Rescindir", + "hycu_listing_error_loading_data": "Erro de carregamento" } diff --git a/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_de_DE.json b/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_de_DE.json index 6d47cbd55e77..91bb11baa5b5 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_de_DE.json +++ b/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_de_DE.json @@ -3,9 +3,9 @@ "moreInfoButtonLabel": "Mehr erfahren", "hycu_onboarding_category_tutorial": "Anleitung", "hycu_onboarding_guide1_title": "Guides und Dokumentation", - "hycu_onboarding_guide1_description": "Entdecken Sie unsere detaillierten Anleitungen und unsere Dokumentation, um Sie bei Ihrem Projekt zu unterstützen.", + "hycu_onboarding_guide1_description": "Entdecken Sie unsere Guides und detaillierte Dokumentation, um Sie bei Ihrem Projekt zu unterstützen.", "hycu_onboarding_guide2_title": "Nutanix on OVHcloud", - "hycu_onboarding_guide2_description": "Entdecken Sie unsere hyperkonvergente Plattform (HCI), die nicht nur skalierbar, sondern auch innerhalb weniger Stunden einsatzbereit ist. Diese Lösung ist als Paket- oder BYOL-Angebot (Bring Your Own Licence) verfügbar und kombiniert die Softwarelizenzen der Nutanix Cloud Platform (NCP) mit den dedizierten und für Nutanix qualifizierten Hosted Private Cloud Infrastrukturen von OVHcloud.", + "hycu_onboarding_guide2_description": "Die Nutanix on OVHcloud Lösung kombiniert die NCP-Lizenzen (Nutanix Cloud Platform) mit den dedizierten und Nutanix-qualifizierten Hosted Private Cloud Infrastrukturen von OVHcloud und ermöglicht damit die Bereitstellung einer gebrauchsfertigen hyperkonvergenten Nutanix-Umgebung (HCI).", "hycu_onboarding_guide3_title": "Disaster-Recovery-Plan (DRP)", "hycu_onboarding_guide3_description": "Nutzen Sie HYCU for OVHcloud für eine kontrollierte und performante Disaster Recovery ohne Überraschungen, bei der Sie die Kosten im Griff behalten." } diff --git a/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_en_GB.json b/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_en_GB.json index fcb246aa9c3f..e614b028a722 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_en_GB.json +++ b/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_en_GB.json @@ -5,7 +5,7 @@ "hycu_onboarding_guide1_title": "Guides and documentation", "hycu_onboarding_guide1_description": "Explore our guides and detailed documentation to help you with your project.", "hycu_onboarding_guide2_title": "Nutanix on OVHcloud", - "hycu_onboarding_guide2_description": "Discover our scalable, hyperconverged platform (HCI), ready to use in just a few hours Available as a packaged service or as a BYOL (Bring Your Own Licence) service, it combines Nutanix Cloud Platform (NCP) software licences with dedicated, Nutanix-qualified OVHcloud Hosted Private Cloud infrastructure.", + "hycu_onboarding_guide2_description": "The Nutanix on OVHcloud solution combines Nutanix Cloud Platform (NCP) licences with dedicated, Nutanix-qualified OVHcloud Hosted Private Cloud infrastructure, providing a pre-configured and ready-to-use Nutanix hyperconverged environment (HCI).", "hycu_onboarding_guide3_title": "Disaster Recovery Plan (DRP)", "hycu_onboarding_guide3_description": "Use the HYCU for OVHcloud service for a controlled, high-performance disaster recovery, with controlled costs and no surprises." } diff --git a/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_es_ES.json b/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_es_ES.json index 04ef75cb4f80..1397fb3ffba8 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_es_ES.json +++ b/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_es_ES.json @@ -3,9 +3,9 @@ "moreInfoButtonLabel": "Más información", "hycu_onboarding_category_tutorial": "Guía", "hycu_onboarding_guide1_title": "Guías y documentación", - "hycu_onboarding_guide1_description": "Descubra nuestras guías y documentación detalladas para ayudarle en su proyecto.", + "hycu_onboarding_guide1_description": "Descubra nuestras guías y nuestra documentación detallada para ayudarle en su proyecto.", "hycu_onboarding_guide2_title": "Nutanix on OVHcloud", - "hycu_onboarding_guide2_description": "Descubra nuestra plataforma hiperconvergente (HCI) escalable y lista para usar en solo unas horas. Disponible como servicio en forma de pack o como servicio BYOL (Bring Your Own Licence), esta solución combina las licencias de software de Nutanix Cloud Platform (NCP) con las infraestructuras Hosted Private Cloud de OVHcloud dedicadas y certificadas por Nutanix.", + "hycu_onboarding_guide2_description": "La solución Nutanix on OVHcloud combina las licencias de Nutanix Cloud Platform (NCP) con las infraestructuras Hosted Private Cloud de OVHcloud dedicadas y certificadas por Nutanix para predesplegar un entorno hiperconvergente (HCI) Nutanix en solo unas horas.", "hycu_onboarding_guide3_title": "Plan de recuperación ante desastres (DRP)", "hycu_onboarding_guide3_description": "Utilice HYCU for OVHcloud para disfrutar de una recuperación de la actividad controlada y potente, con un coste controlado y sin sorpresas." } diff --git a/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_fr_CA.json b/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_fr_CA.json index 150d27c36cf5..8be7e255cb5b 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_fr_CA.json +++ b/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_fr_CA.json @@ -2,10 +2,10 @@ "orderButtonLabel": "Commencer", "moreInfoButtonLabel": "En savoir plus", "hycu_onboarding_category_tutorial": "Tutoriel", - "hycu_onboarding_guide1_title": "Guides et documentations", - "hycu_onboarding_guide1_description": "Découvrez nos guides et documentations détaillés pour vous accompagner dans votre projet.", + "hycu_onboarding_guide1_title": "Guides et documentation", + "hycu_onboarding_guide1_description": "Découvrez nos guides et notre documentation détaillée pour vous accompagner dans votre projet.", "hycu_onboarding_guide2_title": "Nutanix on OVHcloud", - "hycu_onboarding_guide2_description": "Découvrez notre plateforme hyperconvergée (HCI) évolutive et prête à l'emploi en quelques heures. Disponible en offre packagée ou offre BYOL (Bring Your Own Licence), elle associe les licences logicielles de la Nutanix Cloud Platform (NCP) et les infrastructures Hosted Private Cloud d'OVHcloud dédiées et qualifiées Nutanix.", + "hycu_onboarding_guide2_description": "La solution Nutanix on OVHcloud associe les licences de la Nutanix Cloud Platform (NCP) et les infrastructures Hosted Private Cloud d'OVHcloud dédiées et qualifiées Nutanix, pour pré-déployer un environnement hyperconvergé (HCI) Nutanix prêt à l'emploi.", "hycu_onboarding_guide3_title": "Plan de Reprise d'Activité (PRA)", "hycu_onboarding_guide3_description": "Appuyez-vous sur le service HYCU for OVHcloud pour une reprise d'activité contrôlée et performante, avec un coût maîtrisé et sans surprise." } diff --git a/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_it_IT.json b/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_it_IT.json index fa39262ddb6b..5bf6fc823db3 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_it_IT.json +++ b/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_it_IT.json @@ -3,9 +3,9 @@ "moreInfoButtonLabel": "Scopri di più", "hycu_onboarding_category_tutorial": "Tutorial", "hycu_onboarding_guide1_title": "Guide e documentazione", - "hycu_onboarding_guide1_description": "Scopri le nostre guide e la documentazione dettagliata per accompagnarti nel tuo progetto.", + "hycu_onboarding_guide1_description": "Scopri le nostre guide e la nostra documentazione dettagliata per accompagnarti nei tuoi progetti.", "hycu_onboarding_guide2_title": "Nutanix on OVHcloud", - "hycu_onboarding_guide2_description": "Scopri la nostra piattaforma iperconvergente (HCI) scalabile e pronta all'uso in poche ore. Disponibile in pacchetti o servizi BYOL (Bring Your Own Licence), questa soluzione associa le licenze software della Nutanix Cloud Platform (NCP) e le infrastrutture Hosted Private Cloud di OVHcloud dedicate e certificate Nutanix.", + "hycu_onboarding_guide2_description": "La soluzione Nutanix on OVHcloud associa le licenze della Nutanix Cloud Platform (NCP) con le infrastrutture Hosted Private Cloud di OVHcloud dedicate e certificate Nutanix, per usufruire di un ambiente iperconvergente (HCI) Nutanix pronto all’uso.", "hycu_onboarding_guide3_title": "Disaster Recovery Plan (DRP)", "hycu_onboarding_guide3_description": "Affidati al servizio HYCU for OVHcloud per una ripresa operativa controllata e performante, con un costo prevedibile e senza sorprese." } diff --git a/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_pl_PL.json b/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_pl_PL.json index 2c377525307d..b0377ae3901f 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_pl_PL.json +++ b/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_pl_PL.json @@ -5,7 +5,7 @@ "hycu_onboarding_guide1_title": "Przewodniki i dokumentacja", "hycu_onboarding_guide1_description": "Sprawdź nasze przewodniki i szczegółową dokumentację, które pomogą Ci w realizacji Twojego projektu.", "hycu_onboarding_guide2_title": "Nutanix on OVHcloud", - "hycu_onboarding_guide2_description": "Sprawdź naszą skalowalną, hiperkonwergentną platformę (HCI) gotową do użytku w ciągu kilku godzin. Rozwiązanie to, dostępne w pakietach lub w ramach oferty BYOL (Bring Your Own Licence), łączy w sobie licencje oprogramowania Nutanix Cloud Platform (NCP) oraz dedykowaną infrastrukturę Hosted Private Cloud z klasyfikacją Nutanix.", + "hycu_onboarding_guide2_description": "Rozwiązanie Nutanix on OVHcloud łączy licencje Nutanix Cloud Platform (NCP) oraz dedykowaną infrastrukturę OVHcloud Hosted Private Cloud, certyfikowaną przez Nutanix, w celu wstępnego wdrożenia gotowego do użycia hiperkonwergentnego środowiska Nutanix (HCI).", "hycu_onboarding_guide3_title": "Plan Disaster Recovery (DRP)", "hycu_onboarding_guide3_description": "Korzystaj z usługi HYCU for OVHcloud, która umożliwia kontrolowane i skuteczne przywracania usług, przy zachowaniu niskich kosztów i bez niespodzianek." } diff --git a/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_pt_PT.json b/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_pt_PT.json index 55649bd180ce..7bdc9087c9be 100644 --- a/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_pt_PT.json +++ b/packages/manager/apps/hycu/public/translations/hycu/onboarding/Messages_pt_PT.json @@ -3,9 +3,9 @@ "moreInfoButtonLabel": "Saber mais", "hycu_onboarding_category_tutorial": "Tutorial", "hycu_onboarding_guide1_title": "Manuais e documentação", - "hycu_onboarding_guide1_description": "Descubra guias e documentação detalhados para ser acompanhado no seu projeto.", + "hycu_onboarding_guide1_description": "Descubra os nossos manuais e a nossa documentação detalhada para o acompanhar no seu projeto.", "hycu_onboarding_guide2_title": "Nutanix on OVHcloud", - "hycu_onboarding_guide2_description": "Descubra a nossa plataforma hiperconvergente (HCI) evolutiva e pronta a usar em apenas algumas horas. Disponível em oferta em pacote ou em oferta BYOL (Bring Your Own Licence), associa as licenças de software da Nutanix Cloud Platform (NCP) às infraestruturas dedicadas Hosted Private Cloud da OVHcloud com certificação Nutanix.", + "hycu_onboarding_guide2_description": "A solução Nutanix on OVHcloud associa as licenças do Nutanix Cloud Platform (NCP) e as infraestruturas Hosted Private Cloud da OVHcloud dedicadas e com certificação Nutanix, para pré-implementar um ambiente hiperconvergente (HCI) Nutanix pronto a utilizar.", "hycu_onboarding_guide3_title": "Plano de recuperação de desastres (DRP)", "hycu_onboarding_guide3_description": "Conte com o serviço HYCU for OVHcloud para uma recuperação de desastres eficaz, a um custo controlado e sem surpresas." } diff --git a/packages/manager/apps/hycu/public/translations/hycu/order/Messages_de_DE.json b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_de_DE.json new file mode 100644 index 000000000000..6e668c049b78 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_de_DE.json @@ -0,0 +1,9 @@ +{ + "hycu_order_title": "Eine HYCU R-Cloud Hybrid Cloud Edition Lizenz bestellen", + "hycu_order_description": "HYCU R-Cloud Hybrid Cloud Edition ist eine speziell für Nutanix entwickelte Backup- und Wiederherstellungssoftware. Wir bieten Ihnen verschiedene Lizenzpakete je nach Anzahl der von Ihren Nutanix-Workloads verwendeten virtuellen Maschinen (VMs).", + "hycu_order_subtitle": "Pakettyp auswählen", + "hycu_order_subtitle_description": "Wählen Sie die Anzahl der virtuellen Maschinen (VMs) aus, die von der HYCU R-Cloud Hybrid Cloud Edition Lizenz abgedeckt werden sollen. Bitte beachten Sie, dass es nicht möglich ist, mehr als die im Paket vorgesehene Anzahl an VMs zu sichern. Wenn Sie mehr als 500 VMs schützen möchten, kontaktieren Sie bitte unseren Vertrieb.", + "hycu_order_initiated_title": "Bestellung Ihres Pakets", + "hycu_order_initiated_description": "Wenn Sie Ihre Bestellung noch nicht abgeschlossen haben, können Sie diese durch Klicken auf den folgenden Link vervollständigen:", + "hycu_order_initiated_info": "Wir werden Sie per E-Mail über die Verfügbarkeit Ihrer Lizenz informieren." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/order/Messages_en_GB.json b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_en_GB.json new file mode 100644 index 000000000000..61b474a0e391 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_en_GB.json @@ -0,0 +1,9 @@ +{ + "hycu_order_title": "Order a HYCU R-Cloud Hybrid Cloud Edition licence", + "hycu_order_description": "HYCU R-Cloud Hybrid Cloud Edition is a backup and restore software specifically designed for Nutanix. We offer different licence packs, depending on the number of virtual machines (VMs) used by your Nutanix workloads.", + "hycu_order_subtitle": "Choose pack type", + "hycu_order_subtitle_description": "Select the number of virtual machines (VMs) to be covered by the HYCU R-Cloud Hybrid Cloud Edition licence. Keep in mind that you can only back up the number of VMs specified in your pack. If you wish to back up more than 500 VMs, please contact our sales team.", + "hycu_order_initiated_title": "Order your pack", + "hycu_order_initiated_description": "If you haven’t completed your order, you can do so by clicking this link:", + "hycu_order_initiated_info": "We will notify you via email once your licence is ready." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/order/Messages_es_ES.json b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_es_ES.json new file mode 100644 index 000000000000..0dc9033a438b --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_es_ES.json @@ -0,0 +1,9 @@ +{ + "hycu_order_title": "Contratar una licencia HYCU R-Cloud Hybrid Cloud Edition", + "hycu_order_description": "HYCU R-Cloud Hybrid Cloud Edition es un software de backup y restauración especialmente diseñado para Nutanix. OVHcloud ofrece diferentes packs de licencias en función del número de máquinas virtuales (MV) utilizadas por sus cargas de trabajo Nutanix.", + "hycu_order_subtitle": "Elija el tipo de pack", + "hycu_order_subtitle_description": "Seleccione el número de máquinas virtuales (MV) que quiere incluir en la licencia HYCU R-Cloud Hybrid Cloud Edition. Tenga en cuenta que no podrá realizar el backup de un número de MV mayor que el previsto en el pack. Si quiere proteger más de 500 MV, puede ponerse en contacto con nuestro equipo comercial.", + "hycu_order_initiated_title": "Contratación de su pack", + "hycu_order_initiated_description": "Si todavía no ha finalizado el pedido, puede completarlo haciendo clic en el siguiente enlace:", + "hycu_order_initiated_info": "Le informaremos de la disponibilidad de su licencia por correo electrónico." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/order/Messages_fr_CA.json b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_fr_CA.json new file mode 100644 index 000000000000..f372e64baee5 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_fr_CA.json @@ -0,0 +1,9 @@ +{ + "hycu_order_title": "Commander une licence HYCU R-Cloud Hybrid Cloud Edition", + "hycu_order_description": "HYCU R-Cloud Hybrid Cloud Edition est un logiciel de sauvegarde et de restauration spécialement conçu pour Nutanix. Nous vous proposons différents packs de licences selon le nombre de machines virtuelles (VM) utilisées par vos charges de travail Nutanix.", + "hycu_order_subtitle": "Choisissez le type de pack", + "hycu_order_subtitle_description": "Sélectionnez le nombre de machines virtuelles (VM) à couvrir par la licence HYCU R-Cloud Hybrid Cloud Edition. Veuillez noter qu'il vous sera impossible de sauvegarder plus de VM que le nombre prévu dans le pack. Si vous souhaitez protéger plus de 500 VM, merci de vous rapprocher de notre service commercial.", + "hycu_order_initiated_title": "Commande de votre pack", + "hycu_order_initiated_description": "Si vous n'avez pas encore finalisé votre commande, vous pouvez la compléter en cliquant sur le lien suivant :", + "hycu_order_initiated_info": "Nous vous informerons de la disponibilité de votre licence par e-mail." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/order/Messages_it_IT.json b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_it_IT.json new file mode 100644 index 000000000000..23f2f889a166 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_it_IT.json @@ -0,0 +1,9 @@ +{ + "hycu_order_title": "Ordinare una licenza HYCU R-Cloud Hybrid Cloud Edition", + "hycu_order_description": "HYCU R-Cloud Hybrid Cloud Edition è un software di backup e ripristino sviluppato appositamente per Nutanix. Proponiamo diversi pack di licenze in base al numero di macchine virtuali (VM) utilizzate dai tuoi carichi di lavoro Nutanix.", + "hycu_order_subtitle": "Scegli il tipo di pack", + "hycu_order_subtitle_description": "Seleziona il numero di macchine virtuali (VM) da includere nella licenza HYCU R-Cloud Hybrid Cloud Edition. Ti ricordiamo che non sarà possibile effettuare il backup di un numero di VM maggiore di quello previsto nel pack. Per proteggere più di 500 VM, contatta il nostro servizio commerciale.", + "hycu_order_initiated_title": "Ordine del tuo pack", + "hycu_order_initiated_description": "Se non hai ancora finalizzato il tuo ordine, puoi completarlo cliccando sul seguente link:", + "hycu_order_initiated_info": "Ti informeremo della disponibilità della tua licenza via email." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/order/Messages_pl_PL.json b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_pl_PL.json new file mode 100644 index 000000000000..a8e58d4e93f1 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_pl_PL.json @@ -0,0 +1,9 @@ +{ + "hycu_order_title": "Zamów licencję HYCU R-Cloud Hybrid Cloud Edition", + "hycu_order_description": "HYCU R-Cloud Hybrid Cloud Edition to oprogramowanie do tworzenia kopii zapasowych i odzyskiwania danych zaprojektowane specjalnie dla Nutanix. Wybierz odpowiedni pakiet licencji w zależności od liczby wirtualnych maszyn (VM) obsługujących obciążenia Nutanix.", + "hycu_order_subtitle": "Wybierz rodzaj pakietu", + "hycu_order_subtitle_description": "Wybierz liczbę maszyn wirtualnych (VM), które mają zostać objęte licencją HYCU R-Cloud Hybrid Cloud Edition. Pamiętaj, że nie będziesz mógł wykonać kopii zapasowej większej liczby wirtualnych maszyn niż przewidziano w pakiecie. Jeśli chcesz chronić więcej niż 500 wirtualnych maszyn, skontaktuj się z naszym działem hadlowym.", + "hycu_order_initiated_title": "Zamówienie pakietu", + "hycu_order_initiated_description": "Jeśli jeszcze nie sfinalizowałeś zamówienia, możesz to zrobić, klikając link:", + "hycu_order_initiated_info": "O dostępności licencji powiadomimy Cię e-mailem." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/order/Messages_pt_PT.json b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_pt_PT.json new file mode 100644 index 000000000000..1657196fefbb --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/order/Messages_pt_PT.json @@ -0,0 +1,9 @@ +{ + "hycu_order_title": "Encomendar uma licença HYCU R-Cloud Hybrid Cloud Edition", + "hycu_order_description": "O HYCU R-Cloud Hybrid Cloud Edition é um software de backup e restauro especialmente concebido para o Nutanix Propomos-lhe diferentes packs de licenças em função do número de máquinas virtuais (VM) utilizadas pelas suas cargas de trabalho Nutanix.", + "hycu_order_subtitle": "Escolha o tipo de pack", + "hycu_order_subtitle_description": "Selecione o número de máquinas virtuais (VM) a incluir na licença HYCU R-Cloud Hybrid Cloud Edition. Tenha em conta que não será possível incluir mais VM do que o número previsto no pack. Se deseja proteger mais de 500 VM, contacte o nosso serviço comercial.", + "hycu_order_initiated_title": "Encomenda do seu pack", + "hycu_order_initiated_description": "Se ainda não finalizou a sua encomenda, pode concluí-la ao clicar no seguinte link:", + "hycu_order_initiated_info": "Receberá por e-mail a informação da disponibilidade da sua licença." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_de_DE.json b/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_de_DE.json new file mode 100644 index 000000000000..0b8c877efd52 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_de_DE.json @@ -0,0 +1,9 @@ +{ + "hycu_terminate_headline": "Den HYCU for OVHcloud Dienst kündigen", + "hycu_terminate_description": "Bitte geben Sie das Wort „TERMINATE“ ein, um die Kündigung Ihres HYCU for OVHcloud Dienstes zu bestätigen. Mit dieser Aktion erklären Sie sich außerdem damit einverstanden, die zuvor bereitgestellte Lizenzdatei nicht mehr zu verwenden.", + "hycu_terminate_input_label": "Bestätigungswort: ", + "hycu_terminate_cancel_label": "Abbrechen", + "hycu_terminate_confirm_label": "Kündigen", + "hycu_terminate_success_message": "Ihre Kündigungsanfrage für {{serviceName}} wurde registriert. Sie erhalten eine E-Mail zur Bestätigung.", + "hycu_terminate_error_message": "Es ist ein Fehler aufgetreten: {{error}}." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_en_GB.json b/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_en_GB.json new file mode 100644 index 000000000000..3cc316649ddf --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_en_GB.json @@ -0,0 +1,9 @@ +{ + "hycu_terminate_headline": "Cancel the HYCU for OVHcloud service", + "hycu_terminate_description": "Please enter the word “TERMINATE” to confirm the cancellation of your HYCU for OVHcloud service. By performing this action, you also agree to no longer use the previously provided licence file.", + "hycu_terminate_input_label": "Confirmation word: ", + "hycu_terminate_cancel_label": "Cancel", + "hycu_terminate_confirm_label": "Terminate", + "hycu_terminate_success_message": "Your termination request for {{serviceName}} has been processed. You will receive an email to confirm your request.", + "hycu_terminate_error_message": "An error has occurred: {{error}}." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_es_ES.json b/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_es_ES.json new file mode 100644 index 000000000000..aca4c9cde286 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_es_ES.json @@ -0,0 +1,9 @@ +{ + "hycu_terminate_headline": "Dar de baja el servicio HYCU for OVHcloud", + "hycu_terminate_description": "Introduzca la palabra «TERMINATE» para confirmar la baja de su servicio HYCU for OVHcloud. Al realizar esta acción, se compromete a no utilizar el archivo de licencia anteriormente proporcionado.", + "hycu_terminate_input_label": "Palabra de confirmación: ", + "hycu_terminate_cancel_label": "Cancelar", + "hycu_terminate_confirm_label": "Dar de baja", + "hycu_terminate_success_message": "Su solicitud de baja para {{serviceName}} se ha enviado. Recibirá un mensaje de correo electrónico para validarla.", + "hycu_terminate_error_message": "Se ha producido un error: {{error}}." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_fr_CA.json b/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_fr_CA.json new file mode 100644 index 000000000000..3eb7f2ea5363 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_fr_CA.json @@ -0,0 +1,9 @@ +{ + "hycu_terminate_headline": "Résilier le service HYCU for OVHcloud", + "hycu_terminate_description": "Veuillez entrer le mot \"TERMINATE\" pour confirmer la résiliation de votre service HYCU for OVHcloud. En réalisant cette action, vous vous engagez également à ne plus utiliser le fichier de licence préalablement fourni.", + "hycu_terminate_input_label": "Mot de confirmation : ", + "hycu_terminate_cancel_label": "Annuler", + "hycu_terminate_confirm_label": "Résilier", + "hycu_terminate_success_message": "Votre demande de résiliation pour {{serviceName}} à bien été prise en compte, vous allez recevoir un mail pour valider celle-ci.", + "hycu_terminate_error_message": "Une erreur est survenue: {{error}}." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_it_IT.json b/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_it_IT.json new file mode 100644 index 000000000000..c5c0da282518 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_it_IT.json @@ -0,0 +1,9 @@ +{ + "hycu_terminate_headline": "Disattivare il servizio HYCU for OVHcloud", + "hycu_terminate_description": "Inserisci la parola \"TERMINATE\" per confermare la disattivazione del tuo servizio HYCU for OVHcloud. Effettuando questa azione, ti impegni anche a non utilizzare più il file di licenza fornito precedentemente.", + "hycu_terminate_input_label": "Parola di conferma: ", + "hycu_terminate_cancel_label": "Annullare", + "hycu_terminate_confirm_label": "Disattivare", + "hycu_terminate_success_message": "La richiesta di disattivazione per {{serviceName}} è stata presa in carico, riceverai un’email per confermarla.", + "hycu_terminate_error_message": "Si è verificato un errore: {{error}}." +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_pl_PL.json b/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_pl_PL.json new file mode 100644 index 000000000000..121b05a86f08 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_pl_PL.json @@ -0,0 +1,9 @@ +{ + "hycu_terminate_headline": "Rezygnacja z usługi HYCU for OVHcloud", + "hycu_terminate_description": "Wpisz słowo „TERMINATE”, aby potwierdzić rezygnację z usługi HYCU for OVHcloud. Wykonując tę ​​czynność, zobowiązujesz się również do zaprzestania używania uprzednio dostarczonego pliku licencji.", + "hycu_terminate_input_label": "Hasło potwierdzenia: ", + "hycu_terminate_cancel_label": "Anuluj", + "hycu_terminate_confirm_label": "Rezygnacja", + "hycu_terminate_success_message": "Rezygnacja z usługi {{serviceName}} została zarejestrowana. Otrzymasz e-mail z potwierdzeniem.", + "hycu_terminate_error_message": "Wystąpił błąd: {{error}}" +} diff --git a/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_pt_PT.json b/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_pt_PT.json new file mode 100644 index 000000000000..07dd6d183909 --- /dev/null +++ b/packages/manager/apps/hycu/public/translations/hycu/terminate/Messages_pt_PT.json @@ -0,0 +1,9 @@ +{ + "hycu_terminate_headline": "Rescindir o serviço HYCU for OVHcloud", + "hycu_terminate_description": "Introduza a palavra «TERMINATE» para confirmar a rescisão do seu serviço HYCU for OVHcloud. Ao realizar esta ação, compromete-se também a não voltar a utilizar o ficheiro de licença que lhe foi anteriormente fornecido.", + "hycu_terminate_input_label": "Palavra de confirmação: ", + "hycu_terminate_cancel_label": "Anular", + "hycu_terminate_confirm_label": "Rescindir", + "hycu_terminate_success_message": "O seu pedido de rescisão do {{serviceName}} foi registado. Irá receber um e-mail para a validar.", + "hycu_terminate_error_message": "Ocorreu um erro: {{error}}." +} diff --git a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_de_DE.json b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_de_DE.json index 0e7624b1d878..96abce612ef8 100644 --- a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_de_DE.json +++ b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_de_DE.json @@ -20,5 +20,6 @@ "billing_services_actions_menu_see_dashboard": "Dienstdetails anzeigen", "billing_services_actions_menu_commit": "Meine Abonnementlaufzeit verwalten", "billing_services_actions_menu_commit_cancel": "Abonnementbestellung mit fester Laufzeit stornieren", - "billing_services_actions_menu_resiliate_my_engagement": "Meine Vertragsbindung kündigen" + "billing_services_actions_menu_resiliate_my_engagement": "Meine Vertragsbindung kündigen", + "billing_services_actions_menu_resiliate_LICENSE_HYCU": "Meine HYCU-Lizenz löschen" } diff --git a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_en_GB.json b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_en_GB.json index a2177d2c3061..b7f8ce1b5a0b 100644 --- a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_en_GB.json +++ b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_en_GB.json @@ -20,5 +20,6 @@ "billing_services_actions_menu_see_dashboard": "View service details", "billing_services_actions_menu_commit": "Manage my commitment", "billing_services_actions_menu_commit_cancel": "Cancel subscription request", - "billing_services_actions_menu_resiliate_my_engagement": "Cancel subscription" + "billing_services_actions_menu_resiliate_my_engagement": "Cancel subscription", + "billing_services_actions_menu_resiliate_LICENSE_HYCU": "Delete my Hycu licence" } diff --git a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_es_ES.json b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_es_ES.json index 629e88967ff2..3f42d4519a13 100644 --- a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_es_ES.json +++ b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_es_ES.json @@ -20,5 +20,6 @@ "billing_services_actions_menu_see_dashboard": "Ver el detalle del servicio", "billing_services_actions_menu_commit": "Gestionar mi compromiso de permanencia", "billing_services_actions_menu_commit_cancel": "Cancelar la solicitud de contratación con compromiso de permanencia", - "billing_services_actions_menu_resiliate_my_engagement": "Cancelar mi compromiso" + "billing_services_actions_menu_resiliate_my_engagement": "Cancelar mi compromiso", + "billing_services_actions_menu_resiliate_LICENSE_HYCU": "Eliminar mi licencia HYCU" } diff --git a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_fr_CA.json b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_fr_CA.json index 219001192e19..1b81a70ca451 100644 --- a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_fr_CA.json +++ b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_fr_CA.json @@ -15,6 +15,7 @@ "billing_services_actions_menu_resiliate_HOSTING_WEB": "Supprimer immédiatement l'hébergement", "billing_services_actions_menu_resiliate_HOSTING_PRIVATE_DATABASE": "Supprimer mon hébergement SQL privé", "billing_services_actions_menu_resiliate_WEBCOACH": "Supprimer mon WebCoach", + "billing_services_actions_menu_resiliate_LICENSE_HYCU": "Supprimer ma licence Hycu", "billing_services_actions_menu_sms_credit": "Ajouter des crédits", "billing_services_actions_menu_sms_renew": "Configurer la recharge automatique", "billing_services_actions_menu_resiliate_cancel": "Annuler la résiliation du service", diff --git a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_it_IT.json b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_it_IT.json index 3240da99d6ea..a328a7c8f77f 100644 --- a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_it_IT.json +++ b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_it_IT.json @@ -20,5 +20,6 @@ "billing_services_actions_menu_see_dashboard": "Mostra i dettagli del server", "billing_services_actions_menu_commit": "Gestisci il tuo impegno contrattuale", "billing_services_actions_menu_commit_cancel": "Annulla la richiesta di sottoscrizione di un impegno contrattuale", - "billing_services_actions_menu_resiliate_my_engagement": "Rescindi l’impegno contrattuale" + "billing_services_actions_menu_resiliate_my_engagement": "Rescindi l’impegno contrattuale", + "billing_services_actions_menu_resiliate_LICENSE_HYCU": "Eliminare la tua licenza HYCU" } diff --git a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_pl_PL.json b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_pl_PL.json index d521f7cc3f79..4393fb26a572 100644 --- a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_pl_PL.json +++ b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_pl_PL.json @@ -20,5 +20,6 @@ "billing_services_actions_menu_see_dashboard": "Wyświetl szczegółowe informacje o usłudze", "billing_services_actions_menu_commit": "Zarządzanie usługą z opcją umowy terminowej", "billing_services_actions_menu_commit_cancel": "Anuluj zamówienie usługi z opcją umowy terminowej", - "billing_services_actions_menu_resiliate_my_engagement": "Rezygnacja z umowy terminowej" + "billing_services_actions_menu_resiliate_my_engagement": "Rezygnacja z umowy terminowej", + "billing_services_actions_menu_resiliate_LICENSE_HYCU": "Usuń licencję HYCU" } diff --git a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_pt_PT.json b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_pt_PT.json index 46715d8a602a..f12a551f60d8 100644 --- a/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_pt_PT.json +++ b/packages/manager/modules/billing-components/src/components/services-actions/translations/Messages_pt_PT.json @@ -20,5 +20,6 @@ "billing_services_actions_menu_see_dashboard": "Ver os detalhes do serviço", "billing_services_actions_menu_commit": "Gerir o meu compromisso", "billing_services_actions_menu_commit_cancel": "Anular o pedido de compromisso", - "billing_services_actions_menu_resiliate_my_engagement": "Rescindir o meu compromisso" + "billing_services_actions_menu_resiliate_my_engagement": "Rescindir o meu compromisso", + "billing_services_actions_menu_resiliate_LICENSE_HYCU": "Eliminar a minha licença Hycu" } diff --git a/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_de_DE.json b/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_de_DE.json index 0b4052dedfb4..dc7df049291f 100644 --- a/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_de_DE.json +++ b/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_de_DE.json @@ -11,5 +11,9 @@ "autorenew_agora_terminate_service_VRACK_SERVICES_RESOURCE": "vRack Services kündigen", "autorenew_agora_terminate_service_warning_VRACK_SERVICES_RESOURCE": "Bitte bestätigen Sie die Kündigung von vRack Services.", "autorenew_agora_terminate_service_success_VRACK_SERVICES_RESOURCE": "Ihre Anfrage zur Kündigung von vRack Services wurde registriert. Eine E-Mail mit weiteren Informationen zur Vorgehensweise wurde soeben an Sie versandt.", - "autorenew_agora_terminate_service_error_VRACK_SERVICES_RESOURCE": "Bei der Kündigung von vRack Services ist ein Fehler aufgetreten. {{error}}" + "autorenew_agora_terminate_service_error_VRACK_SERVICES_RESOURCE": "Bei der Kündigung von vRack Services ist ein Fehler aufgetreten. {{error}}", + "autorenew_agora_terminate_service_LICENSE_HYCU": "Meine HYCU-Lizenz kündigen", + "autorenew_agora_terminate_service_warning_LICENSE_HYCU": "Bitte bestätigen Sie die Kündigung Ihrer HYCU-Lizenz.", + "autorenew_agora_terminate_service_success_LICENSE_HYCU": "Ihre Anfrage zur Kündigung Ihrer HYCU-Lizenz wurde registriert. Eine E-Mail mit weiteren Informationen zur Vorgehensweise wurde soeben an Sie versandt.", + "autorenew_agora_terminate_service_error_LICENSE_HYCU": "Bei der Anfrage zur Kündigung Ihrer HYCU-Lizenz ist ein Fehler aufgetreten. {{error}}" } diff --git a/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_en_GB.json b/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_en_GB.json index c1cf00a52c7e..fb9494baaf0e 100644 --- a/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_en_GB.json +++ b/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_en_GB.json @@ -11,5 +11,9 @@ "autorenew_agora_terminate_service_VRACK_SERVICES_RESOURCE": "Cancel vRack Services", "autorenew_agora_terminate_service_warning_VRACK_SERVICES_RESOURCE": "Please confirm the cancellation of vRack Services", "autorenew_agora_terminate_service_success_VRACK_SERVICES_RESOURCE": "Your request to cancel vRack Services has been processed. You have been sent an email detailing the procedure to follow.", - "autorenew_agora_terminate_service_error_VRACK_SERVICES_RESOURCE": "An error has occurred cancelling vRack Services. {{error}}" + "autorenew_agora_terminate_service_error_VRACK_SERVICES_RESOURCE": "An error has occurred cancelling vRack Services. {{error}}", + "autorenew_agora_terminate_service_LICENSE_HYCU": "Cancel my HYCU licence", + "autorenew_agora_terminate_service_warning_LICENSE_HYCU": "Please confirm the cancellation of your HYCU licence", + "autorenew_agora_terminate_service_success_LICENSE_HYCU": "Your request to cancel your HYCU licence has been processed. You have been sent an email detailing the procedure to follow.", + "autorenew_agora_terminate_service_error_LICENSE_HYCU": "An error has occurred submitting your HYCU licence cancellation request. {{error}}" } diff --git a/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_es_ES.json b/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_es_ES.json index 9fa3c4a578c8..1ce9b4cd8d09 100644 --- a/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_es_ES.json +++ b/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_es_ES.json @@ -11,5 +11,9 @@ "autorenew_agora_terminate_service_VRACK_SERVICES_RESOURCE": "Dar de baja los vRack Services", "autorenew_agora_terminate_service_warning_VRACK_SERVICES_RESOURCE": "Por favor, confirme la baja de los vRack Services", "autorenew_agora_terminate_service_success_VRACK_SERVICES_RESOURCE": "La solicitud de baja de los vRack Services se ha enviado correctamente. Le hemos enviado un mensaje de correo electrónico con el procedimiento que debe seguir.", - "autorenew_agora_terminate_service_error_VRACK_SERVICES_RESOURCE": "Se ha producido un error al solicitar la baja de los vRack Services: {{error}}" + "autorenew_agora_terminate_service_error_VRACK_SERVICES_RESOURCE": "Se ha producido un error al solicitar la baja de los vRack Services: {{error}}", + "autorenew_agora_terminate_service_LICENSE_HYCU": "Dar de baja mi licencia HYCU", + "autorenew_agora_terminate_service_warning_LICENSE_HYCU": "Por favor, confirme la baja de su licencia HYCU", + "autorenew_agora_terminate_service_success_LICENSE_HYCU": "La solicitud de baja de su licencia HYCU se ha enviado. Le hemos enviado un mensaje de correo electrónico con el procedimiento que debe seguir.", + "autorenew_agora_terminate_service_error_LICENSE_HYCU": "Se ha producido un error al solicitar la baja de su licencia HYCU. {{error}}" } diff --git a/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_fr_CA.json b/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_fr_CA.json index 538233fa726b..93ad21923a09 100644 --- a/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_fr_CA.json +++ b/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_fr_CA.json @@ -1,10 +1,14 @@ { + "autorenew_agora_terminate_service_LICENSE_HYCU": "Résilier ma licence HYCU", "autorenew_agora_terminate_service_OKMS_RESOURCE": "Résilier mon KMS", "autorenew_agora_terminate_service_VRACK_SERVICES_RESOURCE": "Résilier vRack Services", + "autorenew_agora_terminate_service_warning_LICENSE_HYCU": "Veuillez confirmer la résiliation de votre licence HYCU", "autorenew_agora_terminate_service_warning_OKMS_RESOURCE": "Veuillez confirmer la résiliation de votre KMS", "autorenew_agora_terminate_service_warning_VRACK_SERVICES_RESOURCE": "Veuillez confirmer la résiliation de vRAck Services", + "autorenew_agora_terminate_service_success_LICENSE_HYCU": "Votre demande de résiliation de votre licence HYCU a été prise en compte. Un e-mail contenant la procédure vous a été envoyé.", "autorenew_agora_terminate_service_success_OKMS_RESOURCE": "Votre demande de résiliation de votre KMS a été prise en compte. Un e-mail contenant la procédure vous a été envoyé.", "autorenew_agora_terminate_service_success_VRACK_SERVICES_RESOURCE": "Votre demande de résiliation de vRAck Services a été prise en compte. Un e-mail contenant la procédure vous a été envoyé.", + "autorenew_agora_terminate_service_error_LICENSE_HYCU": "Une erreur est survenue lors de la demande de résiliation de votre licence HYCU. {{error}}", "autorenew_agora_terminate_service_error_OKMS_RESOURCE": "Une erreur est survenue lors de la demande de résiliation de votre KMS. {{error}}", "autorenew_agora_terminate_service_DBAAS_LOGS": "Résilier mon LDP", "autorenew_agora_terminate_service_warning_DBAAS_LOGS": "Veuillez confirmer la résiliation de votre LDP", diff --git a/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_it_IT.json b/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_it_IT.json index 88a753e99eab..a81e2b690fb9 100644 --- a/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_it_IT.json +++ b/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_it_IT.json @@ -11,5 +11,9 @@ "autorenew_agora_terminate_service_VRACK_SERVICES_RESOURCE": "Disattivare vRack Services", "autorenew_agora_terminate_service_warning_VRACK_SERVICES_RESOURCE": "Conferma la disattivazione di vRack Services", "autorenew_agora_terminate_service_success_VRACK_SERVICES_RESOURCE": "La tua richiesta di disattivazione di vRack Services è stata presa in carico. Ti abbiamo inviato un’email con la procedura da seguire.", - "autorenew_agora_terminate_service_error_VRACK_SERVICES_RESOURCE": "Si è verificato un errore durante la richiesta di disattivazione di vRack Services. {{error}}" + "autorenew_agora_terminate_service_error_VRACK_SERVICES_RESOURCE": "Si è verificato un errore durante la richiesta di disattivazione di vRack Services. {{error}}", + "autorenew_agora_terminate_service_LICENSE_HYCU": "Disattivare la tua licenza HYCU", + "autorenew_agora_terminate_service_warning_LICENSE_HYCU": "Conferma la disattivazione della tua licenza HYCU", + "autorenew_agora_terminate_service_success_LICENSE_HYCU": "La tua richiesta di disattivazione della licenza HYCU è stata presa in carico. Ti abbiamo inviato un’email con la procedura da seguire.", + "autorenew_agora_terminate_service_error_LICENSE_HYCU": "Si è verificato un errore durante la richiesta di disattivazione della tua licenza HYCU: {{error}}" } diff --git a/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_pl_PL.json b/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_pl_PL.json index 45bc1da37ef3..4442eecb4ddf 100644 --- a/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_pl_PL.json +++ b/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_pl_PL.json @@ -11,5 +11,9 @@ "autorenew_agora_terminate_service_VRACK_SERVICES_RESOURCE": "Rezygnacja z vRack Services", "autorenew_agora_terminate_service_warning_VRACK_SERVICES_RESOURCE": "Potwierdź rezygnację z vRAck Services", "autorenew_agora_terminate_service_success_VRACK_SERVICES_RESOURCE": "Rezygnacja z vRAck Services została zarejestrowana. Otrzymasz e-mail z opisem dalszej procedury.", - "autorenew_agora_terminate_service_error_VRACK_SERVICES_RESOURCE": "Wystąpił błąd podczas rezygnacji z vRack Services. {{error}}" + "autorenew_agora_terminate_service_error_VRACK_SERVICES_RESOURCE": "Wystąpił błąd podczas rezygnacji z vRack Services. {{error}}", + "autorenew_agora_terminate_service_LICENSE_HYCU": "Rezygnacja z licencji HYCU", + "autorenew_agora_terminate_service_warning_LICENSE_HYCU": "Potwierdź rezygnację z licencji HYCU", + "autorenew_agora_terminate_service_success_LICENSE_HYCU": "Rezygnacja z licencji HYCU została przyjęta. Otrzymasz e-mail z opisem dalszej procedury.", + "autorenew_agora_terminate_service_error_LICENSE_HYCU": "Wystąpił błąd podczas składania rezygnacji z licencji HYCU. {{error}}" } diff --git a/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_pt_PT.json b/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_pt_PT.json index 59540bdf05c7..57900007b479 100644 --- a/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_pt_PT.json +++ b/packages/manager/modules/billing/src/autoRenew/actions/terminate-agora-service/translations/Messages_pt_PT.json @@ -11,5 +11,9 @@ "autorenew_agora_terminate_service_VRACK_SERVICES_RESOURCE": "Rescindir vRack Services", "autorenew_agora_terminate_service_warning_VRACK_SERVICES_RESOURCE": "Confirme a rescisão de vRack Services", "autorenew_agora_terminate_service_success_VRACK_SERVICES_RESOURCE": "O seu pedido de rescisão de vRack Services foi registado com êxito. Um e-mail com o procedimento foi-lhe enviado.", - "autorenew_agora_terminate_service_error_VRACK_SERVICES_RESOURCE": "Ocorreu um erro aquando do pedido de rescisão de vRack Services. {{error}}" + "autorenew_agora_terminate_service_error_VRACK_SERVICES_RESOURCE": "Ocorreu um erro aquando do pedido de rescisão de vRack Services. {{error}}", + "autorenew_agora_terminate_service_LICENSE_HYCU": "Cancelar a minha licença HYCU", + "autorenew_agora_terminate_service_warning_LICENSE_HYCU": "Confirme o cancelamento da sua licença HYCU", + "autorenew_agora_terminate_service_success_LICENSE_HYCU": "O seu pedido de cancelamento da sua licença HYCU foi registado com êxito. Um e-mail com o procedimento foi-lhe enviado.", + "autorenew_agora_terminate_service_error_LICENSE_HYCU": "Ocorreu um erro aquando do pedido de cancelamento da sua licença HYCU. {{error}}" } diff --git a/packages/manager/modules/billing/src/autoRenew/translations/Messages_de_DE.json b/packages/manager/modules/billing/src/autoRenew/translations/Messages_de_DE.json index 159724837b4b..2a6386b3bc73 100644 --- a/packages/manager/modules/billing/src/autoRenew/translations/Messages_de_DE.json +++ b/packages/manager/modules/billing/src/autoRenew/translations/Messages_de_DE.json @@ -154,5 +154,6 @@ "billing_autorenew_service_type_DEDICATED_CLUSTER": "Region 3-AZ", "billing_autorenew_service_type_OKMS_RESOURCE": "OVHcloud KMS", "billing_autorenew_service_type_VRACK_SERVICES_RESOURCE": "vRack Services", - "billing_autorenew_service_type_VMWARE_CLOUD_DIRECTOR_ORGANIZATION": "Managed VCD" + "billing_autorenew_service_type_VMWARE_CLOUD_DIRECTOR_ORGANIZATION": "Managed VCD", + "billing_autorenew_service_type_LICENSE_HYCU": "HYCU" } diff --git a/packages/manager/modules/billing/src/autoRenew/translations/Messages_en_GB.json b/packages/manager/modules/billing/src/autoRenew/translations/Messages_en_GB.json index dec2e79237e0..cc7e8c3f2590 100644 --- a/packages/manager/modules/billing/src/autoRenew/translations/Messages_en_GB.json +++ b/packages/manager/modules/billing/src/autoRenew/translations/Messages_en_GB.json @@ -154,5 +154,6 @@ "billing_autorenew_service_type_DEDICATED_CLUSTER": " 3-AZ Region", "billing_autorenew_service_type_OKMS_RESOURCE": "OVHcloud KMS", "billing_autorenew_service_type_VRACK_SERVICES_RESOURCE": "vRack Services", - "billing_autorenew_service_type_VMWARE_CLOUD_DIRECTOR_ORGANIZATION": "Managed VCD" + "billing_autorenew_service_type_VMWARE_CLOUD_DIRECTOR_ORGANIZATION": "Managed VCD", + "billing_autorenew_service_type_LICENSE_HYCU": "HYCU" } diff --git a/packages/manager/modules/billing/src/autoRenew/translations/Messages_es_ES.json b/packages/manager/modules/billing/src/autoRenew/translations/Messages_es_ES.json index c35c53413f7b..b0a1f7b1cbe6 100644 --- a/packages/manager/modules/billing/src/autoRenew/translations/Messages_es_ES.json +++ b/packages/manager/modules/billing/src/autoRenew/translations/Messages_es_ES.json @@ -154,5 +154,6 @@ "billing_autorenew_service_type_DEDICATED_CLUSTER": "Región 3-AZ", "billing_autorenew_service_type_OKMS_RESOURCE": "OVHcloud KMS", "billing_autorenew_service_type_VRACK_SERVICES_RESOURCE": "vRack Services", - "billing_autorenew_service_type_VMWARE_CLOUD_DIRECTOR_ORGANIZATION": "Managed VCD" + "billing_autorenew_service_type_VMWARE_CLOUD_DIRECTOR_ORGANIZATION": "Managed VCD", + "billing_autorenew_service_type_LICENSE_HYCU": "HYCU" } diff --git a/packages/manager/modules/billing/src/autoRenew/translations/Messages_fr_CA.json b/packages/manager/modules/billing/src/autoRenew/translations/Messages_fr_CA.json index a2061afbd2e6..b905a258f263 100644 --- a/packages/manager/modules/billing/src/autoRenew/translations/Messages_fr_CA.json +++ b/packages/manager/modules/billing/src/autoRenew/translations/Messages_fr_CA.json @@ -149,6 +149,7 @@ "billing_autorenew_service_type_LICENSE_SQLSERVER": "Licences SQL Server", "billing_autorenew_service_type_LICENCE_SQLSERVER": "Licences SQL Server", "billing_autorenew_service_type_LICENSE_OFFICE_PREPAID": "Licences Office 365", + "billing_autorenew_service_type_LICENSE_HYCU": "HYCU", "billing_autorenew_service_type_MS_SERVICES_SHAREPOINT": "Microsoft SharePoint", "billing_autorenew_service_type_PACK_XDSL": "Packs xDSL", "billing_autorenew_service_type_VRACK": "vRacks", diff --git a/packages/manager/modules/billing/src/autoRenew/translations/Messages_it_IT.json b/packages/manager/modules/billing/src/autoRenew/translations/Messages_it_IT.json index 21cbddd2200c..933306f6d7ae 100644 --- a/packages/manager/modules/billing/src/autoRenew/translations/Messages_it_IT.json +++ b/packages/manager/modules/billing/src/autoRenew/translations/Messages_it_IT.json @@ -154,5 +154,6 @@ "billing_autorenew_service_type_DEDICATED_CLUSTER": "Region 3-AZ", "billing_autorenew_service_type_OKMS_RESOURCE": "OVHcloud KMS", "billing_autorenew_service_type_VRACK_SERVICES_RESOURCE": "vRack Services", - "billing_autorenew_service_type_VMWARE_CLOUD_DIRECTOR_ORGANIZATION": "Managed VCD" + "billing_autorenew_service_type_VMWARE_CLOUD_DIRECTOR_ORGANIZATION": "Managed VCD", + "billing_autorenew_service_type_LICENSE_HYCU": "HYCU" } diff --git a/packages/manager/modules/billing/src/autoRenew/translations/Messages_pl_PL.json b/packages/manager/modules/billing/src/autoRenew/translations/Messages_pl_PL.json index e3a6fc88ece7..d7541329680a 100644 --- a/packages/manager/modules/billing/src/autoRenew/translations/Messages_pl_PL.json +++ b/packages/manager/modules/billing/src/autoRenew/translations/Messages_pl_PL.json @@ -154,5 +154,6 @@ "billing_autorenew_service_type_DEDICATED_CLUSTER": "Region 3-AZ", "billing_autorenew_service_type_OKMS_RESOURCE": "OVHcloud KMS", "billing_autorenew_service_type_VRACK_SERVICES_RESOURCE": "vRack Services", - "billing_autorenew_service_type_VMWARE_CLOUD_DIRECTOR_ORGANIZATION": "Managed VCD" + "billing_autorenew_service_type_VMWARE_CLOUD_DIRECTOR_ORGANIZATION": "Managed VCD", + "billing_autorenew_service_type_LICENSE_HYCU": "HYCU" } diff --git a/packages/manager/modules/billing/src/autoRenew/translations/Messages_pt_PT.json b/packages/manager/modules/billing/src/autoRenew/translations/Messages_pt_PT.json index f110014f341d..37a7c7fc9ad4 100644 --- a/packages/manager/modules/billing/src/autoRenew/translations/Messages_pt_PT.json +++ b/packages/manager/modules/billing/src/autoRenew/translations/Messages_pt_PT.json @@ -154,5 +154,6 @@ "billing_autorenew_service_type_DEDICATED_CLUSTER": "Região 3-AZ", "billing_autorenew_service_type_OKMS_RESOURCE": "OVHcloud KMS", "billing_autorenew_service_type_VRACK_SERVICES_RESOURCE": "vRack Services", - "billing_autorenew_service_type_VMWARE_CLOUD_DIRECTOR_ORGANIZATION": "Managed VCD" + "billing_autorenew_service_type_VMWARE_CLOUD_DIRECTOR_ORGANIZATION": "Managed VCD", + "billing_autorenew_service_type_LICENSE_HYCU": "HYCU" } diff --git a/packages/manager/modules/hub/src/components/products/translations/Messages_de_DE.json b/packages/manager/modules/hub/src/components/products/translations/Messages_de_DE.json index 4efff679df00..a8c25f754fae 100644 --- a/packages/manager/modules/hub/src/components/products/translations/Messages_de_DE.json +++ b/packages/manager/modules/hub/src/components/products/translations/Messages_de_DE.json @@ -68,5 +68,6 @@ "manager_hub_products_VEEAM_ENTERPRISE": "Veeam Enterprise", "manager_hub_products_VRACK_SERVICES": "vRack Services", "manager_hub_products_KEY_MANAGEMENT_SERVICE": "Key Management Service", - "manager_hub_products_VMWARE_CLOUD_DIRECTOR": "Managed VCD" + "manager_hub_products_VMWARE_CLOUD_DIRECTOR": "Managed VCD", + "manager_hub_products_LICENSE_HYCU": "HYCU" } diff --git a/packages/manager/modules/hub/src/components/products/translations/Messages_en_GB.json b/packages/manager/modules/hub/src/components/products/translations/Messages_en_GB.json index 22735935f71e..af2c44e74cf8 100644 --- a/packages/manager/modules/hub/src/components/products/translations/Messages_en_GB.json +++ b/packages/manager/modules/hub/src/components/products/translations/Messages_en_GB.json @@ -68,5 +68,6 @@ "manager_hub_products_see_all": "See all", "manager_hub_products_VRACK_SERVICES": "vRack Services", "manager_hub_products_KEY_MANAGEMENT_SERVICE": "Key Management Service", - "manager_hub_products_VMWARE_CLOUD_DIRECTOR": "Managed VCD" + "manager_hub_products_VMWARE_CLOUD_DIRECTOR": "Managed VCD", + "manager_hub_products_LICENSE_HYCU": "HYCU" } diff --git a/packages/manager/modules/hub/src/components/products/translations/Messages_es_ES.json b/packages/manager/modules/hub/src/components/products/translations/Messages_es_ES.json index 47aedb138b8d..981f10ba9f37 100644 --- a/packages/manager/modules/hub/src/components/products/translations/Messages_es_ES.json +++ b/packages/manager/modules/hub/src/components/products/translations/Messages_es_ES.json @@ -68,5 +68,6 @@ "manager_hub_products_VEEAM_ENTERPRISE": "Veeam Enterprise", "manager_hub_products_VRACK_SERVICES": "vRack Services", "manager_hub_products_KEY_MANAGEMENT_SERVICE": "Key Management Service", - "manager_hub_products_VMWARE_CLOUD_DIRECTOR": "Managed VCD" + "manager_hub_products_VMWARE_CLOUD_DIRECTOR": "Managed VCD", + "manager_hub_products_LICENSE_HYCU": "HYCU" } diff --git a/packages/manager/modules/hub/src/components/products/translations/Messages_fr_CA.json b/packages/manager/modules/hub/src/components/products/translations/Messages_fr_CA.json index 194be480d691..a1a408d8a402 100644 --- a/packages/manager/modules/hub/src/components/products/translations/Messages_fr_CA.json +++ b/packages/manager/modules/hub/src/components/products/translations/Messages_fr_CA.json @@ -36,6 +36,7 @@ "manager_hub_products_LICENSE_VIRTUOZZO": "Licences Virtuozzo", "manager_hub_products_LICENSE_WORKLIGHT": "Licences Worklight", "manager_hub_products_LICENSE_SQLSERVER": "Licences SQL Server", + "manager_hub_products_LICENSE_HYCU": "HYCU", "manager_hub_products_LICENCE_WINDOWS": "Licences Windows", "manager_hub_products_LICENCE_OFFICE": "Licences Office 365", "manager_hub_products_LICENCE_CLOUD_LINUX": "Licences CloudLinux", diff --git a/packages/manager/modules/hub/src/components/products/translations/Messages_it_IT.json b/packages/manager/modules/hub/src/components/products/translations/Messages_it_IT.json index 269b49e808ed..8d3985e6d3b0 100644 --- a/packages/manager/modules/hub/src/components/products/translations/Messages_it_IT.json +++ b/packages/manager/modules/hub/src/components/products/translations/Messages_it_IT.json @@ -68,5 +68,6 @@ "manager_hub_products_VEEAM_ENTERPRISE": "Veeam Enterprise", "manager_hub_products_VRACK_SERVICES": "vRack Services", "manager_hub_products_KEY_MANAGEMENT_SERVICE": "Key Management Service", - "manager_hub_products_VMWARE_CLOUD_DIRECTOR": "Managed VCD" + "manager_hub_products_VMWARE_CLOUD_DIRECTOR": "Managed VCD", + "manager_hub_products_LICENSE_HYCU": "HYCU" } diff --git a/packages/manager/modules/hub/src/components/products/translations/Messages_pl_PL.json b/packages/manager/modules/hub/src/components/products/translations/Messages_pl_PL.json index 49e4cf103b9b..d190473d323a 100644 --- a/packages/manager/modules/hub/src/components/products/translations/Messages_pl_PL.json +++ b/packages/manager/modules/hub/src/components/products/translations/Messages_pl_PL.json @@ -68,5 +68,6 @@ "manager_hub_products_VEEAM_ENTERPRISE": "Veeam Enterprise", "manager_hub_products_VRACK_SERVICES": "vRack Services", "manager_hub_products_KEY_MANAGEMENT_SERVICE": "Key Management Service", - "manager_hub_products_VMWARE_CLOUD_DIRECTOR": "Managed VCD" + "manager_hub_products_VMWARE_CLOUD_DIRECTOR": "Managed VCD", + "manager_hub_products_LICENSE_HYCU": "HYCU" } diff --git a/packages/manager/modules/hub/src/components/products/translations/Messages_pt_PT.json b/packages/manager/modules/hub/src/components/products/translations/Messages_pt_PT.json index 6be161c7a751..a006d84a8624 100644 --- a/packages/manager/modules/hub/src/components/products/translations/Messages_pt_PT.json +++ b/packages/manager/modules/hub/src/components/products/translations/Messages_pt_PT.json @@ -68,5 +68,6 @@ "manager_hub_products_VEEAM_ENTERPRISE": "Veeam Enterprise", "manager_hub_products_VRACK_SERVICES": "vRack Services", "manager_hub_products_KEY_MANAGEMENT_SERVICE": "Key Management Service", - "manager_hub_products_VMWARE_CLOUD_DIRECTOR": "Managed VCD" + "manager_hub_products_VMWARE_CLOUD_DIRECTOR": "Managed VCD", + "manager_hub_products_LICENSE_HYCU": "HYCU" }