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 18, 2024
1 parent 4142242 commit 9b1156f
Show file tree
Hide file tree
Showing 26 changed files with 343 additions and 45 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
1 change: 1 addition & 0 deletions packages/manager/apps/web-office/src/api/_mock_/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './license';
export * from './user';
export * from './parentTenant';
16 changes: 16 additions & 0 deletions packages/manager/apps/web-office/src/api/_mock_/parentTenant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { UserStateEnum } from '../api.type';
import { ParentTenantType } from '../parentTenant';

export const parentTenantMock: ParentTenantType = {
address: '123 Main Street',
city: 'Springfield',
creationDate: '2023-05-15',
displayName: 'John Doe',
firstName: 'John',
lastName: 'Doe',
phone: '+1234567890',
serviceName: 'office5678.o365.ovh.com-1234',
serviceType: 'prepaid',
status: UserStateEnum.OK,
zipCode: '12345',
};
14 changes: 14 additions & 0 deletions packages/manager/apps/web-office/src/api/license/api.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { aapi, v6 } from '@ovh-ux/manager-core-api';
import { getApiPath, getApiPathWithoutServiceName } from '../utils/apiPath';
import { LicenseType } from './type';

// GET

Expand All @@ -12,6 +13,12 @@ export const getOfficeGlobalLicenses = async () => {
});
return data;
};
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 @@ -40,5 +47,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
29 changes: 29 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,29 @@
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`,
);
console.log('parentTenant', data);
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './api';
export * from './key';
export * from './type';
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { describe, expect } from 'vitest';
import { render } from '@/utils/test.provider';
import Breadcrumb from '../Breadcrumb';

describe('Breadcrumb component', () => {
it('should render', async () => {
const { getByTestId } = render(<Breadcrumb />);
const cmp = getByTestId('breadcrumb');
expect(cmp).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import React from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { ShellContext } from '@ovh-ux/manager-react-shell-client';
import {
ErrorBanner,
ErrorMessage,
TRACKING_LABELS,
} from '@ovh-ux/manager-react-components/src/components/';
import { ErrorBanner } from '@ovh-ux/manager-react-components';
} from '@ovh-ux/manager-react-components';

interface ErrorObject {
[key: string]: any;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { vi, describe, expect } from 'vitest';
import '@testing-library/jest-dom';
import { renderHook, waitFor } from '@testing-library/react';
import { parentTenantMock, licensesMock } from '@/api/_mock_';
import { useOfficeParentTenant } from '@/hooks';
import { wrapper } from '@/utils/test.provider';

const useParamsMock = vi.hoisted(() => ({
useParams: vi.fn(),
}));

vi.mock('react-router-dom', async (importActual) => {
const actual = await importActual<typeof import('react-router-dom')>();
return {
...actual,
useParams: useParamsMock.useParams,
};
});

describe('useOfficeParentTenant', () => {
it('should return the detail of one parentTenant', async () => {
useParamsMock.useParams.mockReturnValue({
serviceName: parentTenantMock.serviceName,
});
const { result } = renderHook(() => useOfficeParentTenant(), {
wrapper,
});
await waitFor(() => {
expect(result.current.isSuccess).toBe(true);

Check failure on line 29 in packages/manager/apps/web-office/src/hooks/__test__/useOfficeParentTenant.spec.tsx

View workflow job for this annotation

GitHub Actions / test

src/hooks/__test__/useOfficeParentTenant.spec.tsx > useOfficeParentTenant > should return the detail of one parentTenant

AssertionError: expected false to be true // Object.is equality Ignored nodes: comments, script, style <html> <head /> <body> <div /> </body> </html> - Expected + Received - true + false ❯ src/hooks/__test__/useOfficeParentTenant.spec.tsx:29:40 ❯ runWithExpensiveErrorDiagnosticsDisabled ../../../../node_modules/@testing-library/dom/dist/@testing-library/dom.esm.js:342:12 ❯ checkCallback ../../../../node_modules/@testing-library/dom/dist/@testing-library/dom.esm.js:1090:24 ❯ Timeout.checkRealTimersCallback ../../../../node_modules/@testing-library/dom/dist/@testing-library/dom.esm.js:1084:16
});
expect(result.current.data).toEqual(parentTenantMock);
});
});
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 './useOfficeParentTenant';
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
@@ -0,0 +1,28 @@
import { useQuery } from '@tanstack/react-query';
import { useParams } from 'react-router-dom';
import { useOfficeServiceType } from './useOfficeServiceType';
import {
getParentTenant,
getOfficeParentTenantQueryKey,
} from '@/api/parentTenant';
import {
getlicenseOfficeServiceQueryKey,
getOfficeLicenseDetails,
} from '@/api/license';

export const useOfficeParentTenant = () => {
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),
});
};
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 {
useOfficeParentTenant,
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 { useOfficeParentTenantQueryKey } 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 } = useOfficeParentTenant();

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
? useOfficeParentTenantQueryKey(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}
/>
);
}
Loading

0 comments on commit 9b1156f

Please sign in to comment.