Skip to content

Commit

Permalink
Merge pull request #11896 from ovh/feat/MANAGER-14005
Browse files Browse the repository at this point in the history
Feat/manager 14005
  • Loading branch information
vovh committed Jun 12, 2024
2 parents 0b09aa8 + 3da3334 commit 918ca13
Show file tree
Hide file tree
Showing 7 changed files with 299 additions and 33 deletions.
1 change: 1 addition & 0 deletions packages/manager/apps/key-management-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
},
});
};
Original file line number Diff line number Diff line change
@@ -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 */
Expand All @@ -15,3 +16,8 @@ export const getOkmsServiceId = async ({ okms }: GetOkmsServiceIdParams) => {
const resourceName = okms ? `?resourceName=${okms}` : '';
return apiClient.v6.get<number[]>(`/services${resourceName}`);
};

export const getServiceInfos = async ({ okms }: GetOkmsServiceIdParams) => {
const serviceId = await getOkmsServiceId({ okms });
return apiClient.v6.get<KMSServiceInfos>(`/services/${serviceId.data[0]}`);
};
Original file line number Diff line number Diff line change
Expand Up @@ -44,36 +44,38 @@ const Dashboard: React.FC<DashboardLayoutProps> = ({ tabs }) => {

return (
<>
<div className="py-4">
<OsdsText
level={ODS_TEXT_LEVEL.heading}
color={ODS_THEME_COLOR_INTENT.text}
size={ODS_TEXT_SIZE._600}
>
{location.pathname.split('/')[2]}
</OsdsText>
<div className="mb-6">
<div className="py-4">
<OsdsText
level={ODS_TEXT_LEVEL.heading}
color={ODS_THEME_COLOR_INTENT.text}
size={ODS_TEXT_SIZE._600}
>
{location.pathname.split('/')[2]}
</OsdsText>
</div>
<OsdsTabs panel={panel}>
<OsdsTabBar slot="top">
{tabs.map((tab: DashboardTabItemProps) => (
<OsdsTabBarItem
key={`osds-tab-bar-item-${tab.name}`}
panel={tab.name}
disabled={tab.disabled}
className="flex items-center justify-center"
>
<NavLink to={tab.to} className="no-underline">
{tab.title}
</NavLink>
{tab.disabled && (
<OsdsChip size={ODS_CHIP_SIZE.sm} inline className="ml-2">
{t('key_management_service_dashboard_tab_comming_soon')}
</OsdsChip>
)}
</OsdsTabBarItem>
))}
</OsdsTabBar>
</OsdsTabs>
</div>
<OsdsTabs panel={panel}>
<OsdsTabBar slot="top">
{tabs.map((tab: DashboardTabItemProps) => (
<OsdsTabBarItem
key={`osds-tab-bar-item-${tab.name}`}
panel={tab.name}
disabled={tab.disabled}
className="flex items-center justify-center"
>
<NavLink to={tab.to} className="no-underline">
{tab.title}
</NavLink>
{tab.disabled && (
<OsdsChip size={ODS_CHIP_SIZE.sm} inline className="ml-2">
{t('key_management_service_dashboard_tab_comming_soon')}
</OsdsChip>
)}
</OsdsTabBarItem>
))}
</OsdsTabBar>
</OsdsTabs>
<Outlet />
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
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_TEXT_COLOR_INTENT,
ODS_TEXT_LEVEL,
ODS_TEXT_SIZE,
} from '@ovhcloud/ods-components';
import { ShellContext } from '@ovh-ux/manager-react-shell-client';
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, shell } = useContext(ShellContext);
const [dateTimeFormat, setDateTimeFormat] = useState<Intl.DateTimeFormat>();
const [contactURL, setContactUrl] = useState<string>();

const getContactUrl = async () => {
const url = await shell.navigation.getURL(
'dedicated',
'#/contacts/services',
{},
);
setContactUrl(url as string);
};

useEffect(() => {
getContactUrl();
}, [shell]);

useEffect(() => {
setDateTimeFormat(
new Intl.DateTimeFormat(environment.getUserLocale().replace('_', '-'), {
day: '2-digit',
month: '2-digit',
year: 'numeric',
}),
);
}, [environment]);

return (
<OsdsTile className="w-full h-fit flex-col" inline rounded>
<div className="flex flex-col w-full">
<OsdsText
size={ODS_TEXT_SIZE._400}
level={ODS_TEXT_LEVEL.heading}
color={ODS_THEME_COLOR_INTENT.text}
>
{t('billing_informations')}
</OsdsText>
<OsdsDivider separator />
<div className="flex flex-col mb-3">
<OsdsText
className="mb-4"
size={ODS_TEXT_SIZE._200}
level={ODS_TEXT_LEVEL.heading}
color={ODS_THEME_COLOR_INTENT.text}
>
{t('key_management_service_dashboard_field_label_creation_date')}
</OsdsText>
<div className="flex flex-row justify-between items-center">
<OsdsText
className="mb-4"
size={ODS_TEXT_SIZE._400}
level={ODS_TEXT_LEVEL.body}
color={ODS_THEME_COLOR_INTENT.default}
>
{kmsService &&
dateTimeFormat.format(
parseISO(
kmsService?.data.billing.lifecycle.current.creationDate,
),
)}
</OsdsText>
</div>
<OsdsDivider separator />
<OsdsText
className="mb-4"
size={ODS_TEXT_SIZE._200}
level={ODS_TEXT_LEVEL.heading}
color={ODS_THEME_COLOR_INTENT.text}
>
{t(
'key_management_service_dashboard_field_label_next_billing_date',
)}
</OsdsText>
<div className="flex flex-row justify-between items-center">
<OsdsText
className="mb-4"
size={ODS_TEXT_SIZE._400}
level={ODS_TEXT_LEVEL.body}
color={ODS_THEME_COLOR_INTENT.default}
>
{kmsService &&
dateTimeFormat.format(
parseISO(kmsService?.data.billing.nextBillingDate),
)}
</OsdsText>
<div className="flex flex-row align-center gap-4">
<OsdsChip color={ODS_TEXT_COLOR_INTENT.success}>
{t(
'key_management_service_dashboard_field_label_engagement_renew_auto',
)}
</OsdsChip>
<OsdsButton
className="w-fit"
variant={ODS_BUTTON_VARIANT.stroked}
size={ODS_BUTTON_SIZE.sm}
color={ODS_THEME_COLOR_INTENT.primary}
>
<OsdsIcon
color={ODS_THEME_COLOR_INTENT.primary}
name={ODS_ICON_NAME.ELLIPSIS_VERTICAL}
size={ODS_ICON_SIZE.xs}
/>
</OsdsButton>
</div>
</div>
<OsdsDivider separator />
<div className="flex flex-row justify-between items-center">
<OsdsText
className="mb-4"
size={ODS_TEXT_SIZE._200}
level={ODS_TEXT_LEVEL.heading}
color={ODS_THEME_COLOR_INTENT.text}
>
{t('key_management_service_dashboard_field_label_engagement')}
</OsdsText>
<OsdsChip color={ODS_TEXT_COLOR_INTENT.error}>
{kmsService?.data.billing.engagement
? kmsService.data.billing.engagement
: t(
'key_management_service_dashboard_field_label_engagement_none',
)}
</OsdsChip>
</div>
<OsdsDivider separator />
<OsdsText
className="mb-4"
size={ODS_TEXT_SIZE._200}
level={ODS_TEXT_LEVEL.heading}
color={ODS_THEME_COLOR_INTENT.text}
>
{t('key_management_service_dashboard_field_label_contacts')}
</OsdsText>
{kmsService?.data.customer.contacts.map((contact) => {
return (
<OsdsText
key={contact.customerCode + contact.type}
className="mb-4"
size={ODS_TEXT_SIZE._400}
level={ODS_TEXT_LEVEL.body}
color={ODS_THEME_COLOR_INTENT.default}
>
{`${contact.customerCode} ${t(
`key_management_service_dashboard_contact_type_${contact.type}`,
)}`}
</OsdsText>
);
})}
<div className="flex flex-row items-center">
<OsdsLink href={contactURL} color={ODS_THEME_COLOR_INTENT.primary}>
{t(
'key_management_service_dashboard_field_label_manage_contacts',
)}
</OsdsLink>
<OsdsIcon
className="pl-4"
name={ODS_ICON_NAME.ARROW_RIGHT}
size={ODS_ICON_SIZE.xs}
color={ODS_THEME_COLOR_INTENT.info}
></OsdsIcon>
</div>
</div>
</div>
</OsdsTile>
);
};

export default BillingInformationsTile;
Original file line number Diff line number Diff line change
@@ -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();
Expand All @@ -26,12 +26,12 @@ function GeneralInformationsTab() {
}

return (
<div className="grid xs:grid-cols-1 sm:grid-cols-3 py-6">
<div className="grid xs:grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-3">
<div className="p-3">
<InformationsTile okmsData={data.data} />
</div>
<div className="p-3">
<OsdsTile>Billing informations (Soon)</OsdsTile>
<BillingInformationsTile okmsData={data.data} />
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}

0 comments on commit 918ca13

Please sign in to comment.