From f39e5665b076471c4cc509027575e3a4a418c335 Mon Sep 17 00:00:00 2001 From: Vincent BONMARCHAND Date: Wed, 5 Jun 2024 09:19:31 +0200 Subject: [PATCH] feat(key-management-service): add billing section in dashboard ref: MANAGER-14005 Signed-off-by: Vincent BONMARCHAND --- .../apps/key-management-service/package.json | 1 + .../src/api/hooks/useKMSServiceInfos.ts | 44 ++++ .../src/api/services/get.ts | 6 + .../layout-helpers/Dashboard/Dashboard.tsx | 60 +++--- .../BillingInformationsTile.tsx | 197 ++++++++++++++++++ .../dashboard/tabs/GeneralInformations.tsx | 6 +- .../dashboard/Messages_fr_FR.json | 13 +- 7 files changed, 294 insertions(+), 33 deletions(-) create mode 100644 packages/manager/apps/key-management-service/src/api/hooks/useKMSServiceInfos.ts create mode 100644 packages/manager/apps/key-management-service/src/components/layout-helpers/Dashboard/GeneralInformationsTiles/BillingInformationsTile.tsx diff --git a/packages/manager/apps/key-management-service/package.json b/packages/manager/apps/key-management-service/package.json index f3b83dfc8376..9caa5fc07ca7 100644 --- a/packages/manager/apps/key-management-service/package.json +++ b/packages/manager/apps/key-management-service/package.json @@ -34,6 +34,7 @@ "@ovhcloud/ods-theme-blue-jeans": "17.2.1", "@tanstack/react-query": "^5.12.2", "@tanstack/react-table": "^8.11.6", + "date-fns": "^3.2.0", "i18next": "^20.4.0", "i18next-http-backend": "2.5.0", "react": "^18.2.0", diff --git a/packages/manager/apps/key-management-service/src/api/hooks/useKMSServiceInfos.ts b/packages/manager/apps/key-management-service/src/api/hooks/useKMSServiceInfos.ts new file mode 100644 index 000000000000..08e5fd5d1b68 --- /dev/null +++ b/packages/manager/apps/key-management-service/src/api/hooks/useKMSServiceInfos.ts @@ -0,0 +1,44 @@ +import { useQuery } from '@tanstack/react-query'; +import { getServiceInfos } from '../services'; +import { OKMS } from '@/interface'; +import { ErrorResponse } from '../GET/apiv2/services'; + +type ServiceLifecycleCurrent = { + creationDate: string; +}; + +type ServiceLifecycle = { + current: ServiceLifecycleCurrent; +}; + +type ServiceBilling = { + engagement?: string | null; + expirationDate?: string | null; + nextBillingDate: string; + lifecycle: ServiceLifecycle; +}; + +type ServiceContact = { + customerCode: string; + type: string; +}; + +type ServiceCustomer = { + contacts: ServiceContact[]; +}; + +export type KMSServiceInfos = { + billing: ServiceBilling; + customer: ServiceCustomer; +}; + +export const useKMSServiceInfos = (okms: OKMS) => { + return useQuery<{ data: KMSServiceInfos }, ErrorResponse>({ + queryKey: ['okms/service/infos', okms.id], + queryFn: () => getServiceInfos({ okms: okms.id }), + retry: false, + ...{ + keepPreviousData: true, + }, + }); +}; diff --git a/packages/manager/apps/key-management-service/src/api/services/get.ts b/packages/manager/apps/key-management-service/src/api/services/get.ts index 5735dcf9ef0c..9119e1349b2d 100644 --- a/packages/manager/apps/key-management-service/src/api/services/get.ts +++ b/packages/manager/apps/key-management-service/src/api/services/get.ts @@ -1,4 +1,5 @@ import { apiClient } from '@ovh-ux/manager-core-api'; +import { KMSServiceInfos } from '../hooks/useKMSServiceInfos'; export type GetOkmsServiceIdParams = { /** Filter on a specific service family */ @@ -15,3 +16,8 @@ export const getOkmsServiceId = async ({ okms }: GetOkmsServiceIdParams) => { const resourceName = okms ? `?resourceName=${okms}` : ''; return apiClient.v6.get(`/services${resourceName}`); }; + +export const getServiceInfos = async ({ okms }: GetOkmsServiceIdParams) => { + const serviceId = await getOkmsServiceId({ okms }); + return apiClient.v6.get(`/services/${serviceId.data[0]}`); +}; diff --git a/packages/manager/apps/key-management-service/src/components/layout-helpers/Dashboard/Dashboard.tsx b/packages/manager/apps/key-management-service/src/components/layout-helpers/Dashboard/Dashboard.tsx index 136c3c742ee6..fb94830bafb1 100644 --- a/packages/manager/apps/key-management-service/src/components/layout-helpers/Dashboard/Dashboard.tsx +++ b/packages/manager/apps/key-management-service/src/components/layout-helpers/Dashboard/Dashboard.tsx @@ -44,36 +44,38 @@ const Dashboard: React.FC = ({ tabs }) => { return ( <> -
- - {location.pathname.split('/')[2]} - +
+
+ + {location.pathname.split('/')[2]} + +
+ + + {tabs.map((tab: DashboardTabItemProps) => ( + + + {tab.title} + + {tab.disabled && ( + + {t('key_management_service_dashboard_tab_comming_soon')} + + )} + + ))} + +
- - - {tabs.map((tab: DashboardTabItemProps) => ( - - - {tab.title} - - {tab.disabled && ( - - {t('key_management_service_dashboard_tab_comming_soon')} - - )} - - ))} - - ); diff --git a/packages/manager/apps/key-management-service/src/components/layout-helpers/Dashboard/GeneralInformationsTiles/BillingInformationsTile.tsx b/packages/manager/apps/key-management-service/src/components/layout-helpers/Dashboard/GeneralInformationsTiles/BillingInformationsTile.tsx new file mode 100644 index 000000000000..8d04e832103c --- /dev/null +++ b/packages/manager/apps/key-management-service/src/components/layout-helpers/Dashboard/GeneralInformationsTiles/BillingInformationsTile.tsx @@ -0,0 +1,197 @@ +import React, { useContext, useEffect, useState } from 'react'; +import { + OsdsButton, + OsdsChip, + OsdsDivider, + OsdsIcon, + OsdsLink, + OsdsText, + OsdsTile, +} from '@ovhcloud/ods-components/react'; +import { + ODS_BUTTON_SIZE, + ODS_BUTTON_VARIANT, + ODS_ICON_NAME, + ODS_ICON_SIZE, + ODS_LINK_REFERRER_POLICY, + ODS_TEXT_COLOR_INTENT, + ODS_TEXT_LEVEL, + ODS_TEXT_SIZE, +} from '@ovhcloud/ods-components'; +import { ShellContext } from '@ovh-ux/manager-react-shell-client'; +import { OdsHTMLAnchorElementTarget } from '@ovhcloud/ods-common-core'; +import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import { useTranslation } from 'react-i18next'; +import { parseISO } from 'date-fns'; +import { OKMS } from '@/interface'; +import { useKMSServiceInfos } from '@/api/hooks/useKMSServiceInfos'; + +type BillingInformationsTileProps = { + okmsData?: OKMS; +}; + +const BillingInformationsTile = ({ + okmsData, +}: BillingInformationsTileProps) => { + const { data: kmsService } = useKMSServiceInfos(okmsData); + const { t } = useTranslation('key-management-service/dashboard'); + const { environment } = useContext(ShellContext); + const [dateTimeFormat, setDateTimeFormat] = useState(); + + useEffect(() => { + setDateTimeFormat( + new Intl.DateTimeFormat(environment.getUserLocale().replace('_', '-'), { + day: '2-digit', + month: '2-digit', + year: 'numeric', + }), + ); + }, [environment]); + + return ( + +
+ + {t('billing_informations')} + + +
+ + {t('key_management_service_dashboard_field_label_creation_date')} + +
+ + {kmsService && + dateTimeFormat.format( + parseISO( + kmsService?.data.billing.lifecycle.current.creationDate, + ), + )} + +
+ + + {t( + 'key_management_service_dashboard_field_label_next_billing_date', + )} + +
+ + {kmsService && + dateTimeFormat.format( + parseISO(kmsService?.data.billing.nextBillingDate), + )} + +
+ + {t( + 'key_management_service_dashboard_field_label_engagement_renew_auto', + )} + + + + +
+
+ +
+ + {t('key_management_service_dashboard_field_label_engagement')} + + + {kmsService?.data.billing.engagement + ? kmsService.data.billing.engagement + : t( + 'key_management_service_dashboard_field_label_engagement_none', + )} + +
+ + + {t('key_management_service_dashboard_field_label_contacts')} + + {kmsService?.data.customer.contacts.map((contact) => { + return ( + + {`${contact.customerCode} ${t( + `key_management_service_dashboard_contact_type_${contact.type}`, + )}`} + + ); + })} +
+ + {t( + 'key_management_service_dashboard_field_label_manage_contacts', + )} + + +
+
+
+
+ ); +}; + +export default BillingInformationsTile; diff --git a/packages/manager/apps/key-management-service/src/pages/dashboard/tabs/GeneralInformations.tsx b/packages/manager/apps/key-management-service/src/pages/dashboard/tabs/GeneralInformations.tsx index ac730150cd44..815f35418bff 100644 --- a/packages/manager/apps/key-management-service/src/pages/dashboard/tabs/GeneralInformations.tsx +++ b/packages/manager/apps/key-management-service/src/pages/dashboard/tabs/GeneralInformations.tsx @@ -1,11 +1,11 @@ import React from 'react'; -import { OsdsTile } from '@ovhcloud/ods-components/react'; import { useNavigate, useParams } from 'react-router-dom'; import { useOKMSById } from '@/hooks/useOKMS'; import Loading from '@/components/Loading/Loading'; import { ROUTES_URLS } from '@/routes/routes.constants'; import InformationsTile from '@/components/layout-helpers/Dashboard/GeneralInformationsTiles/InformationsTile'; +import BillingInformationsTile from '@/components/layout-helpers/Dashboard/GeneralInformationsTiles/BillingInformationsTile'; function GeneralInformationsTab() { const { okmsId } = useParams(); @@ -26,12 +26,12 @@ function GeneralInformationsTab() { } return ( -
+
- Billing informations (Soon) +
); diff --git a/packages/manager/apps/key-management-service/src/public/translations/key-management-service/dashboard/Messages_fr_FR.json b/packages/manager/apps/key-management-service/src/public/translations/key-management-service/dashboard/Messages_fr_FR.json index 3e8d0956c7f0..7f3065043dc5 100644 --- a/packages/manager/apps/key-management-service/src/public/translations/key-management-service/dashboard/Messages_fr_FR.json +++ b/packages/manager/apps/key-management-service/src/public/translations/key-management-service/dashboard/Messages_fr_FR.json @@ -35,5 +35,16 @@ "key_management_service_dashboard_region_ap_south_mum": "Asia Pacific (India - Mumbai)", "key_management_service_dashboard_region_labeu_west_1_preprod": "LABEU (France - Croix) (PREPROD)", "key_management_service_dashboard_region_labeu_west_1_dev_1": "LABEU (France - Croix) (DEV-1)", - "key_management_service_dashboard_region_labeu_west_1_dev_2": "LABEU (France - Croix) (DEV-2)" + "key_management_service_dashboard_region_labeu_west_1_dev_2": "LABEU (France - Croix) (DEV-2)", + "billing_informations": "Abonnement", + "key_management_service_dashboard_field_label_creation_date": "Date de création", + "key_management_service_dashboard_field_label_next_billing_date": "Prochaine échéance", + "key_management_service_dashboard_field_label_engagement": "Engagement", + "key_management_service_dashboard_field_label_contacts": "Contacts", + "key_management_service_dashboard_field_label_manage_contacts": "Gérer les contacts", + "key_management_service_dashboard_field_label_engagement_none": "Aucun", + "key_management_service_dashboard_field_label_engagement_renew_auto": "Renouv. Auto", + "key_management_service_dashboard_contact_type_administrator": "Administrateur", + "key_management_service_dashboard_contact_type_technical": "Technique", + "key_management_service_dashboard_contact_type_billing": "Facturation" }