Skip to content

Commit

Permalink
feat(web-office): add update displayName for title on dashboard
Browse files Browse the repository at this point in the history
ref:MANAGER-16189

Signed-off-by: stif59100 <[email protected]>
  • Loading branch information
stif59100 committed Dec 12, 2024
1 parent 023fd12 commit 71f7a39
Show file tree
Hide file tree
Showing 20 changed files with 259 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { OdsText } from '@ovhcloud/ods-components/react';
import { Title, Subtitle } from '../../typography';

export interface HeadersProps {
title?: string;
title?: React.ReactNode;
subtitle?: string;
description?: string;
headerButton?: React.ReactElement;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
"title": "Dashboard page",
"error_service": "No services info",
"microsoft_office_dashboard_consumption": "Consommation",
"microsoft_office_dashboard_licences": "Licences",
"microsoft_office_dashboard_licenses_group": "Groupes de licences",
"microsoft_office_dashboard_licenses": "Licences",
"microsoft_office_dashboard_edit-name": "Éditer",
"microsoft_office_modal_update_headline": "Changer le nom",
"microsoft_office_modal_update_description": "Veuilliez saisir le nouveau nom que vous souhaitez donner à votre service.",
"microsoft_office_modal_update_input_label": "Nouveau nom",
"microsoft_office_modal_update_confirm": "Confirmer",
"microsoft_office_modal_update_cancel": "Annuler",
"back_link": "Retour à la liste"
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"dashboard_users_table_firstName": "Prénom",
"dashboard_users_table_lastName": " Nom",
"dashboard_users_table_activationEmail": "Email d'activation",
"dashboard_users_table_licences": "Licences",
"dashboard_users_table_licenses": "Licences",
"dashboard_users_table_status": "Statut",
"dashboard_users_download_text": "Les programmes d'installation pour PC et MAC sont disponibles sur le site de microsoft <officeLink/>.",
"dashboard_users_download_info": "Pour smartphones et tablettes, rendez-vous directement dans votre App Store.",
Expand Down
18 changes: 14 additions & 4 deletions packages/manager/apps/web-office/src/api/license/api.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { v6 } from '@ovh-ux/manager-core-api';
import { GetOfficeLicenseServiceParams } from './type';
import { getApiPath, getApiPathWithoutServiceName } from '../utils/apiPath';
import { LicenseType } from './type';

// GET

export const getlicenseOfficeServiceQueryKey = (
params: GetOfficeLicenseServiceParams,
) => [`get/license/office/${params.serviceName}`];
export const getlicenseOfficeServiceQueryKey = (serviceName: string) => [
'get',
'license',
'office',
serviceName,
];

export const getOfficeLicenseDetails = async (serviceName: string) => {
const { data } = await v6.get(`${getApiPath(serviceName)}`);
Expand Down Expand Up @@ -35,5 +38,12 @@ export const getOfficePrepaidLicenses = async (serviceName: string) => {
// POST

// PUT
export const updateOfficeLicenseDetails = async (
serviceName: string,
licenseData: Partial<LicenseType>,
): Promise<LicenseType> => {
const { data } = await v6.put(getApiPath(serviceName), licenseData);
return data;
};

// DELETE
28 changes: 28 additions & 0 deletions packages/manager/apps/web-office/src/api/parentTenant/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { v6 } from '@ovh-ux/manager-core-api';
import { getApiPath } from '../utils/apiPath';
import { ParentTenantType } from './type';

// GET
export const getParentTenant = async (
serviceName: string,
): Promise<ParentTenantType> => {
const { data } = await v6.get<ParentTenantType>(
`${getApiPath(serviceName)}parentTenant`,
);
return data;
};
// POST

// PUT
export const updateParentTenant = async (
serviceName: string,
parentTenantData: Partial<ParentTenantType>,
): Promise<ParentTenantType> => {
const { data } = await v6.put<ParentTenantType>(
`${getApiPath(serviceName)}parentTenant`,
parentTenantData,
);
return data;
};

// DELETE
7 changes: 7 additions & 0 deletions packages/manager/apps/web-office/src/api/parentTenant/key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const getOfficeParentTenantQueryKey = (serviceName: string) => [
'get',
'license',
'officePrepaid',
serviceName,
'parentTenant',
];
15 changes: 15 additions & 0 deletions packages/manager/apps/web-office/src/api/parentTenant/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { UserStateEnum } from '../api.type';

export type ParentTenantType = {
address: string;
city: string;
creationDate: string;
displayName: string;
firstName: string;
lastName: string;
phone: string;
serviceName: string;
serviceType: string;
status: UserStateEnum;
zipCode: string;
};
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const Breadcrumb: React.FC<BreadcrumbProps> = () => {
label: pathParts[1],
href: `#/${pathParts.slice(0, 2).join('/')}`,
},
...breadcrumbParts.map((_, index) => {
...breadcrumbParts.map((_: any, index: number) => {
const label = t(
`microsoft_office_dashboard_${breadcrumbParts
.slice(0, index + 1)
Expand Down
1 change: 1 addition & 0 deletions packages/manager/apps/web-office/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './useOfficeLicenseDetails';
export * from './useGenerateUrl';
export * from './useOfficeServiceType';
export * from './useOfficeUsers';
export * from './officeParentTenant/getOfficeParentTenant';
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useQuery } from '@tanstack/react-query';
import { useParams } from 'react-router-dom';
import { useOfficeServiceType } from '../useOfficeServiceType';
import { getParentTenant } from '@/api/parentTenant/api';
import {
getlicenseOfficeServiceQueryKey,
getOfficeLicenseDetails,
} from '@/api/license/api';
import { getOfficeParentTenantQueryKey } from '@/api/parentTenant/key';

export const getOfficeParentTenant = () => {
const { serviceName } = useParams();
const serviceType = useOfficeServiceType(serviceName);
const isPrepaid = serviceType === 'prepaid';

return useQuery({
queryKey: [
isPrepaid
? getOfficeParentTenantQueryKey(serviceName)
: getlicenseOfficeServiceQueryKey(serviceName),
],
queryFn: isPrepaid
? () => getParentTenant(serviceName)
: () => getOfficeLicenseDetails(serviceName),
});
};
19 changes: 2 additions & 17 deletions packages/manager/apps/web-office/src/hooks/useGenerateUrl.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,17 @@
import { useHref } from 'react-router-dom';
import { useOfficeLicenseDetail } from '@/hooks';

export const UseGenerateUrl = (
baseURL: string,
type: 'path' | 'href' = 'path',
params?: Record<string, string | number>,
) => {
const { data: serviceName } = useOfficeLicenseDetail();

const URL = baseURL.replace(
':serviceName',
(params?.serviceName as string) || '',
);

const queryParams = {
...params,
...(serviceName && { serviceNameDetail: serviceName }),
};

const queryString = Object.entries(queryParams)
.filter(([key]) => key !== 'serviceName')
.map(([key, value]) => `${key}=${value}`)
.join('&');

const fullURL = queryString ? `${URL}?${queryString}` : URL;

if (type === 'href') {
return useHref(fullURL);
return useHref(URL);
}
return fullURL;
return URL;
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ export const useOfficeLicenseDetail = (
const { serviceName: selectedServiceName } = useParams();

return useQuery({
queryKey: getlicenseOfficeServiceQueryKey({
serviceName: serviceName || selectedServiceName,
}),
queryKey: getlicenseOfficeServiceQueryKey(
serviceName || selectedServiceName,
),
queryFn: () =>
getOfficeLicenseDetails(serviceName || selectedServiceName || ''),
enabled: Boolean(serviceName || selectedServiceName),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { UpdateNameModal } from '@ovh-ux/manager-react-components';
import { useNavigate, useParams } from 'react-router-dom';
import { useMutation } from '@tanstack/react-query';
import {
getOfficeParentTenant,
UseGenerateUrl,
useOfficeServiceType,
} from '@/hooks';
import queryClient from '@/queryClient';
import { ParentTenantType } from '@/api/parentTenant/type';
import { updateOfficeLicenseDetails } from '@/api/license/api';
import { updateParentTenant } from '@/api/parentTenant/api';
import { LicenseType } from '@/api/license/type';
import { getOfficeParentTenantQueryKey } from '@/api/parentTenant/key';
import { getOfficeLicenseDetailsQueryKey } from '@/api/license/key';

export default function UpdateDisplayNameModal() {
const navigate = useNavigate();
const { t } = useTranslation('dashboard');
const { serviceName } = useParams();
const serviceType = useOfficeServiceType(serviceName);
const isPrepaid = serviceType === 'prepaid';
const { data: getData, refetch } = getOfficeParentTenant();

const goBackUrl = UseGenerateUrl('..', 'path');
const closeModal = () => {
navigate(goBackUrl, { replace: true });
};
const { mutate: editName, isPending } = useMutation({
mutationFn: isPrepaid
? (parentTenantData: Partial<ParentTenantType>) =>
updateParentTenant(serviceName, parentTenantData)
: (licenseData: Partial<LicenseType>) =>
updateOfficeLicenseDetails(serviceName, licenseData),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: isPrepaid
? getOfficeParentTenantQueryKey(serviceName)
: getOfficeLicenseDetailsQueryKey(serviceName),
});
closeModal();
refetch();
},
});
const handleSaveClick = (displayName: string) => {
editName({ displayName });
};

return (
<UpdateNameModal
isOpen={true}
isLoading={isPending}
closeModal={closeModal}
headline={t('microsoft_office_modal_update_headline')}
description={t('microsoft_office_modal_update_description')}
inputLabel={t('microsoft_office_modal_update_input_label')}
defaultValue={getData?.displayName}
confirmButtonLabel={t('microsoft_office_modal_update_confirm')}
cancelButtonLabel={t('microsoft_office_modal_update_cancel')}
updateDisplayName={handleSaveClick}
/>
);
}
52 changes: 47 additions & 5 deletions packages/manager/apps/web-office/src/pages/dashboard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Outlet, useParams, useResolvedPath } from 'react-router-dom';

import {
Outlet,
useNavigate,
useParams,
useResolvedPath,
} from 'react-router-dom';
import { BaseLayout } from '@ovh-ux/manager-react-components';
import { OdsButton, OdsText } from '@ovhcloud/ods-components/react';
import {
ODS_BUTTON_VARIANT,
ODS_ICON_NAME,
ODS_TEXT_PRESET,
} from '@ovhcloud/ods-components';
import { Breadcrumb } from '@/components/Breadcrumb/Breadcrumb';
import { urls } from '@/routes/routes.constants';
import TabsPanel from '@/components/layout-helpers/Dashboard/TabsPanel';
import { getOfficeParentTenant, UseGenerateUrl } from '@/hooks';
import { ParentTenantType } from '@/api/parentTenant/type';

export type DashboardTabItemProps = {
name: string;
Expand All @@ -21,7 +33,18 @@ export type DashboardLayoutProps = {
export default function DashboardPage() {
const { serviceName } = useParams();
const { t } = useTranslation('dashboard');
const navigate = useNavigate();

const basePath = useResolvedPath('').pathname;
const { data } = getOfficeParentTenant() as {
data?: ParentTenantType;
};

const hrefEditName = UseGenerateUrl('./edit-name', 'path');

const handleEditNamelick = () => {
navigate(hrefEditName);
};

function computePathMatchers(routes: string[]) {
return routes.map(
Expand All @@ -31,8 +54,8 @@ export default function DashboardPage() {

const tabsList: DashboardTabItemProps[] = [
{
name: 'licence',
title: t('microsoft_office_dashboard_licences'),
name: 'license',
title: t('microsoft_office_dashboard_licenses'),
to: basePath,
pathMatchers: computePathMatchers([urls.license]),
},
Expand All @@ -45,7 +68,26 @@ export default function DashboardPage() {
];

const header = {
title: serviceName,
title: (
<>
<OdsText preset={ODS_TEXT_PRESET.heading6}>
{t('microsoft_office_dashboard_licenses_group')}
</OdsText>
<div className="flex items-center justify-between">
<div>{data?.displayName}</div>
<OdsButton
label=""
icon={ODS_ICON_NAME.pen}
variant={ODS_BUTTON_VARIANT.ghost}
onClick={handleEditNamelick}
className="ml-4"
/>
</div>
<OdsText preset={ODS_TEXT_PRESET.paragraph}>
{data?.serviceName}
</OdsText>
</>
),
};

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import { LicenseType } from '@/api/license/type';

interface ActionButtonUsersProps {
usersItem: UserNativeType;
licenceDetail: LicenseType;
licenseDetail: LicenseType;
}
const ActionButtonUsers: React.FC<ActionButtonUsersProps> = ({
usersItem,
licenceDetail,
licenseDetail,
}) => {
const { t } = useTranslation('dashboard/users');

Expand All @@ -39,7 +39,7 @@ const ActionButtonUsers: React.FC<ActionButtonUsersProps> = ({
id: 1,
onclick: handlePasswordChangeClick,
label: t('dashboard_users_action_user_change_password'),
urn: licenceDetail.iam.urn,
urn: licenseDetail.iam.urn,
iamActions: [IAM_ACTIONS.user.edit],
},
]
Expand All @@ -48,7 +48,7 @@ const ActionButtonUsers: React.FC<ActionButtonUsersProps> = ({
id: 2,
onclick: handleEditUserClick,
label: t('dashboard_users_action_user_edit'),
urn: licenceDetail.iam.urn,
urn: licenseDetail.iam.urn,
iamActions: [IAM_ACTIONS.user.edit],
},
...(!usersItem.isVirtual
Expand All @@ -57,7 +57,7 @@ const ActionButtonUsers: React.FC<ActionButtonUsersProps> = ({
id: 3,
onclick: handleDeleteUserClick,
label: t('dashboard_users_action_user_delete'),
urn: licenceDetail.iam.urn,
urn: licenseDetail.iam.urn,
iamActions: [IAM_ACTIONS.user.delete],
color: ODS_BUTTON_COLOR.critical,
},
Expand Down
Loading

0 comments on commit 71f7a39

Please sign in to comment.