Skip to content

Commit 56b0fe3

Browse files
bra-i-amdcoa
authored andcommitted
feat: implement ToastManager for user role removal notifications
1 parent bf5ebaa commit 56b0fe3

5 files changed

Lines changed: 84 additions & 11 deletions

File tree

src/authz-module/index.scss

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,10 @@
3636
}
3737
}
3838

39-
4039
.toast-container {
4140
// Ensure toast appears above modal
4241
z-index: 1000;
4342
// Move toast to the right
4443
left: auto;
4544
right: var(--pgn-spacing-toast-container-gutter-lg);
46-
}
45+
}

src/authz-module/index.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,24 @@ import { Suspense } from 'react';
22
import { Routes, Route } from 'react-router-dom';
33
import { ErrorBoundary } from '@edx/frontend-platform/react';
44
import LoadingPage from '@src/components/LoadingPage';
5+
import { ToastManagerProvider } from './libraries-manager/ToastManagerContext';
56
import { LibrariesTeamManager, LibrariesUserManager, LibrariesLayout } from './libraries-manager';
67
import { ROUTES } from './constants';
78

89
import './index.scss';
910

1011
const AuthZModule = () => (
1112
<ErrorBoundary>
12-
<Suspense fallback={<LoadingPage />}>
13-
<Routes>
14-
<Route element={<LibrariesLayout />}>
15-
<Route path={ROUTES.LIBRARIES_TEAM_PATH} element={<LibrariesTeamManager />} />
16-
<Route path={ROUTES.LIBRARIES_USER_PATH} element={<LibrariesUserManager />} />
17-
</Route>
18-
</Routes>
19-
</Suspense>
13+
<ToastManagerProvider>
14+
<Suspense fallback={<LoadingPage />}>
15+
<Routes>
16+
<Route element={<LibrariesLayout />}>
17+
<Route path={ROUTES.LIBRARIES_TEAM_PATH} element={<LibrariesTeamManager />} />
18+
<Route path={ROUTES.LIBRARIES_USER_PATH} element={<LibrariesUserManager />} />
19+
</Route>
20+
</Routes>
21+
</Suspense>
22+
</ToastManagerProvider>
2023
</ErrorBoundary>
2124
);
2225

src/authz-module/libraries-manager/LibrariesUserManager.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { useIntl } from '@edx/frontend-platform/i18n';
44
import { Container } from '@openedx/paragon';
55
import { ROUTES } from '@src/authz-module/constants';
66
import { Role } from 'types';
7+
import { useToastManager } from 'authz-module/libraries-manager/ToastManagerContext';
78
import AuthZLayout from '../components/AuthZLayout';
89
import { useLibraryAuthZ } from './context';
910
import RoleCard from '../components/RoleCard';
@@ -29,6 +30,7 @@ const LibrariesUserManager = () => {
2930

3031
const [roleToDelete, setRoleToDelete] = useState('');
3132
const [showConfirmDeletionModal, setShowConfirmDeletionModal] = useState(false);
33+
const { handleShowToast, handleDiscardToast } = useToastManager();
3234

3335
const { data: teamMembers, isLoading: isLoadingTeamMembers } = useTeamMembers(libraryId);
3436
const user = teamMembers?.find(member => member.username === username);
@@ -44,11 +46,12 @@ const LibrariesUserManager = () => {
4446
}, [roles, user?.roles, permissions, resources, intl]);
4547

4648
const handleCloseConfirmDeletionModal = () => {
47-
setShowConfirmDeletionModal(false);
4849
setRoleToDelete('');
50+
setShowConfirmDeletionModal(false);
4951
};
5052

5153
const handleShowConfirmDeletionModal = (role: Pick<Role, 'name' | 'role'>) => {
54+
handleDiscardToast();
5255
setRoleToDelete(role.name);
5356
setShowConfirmDeletionModal(true);
5457
};
@@ -63,6 +66,10 @@ const LibrariesUserManager = () => {
6366

6467
revokeUserRoles({ data }, {
6568
onSuccess: () => {
69+
handleShowToast(intl.formatMessage(messages['library.authz.team.remove.user.toast.success.description'], {
70+
role,
71+
rolesCount: userRoles.length - 1,
72+
}));
6673
handleCloseConfirmDeletionModal();
6774
},
6875
});
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import {
2+
createContext, useContext, useMemo, useState,
3+
} from 'react';
4+
import { Toast } from '@openedx/paragon';
5+
6+
type ToastManagerContextType = {
7+
handleShowToast: (message: string) => void;
8+
handleDiscardToast: () => void;
9+
};
10+
11+
const ToastManagerContext = createContext<ToastManagerContextType | undefined>(undefined);
12+
13+
interface ToastManagerProviderProps {
14+
handleClose?: () => void
15+
children: React.ReactNode | React.ReactNode[];
16+
}
17+
18+
export const ToastManagerProvider = ({ handleClose, children }: ToastManagerProviderProps) => {
19+
const [toastMessage, setToastMessage] = useState<string | null>(null);
20+
21+
const handleShowToast = (message: string) => {
22+
setToastMessage(message);
23+
};
24+
25+
const handleDiscardToast = () => {
26+
setToastMessage(null);
27+
};
28+
29+
const value = useMemo((): ToastManagerContextType => ({
30+
handleShowToast,
31+
handleDiscardToast,
32+
}), []);
33+
34+
return (
35+
<ToastManagerContext.Provider value={value}>
36+
{children}
37+
38+
{toastMessage && (
39+
<Toast
40+
onClose={() => {
41+
if (handleClose) { handleClose(); }
42+
setToastMessage(null);
43+
}}
44+
show={!!toastMessage}
45+
>
46+
{toastMessage}
47+
</Toast>
48+
)}
49+
</ToastManagerContext.Provider>
50+
);
51+
};
52+
53+
export const useToastManager = (): ToastManagerContextType => {
54+
const context = useContext(ToastManagerContext);
55+
if (context === undefined) {
56+
throw new Error('useToastManager must be used within an ToastManagerProvider');
57+
}
58+
return context;
59+
};

src/authz-module/libraries-manager/messages.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ const messages = defineMessages({
2626
defaultMessage: 'Permissions',
2727
description: 'Libreries AuthZ title for the permissions tab',
2828
},
29+
'library.authz.team.remove.user.toast.success.description': {
30+
id: 'library.authz.team.remove.user.toast.success.description',
31+
defaultMessage: 'The {role} role has been successfully removed.{rolesCount, plural, =0 { The user no longer has access to this library and has been removed from the member list.} other {}}',
32+
description: 'Libraries team management remove user toast success',
33+
},
2934
});
3035

3136
export default messages;

0 commit comments

Comments
 (0)