Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(web-office): add update displayName for title on dashboard #14541

Open
wants to merge 1 commit into
base: feat/office365-react-app
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './api';
export * from './key';
export * from './type';
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) => {
stif59100 marked this conversation as resolved.
Show resolved Hide resolved
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);
});
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,69 @@
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,
updateParentTenant,
getOfficeParentTenantQueryKey,
} from '@/api/parentTenant';
import {
updateOfficeLicenseDetails,
LicenseType,
getOfficeLicenseDetailsQueryKey,
} from '@/api/license';

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