Skip to content

Commit

Permalink
feat(vcd): add reset password setup
Browse files Browse the repository at this point in the history
ref: MANAGER-15191

Signed-off-by: Paul Dickerson <[email protected]>
  • Loading branch information
Paul Dickerson authored and Nicolas Pierre-charles committed Nov 22, 2024
1 parent 7ccd653 commit c9086f4
Show file tree
Hide file tree
Showing 23 changed files with 443 additions and 117 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './iam/iam.handler';
export * from './vcd-organization/vcd-organization.handler';
export * from './vcd-organization/vcd-datacentre.handler';
export * from './vcd-organization/vcd-datacentre-order.handler';
export * from './veeam-backup/veeam-backup.handler';
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { PathParams } from 'msw';
import { Handler } from '../../../../../../playwright-helpers';
import { datacentreList } from './vcd-datacentre.mock';
import { computeList } from './vdc-compute.mock';
import { storageList } from './vdc-storage.mock';

export type GetDatacentresMocksParams = {
isDatacentresKo?: boolean;
isDatacentreUpdateKo?: boolean;
nbDatacentres?: number;
isComputeKO?: boolean;
nbCompute?: number;
isStorageKO?: boolean;
nbStorage?: number;
};

const findDatacentreById = (params: PathParams) =>
datacentreList.find(({ id }) => id === params.id);

export const getDatacentresMocks = ({
isDatacentresKo,
isDatacentreUpdateKo,
nbDatacentres = Number.POSITIVE_INFINITY,
isComputeKO,
nbCompute = Number.POSITIVE_INFINITY,
isStorageKO,
nbStorage = Number.POSITIVE_INFINITY,
}: GetDatacentresMocksParams): Handler[] => [
{
url: '/vmwareCloudDirector/organization/:id/virtualDataCenter/:id/storage',
response: isStorageKO
? { message: 'Storage error' }
: storageList.slice(0, nbStorage),
api: 'v2',
status: isStorageKO ? 500 : 200,
},
{
url: '/vmwareCloudDirector/organization/:id/virtualDataCenter/:id/compute',
response: isComputeKO
? { message: 'Compute error' }
: computeList.slice(0, nbCompute),
api: 'v2',
status: isComputeKO ? 500 : 200,
},
{
url: '/vmwareCloudDirector/organization/:id/virtualDataCenter',
response: isDatacentresKo
? { message: 'Datacentres error' }
: datacentreList.slice(0, nbDatacentres),
api: 'v2',
status: isDatacentresKo ? 500 : 200,
},
{
url: '/vmwareCloudDirector/organization/:id/virtualDataCenter/:id',
response: (_: unknown, params: PathParams) =>
isDatacentresKo
? { message: 'Datacentre error' }
: findDatacentreById(params),
api: 'v2',
status: isDatacentresKo ? 500 : 200,
},
{
url: '/vmwareCloudDirector/organization/:id/virtualDataCenter/:id',
response: isDatacentreUpdateKo
? { message: 'Datacentre update error' }
: {},
method: 'put',
api: 'v2',
status: isDatacentreUpdateKo ? 500 : 200,
},
];
Original file line number Diff line number Diff line change
@@ -1,89 +1,27 @@
import { PathParams } from 'msw';
import { Handler } from '../../../../../../playwright-helpers';
import { organizationList } from './vcd-organization.mock';
import { datacentreList } from './vcd-datacentre.mock';
import { computeList } from './vdc-compute.mock';
import { storageList } from './vdc-storage.mock';

export type GetOrganizationMocksParams = {
isOrganizationKo?: boolean;
isOrganizationUpdateKo?: boolean;
isOrganizationResetPasswordKo?: boolean;
nbOrganization?: number;
allOrgsBackedUp?: boolean;
isDatacentresKo?: boolean;
isDatacentreUpdateKo?: boolean;
nbDatacentres?: number;
isComputeKO?: boolean;
nbCompute?: number;
isStorageKO?: boolean;
nbStorage?: number;
};

const findOrganizationById = (params: PathParams) =>
organizationList.find(({ id }) => id === params.id);

const findDatacentreById = (params: PathParams) =>
datacentreList.find(({ id }) => id === params.id);

export const getOrganizationMocks = ({
isOrganizationKo,
isOrganizationUpdateKo,
isOrganizationResetPasswordKo,
nbOrganization = Number.POSITIVE_INFINITY,
allOrgsBackedUp,
isDatacentresKo,
isDatacentreUpdateKo,
nbDatacentres = Number.POSITIVE_INFINITY,
isComputeKO,
nbCompute = Number.POSITIVE_INFINITY,
isStorageKO,
nbStorage = Number.POSITIVE_INFINITY,
}: GetOrganizationMocksParams): Handler[] => {
const nb = allOrgsBackedUp ? 1 : nbOrganization;
return [
{
url:
'/vmwareCloudDirector/organization/:id/virtualDataCenter/:id/storage',
response: isStorageKO
? { message: 'Storage error' }
: storageList.slice(0, nbStorage),
api: 'v2',
status: isStorageKO ? 500 : 200,
},
{
url:
'/vmwareCloudDirector/organization/:id/virtualDataCenter/:id/compute',
response: isComputeKO
? { message: 'Compute error' }
: computeList.slice(0, nbCompute),
api: 'v2',
status: isComputeKO ? 500 : 200,
},
{
url: '/vmwareCloudDirector/organization/:id/virtualDataCenter',
response: isDatacentresKo
? { message: 'Datacentres error' }
: datacentreList.slice(0, nbDatacentres),
api: 'v2',
status: isDatacentresKo ? 500 : 200,
},
{
url: '/vmwareCloudDirector/organization/:id/virtualDataCenter/:id',
response: (_: unknown, params: PathParams) =>
isDatacentresKo
? { message: 'Datacentre error' }
: findDatacentreById(params),
api: 'v2',
status: isDatacentresKo ? 500 : 200,
},
{
url: '/vmwareCloudDirector/organization/:id/virtualDataCenter/:id',
response: isDatacentreUpdateKo
? { message: 'Datacentre update error' }
: {},
method: 'put',
api: 'v2',
status: isDatacentreUpdateKo ? 500 : 200,
},
{
url: '/vmwareCloudDirector/organization/:id',
response: isOrganizationUpdateKo
Expand All @@ -93,6 +31,15 @@ export const getOrganizationMocks = ({
api: 'v2',
status: isOrganizationUpdateKo ? 500 : 200,
},
{
url: '/vmwareCloudDirector/organization/:id/password',
response: isOrganizationResetPasswordKo
? { message: 'Organization reset password error' }
: {},
method: 'post',
api: 'v2',
status: isOrganizationResetPasswordKo ? 500 : 200,
},
{
url: '/vmwareCloudDirector/organization/:id',
response: (_: unknown, params: PathParams) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
"managed_vcd_dashboard_service_cancellation": "Résilier le service",
"managed_vcd_dashboard_password": "Mot de passe",
"managed_vcd_dashboard_password_renew": "Renouveler le mot de passe admin",
"managed_vcd_dashboard_password_tooltip": "Si vous souhaitez changer votre mot de passe administrateur, merci de contacter le support",
"managed_vcd_dashboard_password_modal_title": "Changer le mot de passe",
"managed_vcd_dashboard_password_modal_subtitle": "Êtes-vous certain de changer de mot de passe ?",
"managed_vcd_dashboard_password_renew_success": "Vous allez recevoir un email pour visualiser votre mot de passe",
"managed_vcd_dashboard_password_renew_error": "Une erreur est survenue. Veuillez réessayer plus tard ou contacter le support pour changer votre mot de passe administrateur",
"managed_vcd_dashboard_back_link": "Retour à la liste",
"managed_vcd_dashboard_coming_soon": "Bientôt disponible",
"managed_vcd_dashboard_data_protection": "Protection de Données",
Expand All @@ -38,6 +41,7 @@
"managed_vcd_dashboard_edit_modal_error": "Une erreur est survenue: {{error}}.",
"managed_vcd_dashboard_edit_modal_cta_cancel": "Annuler",
"managed_vcd_dashboard_edit_modal_cta_edit": "Modifier",
"managed_vcd_dashboard_edit_modal_cta_validate": "Valider",
"managed_vcd_dashboard_edit_name_modal_title": "Modifier le nom",
"managed_vcd_dashboard_edit_name_modal_label": "Nom",
"managed_vcd_dashboard_edit_name_modal_success": "Le nom a été modifié avec succès.",
Expand Down
5 changes: 4 additions & 1 deletion packages/manager/apps/hpc-vmware-managed-vcd/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { odsSetup } from '@ovhcloud/ods-common-core';
import { RouterProvider, createHashRouter } from 'react-router-dom';
import { Routes } from './routes/routes';
import { MessageContextProvider } from './context/Message.context';

odsSetup();

Expand All @@ -20,7 +21,9 @@ function App() {

return (
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
<MessageContextProvider>
<RouterProvider router={router} />
</MessageContextProvider>
<ReactQueryDevtools />
</QueryClientProvider>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import React, { useEffect, useState } from 'react';
import {
HeadersProps,
BaseLayout,
Notifications,
} from '@ovh-ux/manager-react-components';
import { HeadersProps, BaseLayout } from '@ovh-ux/manager-react-components';
import {
OsdsTabBar,
OsdsTabBarItem,
Expand All @@ -12,6 +8,7 @@ import {
import { NavLink, Outlet, useLocation, useNavigate } from 'react-router-dom';
import Breadcrumb from '@/components/breadcrumb/Breadcrumb.component';
import { BreadcrumbItem } from '@/hooks/breadcrumb/useBreadcrumb';
import { MessageList } from '@/components/message/MessageList.component';

export type DashboardTabItemProps = {
name: string;
Expand Down Expand Up @@ -74,7 +71,7 @@ export default function VcdDashboardLayout({
</OsdsTabs>
}
breadcrumb={<Breadcrumb items={breadcrumbItems} />}
message={<Notifications />}
message={<MessageList />}
backLinkLabel={backLinkLabel}
onClickReturn={onClickReturn}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React, { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { OsdsMessage, OsdsText } from '@ovhcloud/ods-components/react';
import { ODS_THEME_TYPOGRAPHY_SIZE } from '@ovhcloud/ods-common-theming';
import { NotificationType } from '@ovh-ux/manager-react-components';
import {
ODS_MESSAGE_TYPE,
ODS_TEXT_COLOR_INTENT,
} from '@ovhcloud/ods-components';
import { MessageType, useMessageContext } from '@/context/Message.context';

type MessageProps = {
message: MessageType;
};

const messageColors = {
[NotificationType.Success]: ODS_MESSAGE_TYPE.success,
[NotificationType.Error]: ODS_MESSAGE_TYPE.error,
[NotificationType.Warning]: ODS_MESSAGE_TYPE.warning,
[NotificationType.Info]: ODS_MESSAGE_TYPE.info,
};
const textColors = {
[NotificationType.Success]: ODS_TEXT_COLOR_INTENT.success,
[NotificationType.Error]: ODS_TEXT_COLOR_INTENT.error,
[NotificationType.Warning]: ODS_TEXT_COLOR_INTENT.warning,
[NotificationType.Info]: ODS_TEXT_COLOR_INTENT.info,
};

const getMessageColor = (type: NotificationType) =>
messageColors[type] || ODS_MESSAGE_TYPE.info;

const getTextColor = (type: NotificationType) =>
textColors[type] || ODS_TEXT_COLOR_INTENT.info;

export const Message: React.FC<MessageProps> = ({ message }) => {
const { pathname } = useLocation();
const { clearMessage } = useMessageContext();
const {
content,
uid,
type,
persistent,
includedSubRoutes,
excludedSubRoutes,
duration,
} = message;

useEffect(() => {
if (
!includedSubRoutes.every((route) => pathname.includes(route)) ||
excludedSubRoutes.some((route) => pathname.includes(route))
) {
clearMessage(uid);
}
}, [uid, includedSubRoutes, excludedSubRoutes, pathname]);

useEffect(() => {
if (!duration) return;
const durationTimeout = setTimeout(() => clearMessage(uid), duration);

// eslint-disable-next-line consistent-return
return () => clearTimeout(durationTimeout);
}, [duration]);

return (
<OsdsMessage
className="mb-2"
type={getMessageColor(type)}
{...(persistent
? {}
: {
removable: true,
onOdsRemoveClick: () => clearMessage(uid),
})}
>
<OsdsText
color={getTextColor(type)}
size={ODS_THEME_TYPOGRAPHY_SIZE._400}
>
{content}
</OsdsText>
</OsdsMessage>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import { useMessageContext } from '@/context/Message.context';
import { Message } from './Message.component';

export const MessageList: React.FC = () => {
const { messages } = useMessageContext();

return (
<>
{messages.map((message) => (
<Message key={message.uid} message={message} />
))}
</>
);
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { useNotifications } from '@ovh-ux/manager-react-components';
import useManagedVcdOrganization from '@/data/hooks/useManagedVcdOrganization';
import { useUpdateVcdOrganizationDetails } from '@/data/hooks/useUpdateVcdOrganization';
import { IVcdOrganizationState } from '@/types/vcd-organization.interface';
Expand All @@ -10,6 +9,8 @@ import {
validateOrganizationName,
} from '@/utils/formValidation';
import { EditDetailModal } from './EditDetailModal';
import { useMessageContext } from '@/context/Message.context';
import { subRoutes } from '@/routes/routes.constant';

type OrganizationDetailName = 'name' | 'description';
type TValidationFunctions = {
Expand All @@ -27,16 +28,17 @@ export const UpdateDetailModalHandler = ({
const { t } = useTranslation('dashboard');
const navigate = useNavigate();
const closeModal = () => navigate('..');
const { addSuccess } = useNotifications();
const { addSuccess } = useMessageContext();
const { id } = useParams();
const { data: vcdOrganization } = useManagedVcdOrganization({ id });
const { updateDetails, error, isError } = useUpdateVcdOrganizationDetails({
id,
onSuccess: () => {
addSuccess(
t(`managed_vcd_dashboard_edit_${detailName}_modal_success`),
true,
);
addSuccess({
content: t(`managed_vcd_dashboard_edit_${detailName}_modal_success`),
includedSubRoutes: [id],
excludedSubRoutes: [subRoutes.datacentres],
});
closeModal();
},
});
Expand Down
Loading

0 comments on commit c9086f4

Please sign in to comment.