diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/mocks/index.ts b/packages/manager/apps/hpc-vmware-managed-vcd/mocks/index.ts
index 3d40b59a8819..495b7f1ffc5c 100644
--- a/packages/manager/apps/hpc-vmware-managed-vcd/mocks/index.ts
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/mocks/index.ts
@@ -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';
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/mocks/vcd-organization/vcd-datacentre.handler.ts b/packages/manager/apps/hpc-vmware-managed-vcd/mocks/vcd-organization/vcd-datacentre.handler.ts
new file mode 100644
index 000000000000..27e4e84f4f3d
--- /dev/null
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/mocks/vcd-organization/vcd-datacentre.handler.ts
@@ -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,
+ },
+];
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/mocks/vcd-organization/vcd-organization.handler.ts b/packages/manager/apps/hpc-vmware-managed-vcd/mocks/vcd-organization/vcd-organization.handler.ts
index 68da1e813be3..3009416f69ee 100644
--- a/packages/manager/apps/hpc-vmware-managed-vcd/mocks/vcd-organization/vcd-organization.handler.ts
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/mocks/vcd-organization/vcd-organization.handler.ts
@@ -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
@@ -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) =>
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/public/translations/dashboard/Messages_fr_FR.json b/packages/manager/apps/hpc-vmware-managed-vcd/public/translations/dashboard/Messages_fr_FR.json
index c1654ead13d2..9ab63c50698d 100644
--- a/packages/manager/apps/hpc-vmware-managed-vcd/public/translations/dashboard/Messages_fr_FR.json
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/public/translations/dashboard/Messages_fr_FR.json
@@ -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",
@@ -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.",
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/App.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/App.tsx
index 2c333cefe6d7..ec72c8de080e 100644
--- a/packages/manager/apps/hpc-vmware-managed-vcd/src/App.tsx
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/App.tsx
@@ -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();
@@ -20,7 +21,9 @@ function App() {
return (
-
+
+
+
);
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/components/dashboard/layout/VcdDashboardLayout.component.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/components/dashboard/layout/VcdDashboardLayout.component.tsx
index 6aabda0848d0..d694a86df261 100644
--- a/packages/manager/apps/hpc-vmware-managed-vcd/src/components/dashboard/layout/VcdDashboardLayout.component.tsx
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/components/dashboard/layout/VcdDashboardLayout.component.tsx
@@ -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,
@@ -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;
@@ -74,7 +71,7 @@ export default function VcdDashboardLayout({
}
breadcrumb={}
- message={}
+ message={}
backLinkLabel={backLinkLabel}
onClickReturn={onClickReturn}
/>
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/components/message/Message.component.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/components/message/Message.component.tsx
new file mode 100644
index 000000000000..9430a74e2399
--- /dev/null
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/components/message/Message.component.tsx
@@ -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 = ({ 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 (
+ clearMessage(uid),
+ })}
+ >
+
+ {content}
+
+
+ );
+};
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/components/message/MessageList.component.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/components/message/MessageList.component.tsx
new file mode 100644
index 000000000000..369fe886f023
--- /dev/null
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/components/message/MessageList.component.tsx
@@ -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) => (
+
+ ))}
+ >
+ );
+};
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/components/modal/UpdateDetailModalHandler.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/components/modal/UpdateDetailModalHandler.tsx
index e5092bce2b54..de8a6f62f73e 100644
--- a/packages/manager/apps/hpc-vmware-managed-vcd/src/components/modal/UpdateDetailModalHandler.tsx
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/components/modal/UpdateDetailModalHandler.tsx
@@ -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';
@@ -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 = {
@@ -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();
},
});
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/components/tiles/organization-service-tile/OrganizationServiceManagementTile.spec.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/components/tiles/organization-service-tile/OrganizationServiceManagementTile.spec.tsx
index b9fbbdd16567..33468b19f3c7 100644
--- a/packages/manager/apps/hpc-vmware-managed-vcd/src/components/tiles/organization-service-tile/OrganizationServiceManagementTile.spec.tsx
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/components/tiles/organization-service-tile/OrganizationServiceManagementTile.spec.tsx
@@ -12,6 +12,11 @@ import {
} from '@ovh-ux/manager-react-shell-client';
import OrganizationServiceManagementTile from './OrganizationServiceManagementTile.component';
+vi.mock('react-router-dom', () => ({
+ useNavigate: () => ({ navigate: vi.fn() }),
+ useParams: () => ({ id: 'id' }),
+}));
+
const shellContext = {
environment: {
getUser: vi.fn(),
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/context/Message.context.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/context/Message.context.tsx
new file mode 100644
index 000000000000..f1aecf0cefda
--- /dev/null
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/context/Message.context.tsx
@@ -0,0 +1,95 @@
+import { NotificationType } from '@ovh-ux/manager-react-components/src/components/notifications/useNotifications';
+import React, {
+ createContext,
+ FC,
+ PropsWithChildren,
+ ReactNode,
+ useContext,
+ useMemo,
+ useState,
+} from 'react';
+
+export type MessageType = {
+ uid: number;
+ content: ReactNode;
+ type: NotificationType;
+ persistent?: boolean;
+ includedSubRoutes?: string[];
+ excludedSubRoutes?: string[];
+ duration?: number;
+};
+
+type AddMessageProps = Omit;
+type AddSpecificMessageProps = Omit;
+
+export type MessageContextType = {
+ messages: MessageType[];
+ addSuccess: (props: AddSpecificMessageProps) => void;
+ addError: (props: AddSpecificMessageProps) => void;
+ addWarning: (props: AddSpecificMessageProps) => void;
+ addInfo: (props: AddSpecificMessageProps) => void;
+ clearMessage: (uid: number) => void;
+ clearMessages: () => void;
+};
+
+const MessageContext = createContext({
+ messages: [],
+ addSuccess: () => null,
+ addError: () => null,
+ addWarning: () => null,
+ addInfo: () => null,
+ clearMessage: () => null,
+ clearMessages: () => null,
+});
+
+export const MessageContextProvider: FC = ({ children }) => {
+ const [messages, setMessages] = useState([]);
+
+ const addMessage = (props: AddMessageProps) => {
+ setMessages((prevList) => [
+ ...prevList,
+ {
+ uid: Date.now(),
+ includedSubRoutes: props.includedSubRoutes || [],
+ excludedSubRoutes: props.excludedSubRoutes || [],
+ ...props,
+ },
+ ]);
+ };
+ const deleteMessage = (id: number) => {
+ setMessages((prevList) => prevList.filter((msg) => msg.uid !== id));
+ };
+
+ const messageContextValue: MessageContextType = useMemo(
+ () => ({
+ messages,
+ addSuccess: (props: AddSpecificMessageProps) =>
+ addMessage({ type: NotificationType.Success, ...props }),
+ addError: (props: AddSpecificMessageProps) =>
+ addMessage({ type: NotificationType.Error, ...props }),
+ addInfo: (props: AddSpecificMessageProps) =>
+ addMessage({ type: NotificationType.Info, ...props }),
+ addWarning: (props: AddSpecificMessageProps) =>
+ addMessage({ type: NotificationType.Warning, ...props }),
+ clearMessage: (id) => deleteMessage(id),
+ clearMessages: () => setMessages([]),
+ }),
+ [messages],
+ );
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const useMessageContext = (): MessageContextType => {
+ const context = useContext(MessageContext);
+ if (context === undefined) {
+ throw new Error(
+ 'useMessageContext must be used within a MessageContextProvider',
+ );
+ }
+ return context;
+};
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/data/api/hpc-vmware-managed-vcd-reset-password.ts b/packages/manager/apps/hpc-vmware-managed-vcd/src/data/api/hpc-vmware-managed-vcd-reset-password.ts
new file mode 100644
index 000000000000..724ad903b770
--- /dev/null
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/data/api/hpc-vmware-managed-vcd-reset-password.ts
@@ -0,0 +1,10 @@
+import { apiClient, ApiResponse } from '@ovh-ux/manager-core-api';
+import { VCD_ORGANIZATION_ROUTE } from './hpc-vmware-managed-vcd.constants';
+
+const getResetPasswordRoute = (id: string) =>
+ `${VCD_ORGANIZATION_ROUTE}/${id}/password`;
+
+export const resetOrganizationPassword = (
+ id: string,
+): Promise> =>
+ apiClient.v2.post(getResetPasswordRoute(id));
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/data/hooks/useResetPassword.ts b/packages/manager/apps/hpc-vmware-managed-vcd/src/data/hooks/useResetPassword.ts
new file mode 100644
index 000000000000..db118380b031
--- /dev/null
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/data/hooks/useResetPassword.ts
@@ -0,0 +1,16 @@
+import { useMutation, UseMutationOptions } from '@tanstack/react-query';
+import { ApiError, ApiResponse } from '@ovh-ux/manager-core-api';
+import { resetOrganizationPassword } from '../api/hpc-vmware-managed-vcd-reset-password';
+import { getVcdOrganizationResetPasswordQueryKey } from '@/utils/queryKeys';
+
+export const useResetPassword = (
+ { id }: { id: string },
+ options?: Partial<
+ UseMutationOptions, ApiError, void, unknown>
+ >,
+) =>
+ useMutation({
+ mutationKey: getVcdOrganizationResetPasswordQueryKey(id),
+ mutationFn: () => resetOrganizationPassword(id),
+ ...options,
+ });
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/dashboard/datacentre/general-informations/edit/EditVdcDescription.page.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/dashboard/datacentre/general-informations/edit/EditVdcDescription.page.tsx
index f1a618d9c607..7bc9b462e3a9 100644
--- a/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/dashboard/datacentre/general-informations/edit/EditVdcDescription.page.tsx
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/dashboard/datacentre/general-informations/edit/EditVdcDescription.page.tsx
@@ -1,28 +1,30 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate, useParams } from 'react-router-dom';
-import { useNotifications } from '@ovh-ux/manager-react-components';
import { useManagedVcdDatacentre } from '@/data/hooks/useManagedVcdDatacentres';
import { useUpdateVdcDetails } from '@/data/hooks/useUpdateVcdDatacentre';
import { validateDescription } from '@/utils/formValidation';
import { IVcdDatacentreState } from '@/types/vcd-datacenter.interface';
import { EditDetailModal } from '@/components/modal/EditDetailModal';
+import { useMessageContext } from '@/context/Message.context';
+import { subRoutes } from '@/routes/routes.constant';
export default function EditVdcDescription() {
const { t } = useTranslation('dashboard');
const navigate = useNavigate();
const closeModal = () => navigate('..');
- const { addSuccess } = useNotifications();
+ const { addSuccess } = useMessageContext();
const { id, vdcId } = useParams();
const { data: vcdDatacentre } = useManagedVcdDatacentre(id, vdcId);
const { updateDetails, error, isError } = useUpdateVdcDetails({
id,
vdcId,
onSuccess: () => {
- addSuccess(
- t('managed_vcd_dashboard_edit_description_modal_success'),
- true,
- );
+ addSuccess({
+ content: t('managed_vcd_dashboard_edit_description_modal_success'),
+ includedSubRoutes: [id],
+ excludedSubRoutes: [subRoutes.datacentres],
+ });
closeModal();
},
});
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/dashboard/organization/general-information/OrganizationGeneralInformation.spec.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/dashboard/organization/general-information/OrganizationGeneralInformation.spec.tsx
index 15c81490486e..c5314a0d14e8 100644
--- a/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/dashboard/organization/general-information/OrganizationGeneralInformation.spec.tsx
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/dashboard/organization/general-information/OrganizationGeneralInformation.spec.tsx
@@ -7,6 +7,7 @@ import {
mockSubmitNewValue,
checkModalError,
DEFAULT_TIMEOUT,
+ checkTextVisibility,
} from '../../../../test-utils';
import { organizationList } from '../../../../../mocks/vcd-organization/vcd-organization.mock';
@@ -19,21 +20,15 @@ describe('Organization General Information Page', () => {
initialRoute: `/${organizationList[1].id}`,
});
- await waitFor(
- () =>
- expect(
- screen.getByText(
- labels.dashboard.managed_vcd_dashboard_data_protection,
- ),
- ).toBeVisible(),
- { timeout: DEFAULT_TIMEOUT },
+ await checkTextVisibility(
+ labels.dashboard.managed_vcd_dashboard_data_protection,
);
let editButton;
await waitFor(
() => {
editButton = screen.getAllByTestId('editIcon').at(0);
- return expect(editButton).not.toHaveAttribute('disabled');
+ return expect(editButton).toBeEnabled();
},
{ timeout: DEFAULT_TIMEOUT },
);
@@ -44,12 +39,9 @@ describe('Organization General Information Page', () => {
await mockSubmitNewValue({ submitButtonLabel });
await checkModalVisibility({ container, isVisible: false });
-
- expect(
- screen.queryByText(
- labels.dashboard.managed_vcd_dashboard_edit_name_modal_success,
- ),
- ).toBeVisible();
+ await checkTextVisibility(
+ labels.dashboard.managed_vcd_dashboard_edit_name_modal_success,
+ );
});
it('trying to update name displays an error if update organization service is KO', async () => {
@@ -71,21 +63,15 @@ describe('Organization General Information Page', () => {
initialRoute: `/${organizationList[1].id}`,
});
- await waitFor(
- () =>
- expect(
- screen.getByText(
- labels.dashboard.managed_vcd_dashboard_data_protection,
- ),
- ).toBeVisible(),
- { timeout: DEFAULT_TIMEOUT },
+ await checkTextVisibility(
+ labels.dashboard.managed_vcd_dashboard_data_protection,
);
let editButton;
await waitFor(
() => {
editButton = screen.getAllByTestId('editIcon').at(1);
- return expect(editButton).not.toHaveAttribute('disabled');
+ return expect(editButton).toBeEnabled();
},
{ timeout: DEFAULT_TIMEOUT },
);
@@ -96,12 +82,9 @@ describe('Organization General Information Page', () => {
await mockSubmitNewValue({ submitButtonLabel });
await checkModalVisibility({ container, isVisible: false });
-
- expect(
- screen.queryByText(
- labels.dashboard.managed_vcd_dashboard_edit_description_modal_success,
- ),
- ).toBeVisible();
+ await checkTextVisibility(
+ labels.dashboard.managed_vcd_dashboard_edit_description_modal_success,
+ );
});
it('trying to update description displays an error if update organization service is KO', async () => {
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/dashboard/organization/general-information/edit/EditPassword.page.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/dashboard/organization/general-information/edit/EditPassword.page.tsx
new file mode 100644
index 000000000000..5426f12aa3b4
--- /dev/null
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/dashboard/organization/general-information/edit/EditPassword.page.tsx
@@ -0,0 +1,65 @@
+import React from 'react';
+import { useNavigate, useParams } from 'react-router-dom';
+import { useTranslation } from 'react-i18next';
+import { OsdsModal, OsdsButton } from '@ovhcloud/ods-components/react';
+import { Description } from '@ovh-ux/manager-react-components';
+import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming';
+import { ODS_BUTTON_VARIANT } from '@ovhcloud/ods-components';
+import { useResetPassword } from '@/data/hooks/useResetPassword';
+import { useMessageContext } from '@/context/Message.context';
+import { subRoutes } from '@/routes/routes.constant';
+
+export default function EditPassword() {
+ const { t } = useTranslation('dashboard');
+ const navigate = useNavigate();
+ const closeModal = () => navigate('..');
+ const { id } = useParams();
+ const { addSuccess, addError } = useMessageContext();
+ const { mutate: resetPassword } = useResetPassword(
+ { id },
+ {
+ onSettled: () => closeModal(),
+ onSuccess: () =>
+ addSuccess({
+ content: t('managed_vcd_dashboard_password_renew_success'),
+ includedSubRoutes: [id],
+ excludedSubRoutes: [subRoutes.datacentres],
+ }),
+ onError: () =>
+ addError({
+ content: t('managed_vcd_dashboard_password_renew_error'),
+ includedSubRoutes: [id],
+ excludedSubRoutes: [subRoutes.datacentres],
+ }),
+ },
+ );
+
+ return (
+
+
+ {t('managed_vcd_dashboard_password_modal_subtitle')}
+
+
+ {t('managed_vcd_dashboard_edit_modal_cta_cancel')}
+
+ resetPassword()}
+ >
+ {t('managed_vcd_dashboard_edit_modal_cta_validate')}
+
+
+ );
+}
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/routes/routes.constant.ts b/packages/manager/apps/hpc-vmware-managed-vcd/src/routes/routes.constant.ts
index 1eb746e97450..6a72bceb5a1e 100644
--- a/packages/manager/apps/hpc-vmware-managed-vcd/src/routes/routes.constant.ts
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/routes/routes.constant.ts
@@ -8,6 +8,7 @@ export const subRoutes = {
datacentres: 'datacentres',
datacentreStorage: 'storage',
datacentreCompute: 'compute',
+ resetPassword: 'reset-password',
};
export const urls = {
@@ -15,6 +16,7 @@ export const urls = {
listing: '/',
onboarding: `/${subRoutes.onboarding}`,
dashboard: `/${subRoutes.dashboard}`,
+ resetPassword: `/${subRoutes.dashboard}/${subRoutes.resetPassword}`,
editName: `/${subRoutes.dashboard}/${subRoutes.editName}`,
editDescription: `/${subRoutes.dashboard}/${subRoutes.editDescription}`,
datacentres: `/${subRoutes.dashboard}/${subRoutes.datacentres}`,
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/TestApp.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/TestApp.tsx
index f2fe8695cbc1..99fa0eaedc42 100644
--- a/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/TestApp.tsx
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/TestApp.tsx
@@ -2,6 +2,7 @@ import React from 'react';
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
import { createMemoryRouter, RouterProvider } from 'react-router-dom';
import { Routes } from '../routes/routes';
+import { MessageContextProvider } from '@/context/Message.context';
export function TestApp({ initialRoute = '/' }) {
const router = createMemoryRouter(Routes, {
@@ -15,7 +16,9 @@ export function TestApp({ initialRoute = '/' }) {
return (
-
+
+
+
);
}
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/index.ts b/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/index.ts
index 1304c9bc2038..27f202fe11ad 100644
--- a/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/index.ts
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/index.ts
@@ -4,6 +4,7 @@ export {
DEFAULT_TIMEOUT,
DEFAULT_LISTING_ERROR,
checkTextVisibility,
+ waitForEnabledElement,
mockEditInputValue,
mockSubmitNewValue,
checkModalVisibility,
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/render-test.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/render-test.tsx
index 4ab566b5cee6..1c85cc7ac150 100644
--- a/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/render-test.tsx
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/render-test.tsx
@@ -19,6 +19,8 @@ import {
getVeeamBackupMocks,
getOrganizationMocks,
GetOrganizationMocksParams,
+ getDatacentresMocks,
+ GetDatacentresMocksParams,
getDatacentreOrderMocks,
GetDatacentreOrderMocksParams,
GetVeeamBackupMocksParams,
@@ -37,6 +39,7 @@ export const renderTest = async ({
}: {
initialRoute?: string;
} & GetOrganizationMocksParams &
+ GetDatacentresMocksParams &
GetDatacentreOrderMocksParams &
GetVeeamBackupMocksParams &
GetServicesMocksParams = {}) => {
@@ -45,6 +48,7 @@ export const renderTest = async ({
...getAuthenticationMocks({ isAuthMocked: true }),
...getVeeamBackupMocks(mockParams),
...getOrganizationMocks(mockParams),
+ ...getDatacentresMocks(mockParams),
...getDatacentreOrderMocks(mockParams),
...getIamMocks(),
...getServicesMocks(mockParams),
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/uiTestHelpers.ts b/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/uiTestHelpers.ts
index 9870fe869fa0..72b8d1c0a686 100644
--- a/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/uiTestHelpers.ts
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/uiTestHelpers.ts
@@ -12,10 +12,11 @@ import { expect } from 'vitest';
export const DEFAULT_TIMEOUT = 30_000;
export const DEFAULT_LISTING_ERROR = 'An error occured while fetching data';
+// General helpers
/**
* @description Standard check: wait and expect some text to be visible on the screen
* @param text expected to be visible
- * @param timeout time to wait for
+ * @param timeout time to wait for (default to 30sec)
* @returns
*/
export const checkTextVisibility = (
@@ -26,6 +27,17 @@ export const checkTextVisibility = (
timeout,
});
+export const waitForEnabledElement = async (
+ elementLabel: string,
+): Promise => {
+ let button;
+ await waitFor(() => {
+ button = screen.getByText(elementLabel);
+ return expect(button).toBeEnabled();
+ });
+ return button;
+};
+
// Form helpers
export const mockEditInputValue = async (value: string) => {
const input = screen.getByLabelText('edit-input');
diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/utils/queryKeys.ts b/packages/manager/apps/hpc-vmware-managed-vcd/src/utils/queryKeys.ts
index 5ed87dc0edf6..4386c620355c 100644
--- a/packages/manager/apps/hpc-vmware-managed-vcd/src/utils/queryKeys.ts
+++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/utils/queryKeys.ts
@@ -12,6 +12,10 @@ export const getVcdOrganizationBackupQueryKey = (id: string) => [
...getVcdOrganizationQueryKey(id),
'backup',
];
+export const getVcdOrganizationResetPasswordQueryKey = (id: string) => [
+ ...getVcdOrganizationQueryKey(id),
+ 'resetPassword',
+];
export const getVcdCatalogQueryKey = (serviceName: string) => [
'order',
'cartServiceOption',
diff --git a/packages/manager/apps/veeam-backup/package.json b/packages/manager/apps/veeam-backup/package.json
index 47f9c5138108..398805554833 100644
--- a/packages/manager/apps/veeam-backup/package.json
+++ b/packages/manager/apps/veeam-backup/package.json
@@ -29,7 +29,7 @@
"@ovh-ux/manager-react-core-application": "^0.11.1",
"@ovh-ux/manager-react-shell-client": "^0.8.1",
"@ovh-ux/manager-tailwind-config": "^0.2.1",
- "@ovh-ux/manager-module-order": "^0.6.3",
+ "@ovh-ux/manager-module-order": "^0.7.1",
"@ovh-ux/request-tagger": "^0.4.0",
"@ovhcloud/ods-common-core": "17.2.2",
"@ovhcloud/ods-common-theming": "17.2.2",