@openedx/frontend-app-admin-console 1.0.0-alpha.1 → 1.0.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authz-module/audit-user/index.js +6 -13
- package/dist/authz-module/audit-user/index.js.map +1 -1
- package/dist/authz-module/authz-home/index.js +21 -2
- package/dist/authz-module/authz-home/index.js.map +1 -1
- package/dist/authz-module/components/AddRoleButton.js +1 -1
- package/dist/authz-module/components/AddRoleButton.js.map +1 -1
- package/dist/authz-module/components/AuthZLayout.d.ts +7 -6
- package/dist/authz-module/components/AuthZLayout.js +9 -3
- package/dist/authz-module/components/AuthZLayout.js.map +1 -1
- package/dist/authz-module/components/AuthZTitle.d.ts +3 -2
- package/dist/authz-module/components/AuthZTitle.js +9 -7
- package/dist/authz-module/components/AuthZTitle.js.map +1 -1
- package/dist/authz-module/components/ExpandableButton.d.ts +17 -0
- package/dist/authz-module/components/ExpandableButton.js +16 -0
- package/dist/authz-module/components/ExpandableButton.js.map +1 -0
- package/dist/authz-module/components/PermissionTable.js +5 -1
- package/dist/authz-module/components/PermissionTable.js.map +1 -1
- package/dist/authz-module/components/TableCells.d.ts +5 -9
- package/dist/authz-module/components/TableCells.js +35 -65
- package/dist/authz-module/components/TableCells.js.map +1 -1
- package/dist/authz-module/components/TableControlBar/MultipleChoiceFilter.d.ts +1 -1
- package/dist/authz-module/components/TableControlBar/MultipleChoiceFilter.js +4 -3
- package/dist/authz-module/components/TableControlBar/MultipleChoiceFilter.js.map +1 -1
- package/dist/authz-module/components/TableControlBar/OrgFilter.js +2 -2
- package/dist/authz-module/components/TableControlBar/OrgFilter.js.map +1 -1
- package/dist/authz-module/components/TableControlBar/SearchFilter.d.ts +2 -1
- package/dist/authz-module/components/TableControlBar/SearchFilter.js +2 -1
- package/dist/authz-module/components/TableControlBar/SearchFilter.js.map +1 -1
- package/dist/authz-module/components/TableControlBar/TableControlBar.d.ts +4 -1
- package/dist/authz-module/components/TableControlBar/TableControlBar.js +24 -24
- package/dist/authz-module/components/TableControlBar/TableControlBar.js.map +1 -1
- package/dist/authz-module/components/TableControlBar/types.d.ts +1 -0
- package/dist/authz-module/components/TableControlBar/types.js.map +1 -1
- package/dist/authz-module/components/TableFooter/TableFooter.d.ts +14 -1
- package/dist/authz-module/components/TableFooter/TableFooter.js +3 -2
- package/dist/authz-module/components/TableFooter/TableFooter.js.map +1 -1
- package/dist/authz-module/components/constants.d.ts +1 -0
- package/dist/authz-module/components/constants.js +2 -1
- package/dist/authz-module/components/constants.js.map +1 -1
- package/dist/authz-module/components/messages.d.ts +0 -5
- package/dist/authz-module/components/messages.js +2 -7
- package/dist/authz-module/components/messages.js.map +1 -1
- package/dist/authz-module/constants.d.ts +18 -8
- package/dist/authz-module/constants.js +30 -11
- package/dist/authz-module/constants.js.map +1 -1
- package/dist/authz-module/data/api.d.ts +12 -4
- package/dist/authz-module/data/api.js +11 -2
- package/dist/authz-module/data/api.js.map +1 -1
- package/dist/authz-module/data/hooks.d.ts +8 -8
- package/dist/authz-module/data/hooks.js +15 -20
- package/dist/authz-module/data/hooks.js.map +1 -1
- package/dist/authz-module/hooks/useExclusiveRowExpansion.d.ts +7 -0
- package/dist/authz-module/hooks/useExclusiveRowExpansion.js +24 -0
- package/dist/authz-module/hooks/useExclusiveRowExpansion.js.map +1 -0
- package/dist/authz-module/index.scss +150 -13
- package/dist/authz-module/messages.d.ts +23 -0
- package/dist/authz-module/messages.js +18 -0
- package/dist/authz-module/messages.js.map +1 -1
- package/dist/authz-module/role-assignation-wizard/AssignRoleWizard.js +1 -1
- package/dist/authz-module/role-assignation-wizard/AssignRoleWizard.js.map +1 -1
- package/dist/authz-module/role-assignation-wizard/AssignRoleWizardPage.js +4 -4
- package/dist/authz-module/role-assignation-wizard/AssignRoleWizardPage.js.map +1 -1
- package/dist/authz-module/role-assignation-wizard/components/ScopeFilterBar.js +1 -1
- package/dist/authz-module/role-assignation-wizard/components/ScopeFilterBar.js.map +1 -1
- package/dist/authz-module/role-assignation-wizard/hooks/useScopeListData.js.map +1 -1
- package/dist/authz-module/roles-permissions/RolesPermissions.js +3 -3
- package/dist/authz-module/roles-permissions/RolesPermissions.js.map +1 -1
- package/dist/authz-module/team-members/TeamMembersTable.js +102 -58
- package/dist/authz-module/team-members/TeamMembersTable.js.map +1 -1
- package/dist/authz-module/team-members/components/AssignedRolesCell.d.ts +20 -0
- package/dist/authz-module/team-members/components/AssignedRolesCell.js +54 -0
- package/dist/authz-module/team-members/components/AssignedRolesCell.js.map +1 -0
- package/dist/authz-module/team-members/components/MoreRolesToggle.d.ts +14 -0
- package/dist/authz-module/team-members/components/MoreRolesToggle.js +25 -0
- package/dist/authz-module/team-members/components/MoreRolesToggle.js.map +1 -0
- package/dist/authz-module/team-members/components/TeamMemberCells.d.ts +17 -0
- package/dist/authz-module/team-members/components/TeamMemberCells.js +21 -0
- package/dist/authz-module/team-members/components/TeamMemberCells.js.map +1 -0
- package/dist/authz-module/team-members/components/TeamMemberViewActionCell.d.ts +18 -0
- package/dist/authz-module/team-members/components/TeamMemberViewActionCell.js +42 -0
- package/dist/authz-module/team-members/components/TeamMemberViewActionCell.js.map +1 -0
- package/dist/authz-module/team-members/components/UserAssignmentsSubTable.d.ts +16 -0
- package/dist/authz-module/team-members/components/UserAssignmentsSubTable.js +74 -0
- package/dist/authz-module/team-members/components/UserAssignmentsSubTable.js.map +1 -0
- package/dist/authz-module/team-members/index.d.ts +1 -0
- package/dist/authz-module/team-members/index.js +2 -0
- package/dist/authz-module/team-members/index.js.map +1 -0
- package/dist/authz-module/team-members/messages.d.ts +56 -1
- package/dist/authz-module/team-members/messages.js +59 -4
- package/dist/authz-module/team-members/messages.js.map +1 -1
- package/dist/authz-module/utils.d.ts +6 -0
- package/dist/authz-module/utils.js +12 -10
- package/dist/authz-module/utils.js.map +1 -1
- package/dist/components/LoadingPage.d.ts +3 -0
- package/dist/components/LoadingPage.js +9 -1
- package/dist/components/LoadingPage.js.map +1 -1
- package/dist/components/messages.d.ts +8 -0
- package/dist/components/messages.js +10 -0
- package/dist/components/messages.js.map +1 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/routes.d.ts +3 -1
- package/dist/routes.js +17 -4
- package/dist/routes.js.map +1 -1
- package/dist/style.scss +19 -2
- package/dist/types.d.ts +29 -20
- package/dist/types.js.map +1 -1
- package/package.json +6 -3
- package/dist/authz-module/components/ViewMoreLink.d.ts +0 -8
- package/dist/authz-module/components/ViewMoreLink.js +0 -8
- package/dist/authz-module/components/ViewMoreLink.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useContext, useEffect, useMemo, useState, } from 'react';
|
|
3
3
|
import { SiteContext, useIntl } from '@openedx/frontend-base';
|
|
4
|
-
import {
|
|
4
|
+
import { DataTable } from '@openedx/paragon';
|
|
5
5
|
import TableFooter from '../components/TableFooter/TableFooter';
|
|
6
6
|
import { AUTHZ_HOME_PATH, TABLE_DEFAULT_PAGE_SIZE, } from '../constants';
|
|
7
7
|
import AuthZLayout from '../components/AuthZLayout';
|
|
@@ -14,7 +14,6 @@ import baseMessages from '../messages';
|
|
|
14
14
|
import AddRoleButton from '../components/AddRoleButton';
|
|
15
15
|
import { OrgCell, RoleCell, ScopeCell, PermissionsCell, ViewAllPermissionsCell, createActionsCell, } from '../components/TableCells';
|
|
16
16
|
import { useQuerySettings } from '../hooks/useQuerySettings';
|
|
17
|
-
import { useCourseAuthoringFlag } from '../hooks/useCourseAuthoringFlag';
|
|
18
17
|
import { useRevokeUserRoles, useUserAssignedRoles } from '../data/hooks';
|
|
19
18
|
import { useToastManager } from '../../components/ToastManager/ToastManagerContext';
|
|
20
19
|
import UserPermissions from '../components/UserPermissions';
|
|
@@ -33,7 +32,6 @@ const AuditUserPage = () => {
|
|
|
33
32
|
const { isLoading: isLoadingUser, data: user, isError: isErrorUser, error: errorUser, } = useUserAccount(username);
|
|
34
33
|
const { querySettings, handleTableFetch } = useQuerySettings();
|
|
35
34
|
const { isCourseViewAllowed } = useViewTeamPermissions();
|
|
36
|
-
const { isCourseEnabled } = useCourseAuthoringFlag();
|
|
37
35
|
const effectiveQuerySettings = useMemo(() => {
|
|
38
36
|
if (isCourseViewAllowed || querySettings.roles)
|
|
39
37
|
return querySettings;
|
|
@@ -89,10 +87,9 @@ const AuditUserPage = () => {
|
|
|
89
87
|
Cell: createActionsCell({
|
|
90
88
|
onClickDeleteButton: handleShowConfirmDeletionModal,
|
|
91
89
|
isUserAuthenticatedPage: username === (authenticatedUser === null || authenticatedUser === void 0 ? void 0 : authenticatedUser.username),
|
|
92
|
-
isCourseEnabled,
|
|
93
90
|
}),
|
|
94
91
|
},
|
|
95
|
-
], [authenticatedUser === null || authenticatedUser === void 0 ? void 0 : authenticatedUser.username, formatMessage, handleShowConfirmDeletionModal, username
|
|
92
|
+
], [authenticatedUser === null || authenticatedUser === void 0 ? void 0 : authenticatedUser.username, formatMessage, handleShowConfirmDeletionModal, username]);
|
|
96
93
|
const columns = useMemo(() => [
|
|
97
94
|
{
|
|
98
95
|
Header: getCellHeader('role', formatMessage(messages['authz.user.table.role.column.header']), columnsWithFiltersApplied),
|
|
@@ -173,19 +170,15 @@ const AuditUserPage = () => {
|
|
|
173
170
|
};
|
|
174
171
|
runRevokeRole({ data });
|
|
175
172
|
};
|
|
176
|
-
return (_jsxs(
|
|
173
|
+
return (_jsxs(_Fragment, { children: [_jsx(ConfirmDeletionModal, { isOpen: showConfirmDeletionModal, close: handleCloseConfirmDeletionModal, onSave: handleRevokeUserRole, isDeleting: isRevokingUserRolePending, context: {
|
|
177
174
|
userName: (user === null || user === void 0 ? void 0 : user.username) || '',
|
|
178
175
|
scope: (roleToDelete === null || roleToDelete === void 0 ? void 0 : roleToDelete.scope) || '',
|
|
179
176
|
role: (roleToDelete === null || roleToDelete === void 0 ? void 0 : roleToDelete.role) || '',
|
|
180
177
|
name: (roleToDelete === null || roleToDelete === void 0 ? void 0 : roleToDelete.name) || '',
|
|
181
178
|
rolesCount: count || 0,
|
|
182
|
-
} }), _jsx(AuthZLayout, {
|
|
183
|
-
id: '',
|
|
184
|
-
org: '',
|
|
185
|
-
title: '',
|
|
186
|
-
}, navLinks: navLinks, activeLabel: (user === null || user === void 0 ? void 0 : user.username) || '', pageTitle: (user === null || user === void 0 ? void 0 : user.username) || '', pageSubtitle: (user === null || user === void 0 ? void 0 : user.email) || '', actions: [
|
|
179
|
+
} }), _jsx(AuthZLayout, { navLinks: navLinks, activeLabel: (user === null || user === void 0 ? void 0 : user.username) || '', pageTitle: (user === null || user === void 0 ? void 0 : user.username) || '', pageSubtitle: (user === null || user === void 0 ? void 0 : user.email) || '', actions: [
|
|
187
180
|
_jsx(AddRoleButton, { presetUsername: user === null || user === void 0 ? void 0 : user.username }, "add-role-button"),
|
|
188
|
-
], children: _jsx(
|
|
181
|
+
], showDivider: true, children: _jsx("div", { className: "page-band py-3", children: _jsxs(DataTable, { isPaginated: true, isFilterable: true, isSortable: true, manualPagination: true, data: rowsWithPermissions, manualFilters: true, manualSortBy: true, fetchData: fetchData, itemCount: count, pageCount: pageCount, initialState: { pageSize: TABLE_DEFAULT_PAGE_SIZE }, additionalColumns: additionalColumns, columns: columns, isLoading: isLoadingUserAssignments, isExpandable: true, renderRowSubComponent: ({ row }) => (_jsx(UserPermissions, { row: row })), children: [_jsx(TableControlBar, { onFilterChange: setColumnsWithFiltersApplied }), _jsx(DataTable.Table, {}), _jsx(TableFooter, {})] }) }) })] }));
|
|
189
182
|
};
|
|
190
183
|
export default AuditUserPage;
|
|
191
184
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authz-module/audit-user/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,WAAW,EACX,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,GACzC,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EACL,SAAS,EAAE,SAAS,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,WAAW,MAAM,sDAAsD,CAAC;AAC/E,OAAO,EACL,eAAe,EAAE,uBAAuB,GACzC,MAAM,6BAA6B,CAAC;AACrC,OAAO,WAAW,MAAM,0CAA0C,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,qCAAqC,EAAE,MAAM,iBAAiB,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AACxF,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,YAAY,MAAM,4BAA4B,CAAC;AACtD,OAAO,aAAa,MAAM,4CAA4C,CAAC;AACvE,OAAO,EACL,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,sBAAsB,EACrE,iBAAiB,GAClB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AACxF,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAGxF,OAAO,EAAE,eAAe,EAAE,MAAM,kDAAkD,CAAC;AACnF,OAAO,eAAe,MAAM,8CAA8C,CAAC;AAC3E,OAAO,SAAS,MAAM,wDAAwD,CAAC;AAC/E,OAAO,WAAW,MAAM,0DAA0D,CAAC;AACnF,OAAO,eAAe,MAAM,8DAA8D,CAAC;AAC3F,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,oBAAoB,MAAM,mDAAmD,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AAExF,MAAM,aAAa,GAAG,GAAG,EAAE;IACzB,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,CAAC,yBAAyB,EAAE,4BAA4B,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IACzF,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,CAAC;IACjC,MAAM,EAAE,iBAAiB,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,EACJ,SAAS,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,GAC7E,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC7B,MAAM,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAE/D,MAAM,EAAE,mBAAmB,EAAE,GAAG,sBAAsB,EAAE,CAAC;IACzD,MAAM,EAAE,eAAe,EAAE,GAAG,sBAAsB,EAAE,CAAC;IAErD,MAAM,sBAAsB,GAAG,OAAO,CAAC,GAAG,EAAE;QAC1C,IAAI,mBAAmB,IAAI,aAAa,CAAC,KAAK;YAAE,OAAO,aAAa,CAAC;QACrE,uCAAY,aAAa,KAAE,KAAK,EAAE,iBAAiB,IAAG;IACxD,CAAC,EAAE,CAAC,mBAAmB,EAAE,aAAa,CAAC,CAAC,CAAC;IAEzC,MAAM,EACJ,SAAS,EAAE,wBAAwB,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,GAC3G,GAAG,oBAAoB,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAC;IAC3D,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAsB,IAAI,CAAC,CAAC;IAC5E,MAAM,CAAC,wBAAwB,EAAE,2BAA2B,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChF,MAAM,EACJ,SAAS,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,GACpC,GAAG,eAAe,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,yBAAyB,EAAE,GAAG,kBAAkB,EAAE,CAAC;IAE/F,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,EAAE;QACrC,MAAM,YAAY,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvF,OAAO,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,8BAA8B,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1E,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;IAEtB,MAAM,EACJ,IAAI,EAAE,wBAAwB,GAC/B,GAAG,qCAAqC,CAAC,iBAAiB,CAAC,CAAC;IAE7D,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,EAAE;QACvC,IAAI,CAAC,wBAAwB;YAAE,OAAO,eAAe,CAAC;QAEtD,OAAO,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;YACtC,MAAM,cAAc,GAAG,wBAAwB,CAAC,IAAI,CAClD,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,IAAI,UAAU,CAAC,OAAO,CAC1E,CAAC;YACF,uCACK,UAAU,KACb,cAAc,IACd;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,eAAe,EAAE,wBAAwB,CAAC,CAAC,CAAC;IAEhD,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,gBAAgB,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEtE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YAC5B,IAAI,CAAC,WAAW,IAAI,kBAAkB,CAAC,SAAS,CAAC,KAAK,GAAG,EAAE,CAAC;gBAC1D,QAAQ,CAAC,eAAe,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;IAE5D,MAAM,8BAA8B,GAAG,WAAW,CAAC,CAAC,IAAkB,EAAE,EAAE;QACxE,IAAI,yBAAyB;YAAE,OAAO;QAEtC,eAAe,CAAC,IAAI,CAAC,CAAC;QACtB,2BAA2B,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAEhC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAC7B;YACE,KAAK,EAAE,aAAa,CAAC,YAAY,CAAC,gCAAgC,CAAC,CAAC;YACpE,EAAE,EAAE,eAAe;SACpB;KACF,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QACtC;YACE,EAAE,EAAE,kBAAkB;YACtB,MAAM,EAAE,EAAE;YACV,IAAI,EAAE,sBAAsB;SAC7B;QACD;YACE,EAAE,EAAE,QAAQ;YACZ,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,uCAAuC,CAAC,CAAC;YACxE,IAAI,EAAE,iBAAiB,CAAC;gBACtB,mBAAmB,EAAE,8BAA8B;gBACnD,uBAAuB,EAAE,QAAQ,MAAK,iBAAiB,aAAjB,iBAAiB,uBAAjB,iBAAiB,CAAE,QAAQ,CAAA;gBACjE,eAAe;aAChB,CAAC;SACH;KACF,EAAE,CAAC,iBAAiB,aAAjB,iBAAiB,uBAAjB,iBAAiB,CAAE,QAAQ,EAAE,aAAa,EAAE,8BAA8B,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC;IAE5G,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAC5B;YACE,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,qCAAqC,CAAC,CAAC,EAAE,yBAAyB,CAAC;YACxH,QAAQ,EAAE,MAAM;YAChB,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,eAAe;YACvB,MAAM,EAAE,WAAW;YACnB,gBAAgB,EAAE,aAAa,CAAC,QAAQ,CAAC,qCAAqC,CAAC,CAAC;YAChF,WAAW,EAAE,CAAC;SACf;QACD;YACE,MAAM,EAAE,aAAa,CAAC,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,6CAA6C,CAAC,CAAC,EAAE,yBAAyB,CAAC;YAC/H,QAAQ,EAAE,KAAK;YACf,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,eAAe;YACvB,MAAM,EAAE,SAAS;YACjB,gBAAgB,EAAE,aAAa,CAAC,QAAQ,CAAC,6CAA6C,CAAC,CAAC;YACxF,WAAW,EAAE,CAAC;SACf;QACD;YACE,MAAM,EAAE,aAAa,CAAC,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,sCAAsC,CAAC,CAAC,EAAE,yBAAyB,CAAC;YAC1H,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,SAAS;YACf,cAAc,EAAE,IAAI;SAErB;QACD;YACE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,4CAA4C,CAAC,CAAC;YAC7E,IAAI,EAAE,eAAe;YACrB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;KACF,EAAE,CAAC,aAAa,EAAE,yBAAyB,CAAC,CAAC,CAAC;IAE/C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,uBAAuB,CAAC,CAAC;IAE7D,MAAM,+BAA+B,GAAG,GAAG,EAAE;QAC3C,eAAe,CAAC,IAAI,CAAC,CAAC;QACtB,2BAA2B,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC,CAAC;IAEF,MAAM,oBAAoB,GAAG,GAAG,EAAE;QAChC,IAAI,CAAC,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO;QAEnC,MAAM,IAAI,GAAG;YACX,KAAK,EAAE,IAAI,CAAC,QAAQ;YACpB,IAAI,EAAE,YAAY,CAAC,IAAI;YACvB,KAAK,EAAE,YAAY,CAAC,KAAK;SAC1B,CAAC;QAEF,MAAM,aAAa,GAAG,CAAC,SAA2C,EAAE,EAAE;YACpE,MAAM,aAAa,GAAG;gBACpB,IAAI,kCACC,SAAS,CAAC,IAAI,KACjB,aAAa,GACd;aAEF,CAAC;YACF,eAAe,CAAC,aAAa,EAAE;gBAC7B,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE;;oBACtB,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC;oBAE5B,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;wBAClB,SAAS,CAAC;4BACR,IAAI,EAAE,OAAO;4BACb,OAAO,EAAE,aAAa,CACpB,YAAY,CAAC,wCAAwC,CAAC,EACtD,EAAE,IAAI,EAAE,EAAE,EAAE,CACb;yBACF,CAAC,CAAC;wBACH,OAAO;oBACT,CAAC;oBAED,MAAM,mBAAmB,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBAClD,SAAS,CAAC;wBACR,OAAO,EAAE,aAAa,CACpB,YAAY,CAAC,kDAAkD,CAAC,EAChE;4BACE,IAAI,EAAE,MAAA,YAAY,CAAC,IAAI,mCAAI,YAAY,CAAC,IAAI;4BAC5C,UAAU,EAAE,mBAAmB;yBAChC,CACF;wBACD,IAAI,EAAE,SAAS;qBAChB,CAAC,CAAC;oBACH,+BAA+B,EAAE,CAAC;oBAClC,IAAI,mBAAmB,KAAK,CAAC,EAAE,CAAC;wBAC9B,QAAQ,CAAC,eAAe,CAAC,CAAC;oBAC5B,CAAC;gBACH,CAAC;gBACD,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE;oBACjC,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC;gBAC7D,CAAC;aACF,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAC,cAAc,aAC3B,KAAC,oBAAoB,IACnB,MAAM,EAAE,wBAAwB,EAChC,KAAK,EAAE,+BAA+B,EACtC,MAAM,EAAE,oBAAoB,EAC5B,UAAU,EAAE,yBAAyB,EACrC,OAAO,EAAE;oBACP,QAAQ,EAAE,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,KAAI,EAAE;oBAC9B,KAAK,EAAE,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK,KAAI,EAAE;oBAChC,IAAI,EAAE,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,IAAI,KAAI,EAAE;oBAC9B,IAAI,EAAE,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,IAAI,KAAI,EAAE;oBAC9B,UAAU,EAAE,KAAK,IAAI,CAAC;iBACvB,GACD,EACF,KAAC,WAAW,IACV,OAAO,EAAE;oBACP,EAAE,EAAE,EAAE;oBACN,GAAG,EAAE,EAAE;oBACP,KAAK,EAAE,EAAE;iBACV,EACD,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,KAAI,EAAE,EACjC,SAAS,EAAE,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,KAAI,EAAE,EAC/B,YAAY,EAAE,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK,KAAI,EAAE,EAC/B,OAAO,EACL;oBACE,KAAC,aAAa,IAAC,cAAc,EAAE,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,IAAM,iBAAiB,CAAG;iBACxE,YAGH,KAAC,SAAS,IAAC,SAAS,EAAC,kBAAkB,YACrC,MAAC,SAAS,IACR,WAAW,QACX,YAAY,QACZ,UAAU,QACV,gBAAgB,QAChB,IAAI,EAAE,mBAAmB,EACzB,aAAa,QACb,YAAY,QACZ,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,KAAK,EAChB,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,EAAE,QAAQ,EAAE,uBAAuB,EAAE,EACnD,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,wBAAwB,EACnC,YAAY,QACZ,qBAAqB,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAClC,KAAC,eAAe,IAAC,GAAG,EAAE,GAAG,GAAI,CAC9B,aAED,KAAC,eAAe,IAAC,cAAc,EAAE,4BAA4B,GAAI,EACjE,KAAC,SAAS,CAAC,KAAK,KAAG,EACnB,KAAC,WAAW,KAAG,IACL,GAEF,GACA,IACV,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,aAAa,CAAC","sourcesContent":["import {\n useCallback,\n useContext, useEffect, useMemo, useState,\n} from 'react';\nimport { SiteContext, useIntl } from '@openedx/frontend-base';\nimport {\n Container, DataTable,\n} from '@openedx/paragon';\nimport TableFooter from '@src/authz-module/components/TableFooter/TableFooter';\nimport {\n AUTHZ_HOME_PATH, TABLE_DEFAULT_PAGE_SIZE,\n} from '@src/authz-module/constants';\nimport AuthZLayout from '@src/authz-module/components/AuthZLayout';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport { useUserAccount, useValidateUserPermissionsNonSuspense } from '@src/data/hooks';\nimport { LIBRARY_ROLE_KEYS } from '@src/authz-module/roles-permissions';\nimport { useViewTeamPermissions } from '@src/authz-module/hooks/useViewTeamPermissions';\nimport { getHttpErrorStatus } from '@src/data/utils';\nimport baseMessages from '@src/authz-module/messages';\nimport AddRoleButton from '@src/authz-module/components/AddRoleButton';\nimport {\n OrgCell, RoleCell, ScopeCell, PermissionsCell, ViewAllPermissionsCell,\n createActionsCell,\n} from '@src/authz-module/components/TableCells';\nimport { useQuerySettings } from '@src/authz-module/hooks/useQuerySettings';\nimport { useCourseAuthoringFlag } from '@src/authz-module/hooks/useCourseAuthoringFlag';\nimport { useRevokeUserRoles, useUserAssignedRoles } from '@src/authz-module/data/hooks';\nimport type { RevokeUserRolesRequest } from '@src/authz-module/data/api';\nimport { RoleToDelete } from '@src/types';\nimport { useToastManager } from '@src/components/ToastManager/ToastManagerContext';\nimport UserPermissions from '@src/authz-module/components/UserPermissions';\nimport OrgFilter from '@src/authz-module/components/TableControlBar/OrgFilter';\nimport RolesFilter from '@src/authz-module/components/TableControlBar/RolesFilter';\nimport TableControlBar from '@src/authz-module/components/TableControlBar/TableControlBar';\nimport messages from './messages';\nimport ConfirmDeletionModal from '@src/authz-module/components/ConfirmDeletionModal';\nimport { getCellHeader, getScopeManageActionPermission } from '@src/authz-module/utils';\n\nconst AuditUserPage = () => {\n const { formatMessage } = useIntl();\n const [columnsWithFiltersApplied, setColumnsWithFiltersApplied] = useState<string[]>([]);\n const { username } = useParams();\n const { authenticatedUser } = useContext(SiteContext);\n const navigate = useNavigate();\n const {\n isLoading: isLoadingUser, data: user, isError: isErrorUser, error: errorUser,\n } = useUserAccount(username);\n const { querySettings, handleTableFetch } = useQuerySettings();\n\n const { isCourseViewAllowed } = useViewTeamPermissions();\n const { isCourseEnabled } = useCourseAuthoringFlag();\n\n const effectiveQuerySettings = useMemo(() => {\n if (isCourseViewAllowed || querySettings.roles) return querySettings;\n return { ...querySettings, roles: LIBRARY_ROLE_KEYS };\n }, [isCourseViewAllowed, querySettings]);\n\n const {\n isLoading: isLoadingUserAssignments, data: { results: userAssignments, count } = { results: [], count: 0 },\n } = useUserAssignedRoles(username, effectiveQuerySettings);\n const [roleToDelete, setRoleToDelete] = useState<RoleToDelete | null>(null);\n const [showConfirmDeletionModal, setShowConfirmDeletionModal] = useState(false);\n const {\n showToast, showErrorToast, Bold, Br,\n } = useToastManager();\n const { mutate: revokeUserRoles, isPending: isRevokingUserRolePending } = useRevokeUserRoles();\n\n const deletePermissions = useMemo(() => {\n const uniqueScopes = [...new Set(userAssignments.map(assignment => assignment.scope))];\n return uniqueScopes.map(scope => getScopeManageActionPermission(scope));\n }, [userAssignments]);\n\n const {\n data: permissionsToManageScope,\n } = useValidateUserPermissionsNonSuspense(deletePermissions);\n\n const rowsWithPermissions = useMemo(() => {\n if (!permissionsToManageScope) return userAssignments;\n\n return userAssignments.map(assignment => {\n const canManageScope = permissionsToManageScope.some(\n permission => permission.scope === assignment.scope && permission.allowed,\n );\n return {\n ...assignment,\n canManageScope,\n };\n });\n }, [userAssignments, permissionsToManageScope]);\n\n const fetchData = useMemo(() => handleTableFetch, [handleTableFetch]);\n\n useEffect(() => {\n if (!user && !isLoadingUser) {\n if (!isErrorUser || getHttpErrorStatus(errorUser) === 404) {\n navigate(AUTHZ_HOME_PATH);\n }\n }\n }, [user, isLoadingUser, navigate, isErrorUser, errorUser]);\n\n const handleShowConfirmDeletionModal = useCallback((role: RoleToDelete) => {\n if (isRevokingUserRolePending) return;\n\n setRoleToDelete(role);\n setShowConfirmDeletionModal(true);\n }, [isRevokingUserRolePending]);\n\n const navLinks = useMemo(() => [\n {\n label: formatMessage(baseMessages['authz.management.home.nav.link']),\n to: AUTHZ_HOME_PATH,\n },\n ], [formatMessage]);\n\n const additionalColumns = useMemo(() => [\n {\n id: 'view_permissions',\n Header: '',\n Cell: ViewAllPermissionsCell,\n },\n {\n id: 'action',\n Header: formatMessage(messages['authz.user.table.action.column.header']),\n Cell: createActionsCell({\n onClickDeleteButton: handleShowConfirmDeletionModal,\n isUserAuthenticatedPage: username === authenticatedUser?.username,\n isCourseEnabled,\n }),\n },\n ], [authenticatedUser?.username, formatMessage, handleShowConfirmDeletionModal, username, isCourseEnabled]);\n\n const columns = useMemo(() => [\n {\n Header: getCellHeader('role', formatMessage(messages['authz.user.table.role.column.header']), columnsWithFiltersApplied),\n accessor: 'role',\n Cell: RoleCell,\n filter: 'includesValue',\n Filter: RolesFilter,\n filterButtonText: formatMessage(messages['authz.user.table.role.column.header']),\n filterOrder: 2,\n },\n {\n Header: getCellHeader('org', formatMessage(messages['authz.user.table.organization.column.header']), columnsWithFiltersApplied),\n accessor: 'org',\n Cell: OrgCell,\n filter: 'includesValue',\n Filter: OrgFilter,\n filterButtonText: formatMessage(messages['authz.user.table.organization.column.header']),\n filterOrder: 1,\n },\n {\n Header: getCellHeader('scope', formatMessage(messages['authz.user.table.scope.column.header']), columnsWithFiltersApplied),\n accessor: 'scope',\n Cell: ScopeCell,\n disableFilters: true,\n\n },\n {\n Header: formatMessage(messages['authz.user.table.permissions.column.header']),\n Cell: PermissionsCell,\n disableFilters: true,\n disableSortBy: true,\n },\n ], [formatMessage, columnsWithFiltersApplied]);\n\n const pageCount = Math.ceil(count / TABLE_DEFAULT_PAGE_SIZE);\n\n const handleCloseConfirmDeletionModal = () => {\n setRoleToDelete(null);\n setShowConfirmDeletionModal(false);\n };\n\n const handleRevokeUserRole = () => {\n if (!user || !roleToDelete) return;\n\n const data = {\n users: user.username,\n role: roleToDelete.role,\n scope: roleToDelete.scope,\n };\n\n const runRevokeRole = (variables: { data: RevokeUserRolesRequest }) => {\n const variablesData = {\n data: {\n ...variables.data,\n querySettings,\n },\n\n };\n revokeUserRoles(variablesData, {\n onSuccess: (response) => {\n const { errors } = response;\n\n if (errors.length) {\n showToast({\n type: 'error',\n message: formatMessage(\n baseMessages['authz.team.toast.default.error.message'],\n { Bold, Br },\n ),\n });\n return;\n }\n\n const remainingRolesCount = count ? count - 1 : 0;\n showToast({\n message: formatMessage(\n baseMessages['authz.team.remove.user.toast.success.description'],\n {\n role: roleToDelete.name ?? roleToDelete.role,\n rolesCount: remainingRolesCount,\n },\n ),\n type: 'success',\n });\n handleCloseConfirmDeletionModal();\n if (remainingRolesCount === 0) {\n navigate(AUTHZ_HOME_PATH);\n }\n },\n onError: (error, retryVariables) => {\n showErrorToast(error, () => runRevokeRole(retryVariables));\n },\n });\n };\n\n runRevokeRole({ data });\n };\n\n return (\n <div className=\"authz-module\">\n <ConfirmDeletionModal\n isOpen={showConfirmDeletionModal}\n close={handleCloseConfirmDeletionModal}\n onSave={handleRevokeUserRole}\n isDeleting={isRevokingUserRolePending}\n context={{\n userName: user?.username || '',\n scope: roleToDelete?.scope || '',\n role: roleToDelete?.role || '',\n name: roleToDelete?.name || '',\n rolesCount: count || 0,\n }}\n />\n <AuthZLayout\n context={{\n id: '',\n org: '',\n title: '',\n }}\n navLinks={navLinks}\n activeLabel={user?.username || ''}\n pageTitle={user?.username || ''}\n pageSubtitle={user?.email || ''}\n actions={\n [\n <AddRoleButton presetUsername={user?.username} key=\"add-role-button\" />,\n ]\n }\n >\n <Container className=\"bg-light-200 p-5\">\n <DataTable\n isPaginated\n isFilterable\n isSortable\n manualPagination\n data={rowsWithPermissions}\n manualFilters\n manualSortBy\n fetchData={fetchData}\n itemCount={count}\n pageCount={pageCount}\n initialState={{ pageSize: TABLE_DEFAULT_PAGE_SIZE }}\n additionalColumns={additionalColumns}\n columns={columns}\n isLoading={isLoadingUserAssignments}\n isExpandable\n renderRowSubComponent={({ row }) => (\n <UserPermissions row={row} />\n )}\n >\n <TableControlBar onFilterChange={setColumnsWithFiltersApplied} />\n <DataTable.Table />\n <TableFooter />\n </DataTable>\n\n </Container>\n </AuthZLayout>\n </div>\n );\n};\n\nexport default AuditUserPage;\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authz-module/audit-user/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useCallback,\n useContext, useEffect, useMemo, useState,\n} from 'react';\nimport { SiteContext, useIntl } from '@openedx/frontend-base';\nimport { DataTable } from '@openedx/paragon';\nimport TableFooter from '@src/authz-module/components/TableFooter/TableFooter';\nimport {\n AUTHZ_HOME_PATH, TABLE_DEFAULT_PAGE_SIZE,\n} from '@src/authz-module/constants';\nimport AuthZLayout from '@src/authz-module/components/AuthZLayout';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport { useUserAccount, useValidateUserPermissionsNonSuspense } from '@src/data/hooks';\nimport { LIBRARY_ROLE_KEYS } from '@src/authz-module/roles-permissions';\nimport { useViewTeamPermissions } from '@src/authz-module/hooks/useViewTeamPermissions';\nimport { getHttpErrorStatus } from '@src/data/utils';\nimport baseMessages from '@src/authz-module/messages';\nimport AddRoleButton from '@src/authz-module/components/AddRoleButton';\nimport {\n OrgCell, RoleCell, ScopeCell, PermissionsCell, ViewAllPermissionsCell,\n createActionsCell,\n} from '@src/authz-module/components/TableCells';\nimport { useQuerySettings } from '@src/authz-module/hooks/useQuerySettings';\nimport { useRevokeUserRoles, useUserAssignedRoles } from '@src/authz-module/data/hooks';\nimport type { RevokeUserRolesRequest } from '@src/authz-module/data/api';\nimport { RoleToDelete } from '@src/types';\nimport { useToastManager } from '@src/components/ToastManager/ToastManagerContext';\nimport UserPermissions from '@src/authz-module/components/UserPermissions';\nimport OrgFilter from '@src/authz-module/components/TableControlBar/OrgFilter';\nimport RolesFilter from '@src/authz-module/components/TableControlBar/RolesFilter';\nimport TableControlBar from '@src/authz-module/components/TableControlBar/TableControlBar';\nimport messages from './messages';\nimport ConfirmDeletionModal from '@src/authz-module/components/ConfirmDeletionModal';\nimport { getCellHeader, getScopeManageActionPermission } from '@src/authz-module/utils';\n\nconst AuditUserPage = () => {\n const { formatMessage } = useIntl();\n const [columnsWithFiltersApplied, setColumnsWithFiltersApplied] = useState<string[]>([]);\n const { username } = useParams();\n const { authenticatedUser } = useContext(SiteContext);\n const navigate = useNavigate();\n const {\n isLoading: isLoadingUser, data: user, isError: isErrorUser, error: errorUser,\n } = useUserAccount(username);\n const { querySettings, handleTableFetch } = useQuerySettings();\n\n const { isCourseViewAllowed } = useViewTeamPermissions();\n\n const effectiveQuerySettings = useMemo(() => {\n if (isCourseViewAllowed || querySettings.roles) return querySettings;\n return { ...querySettings, roles: LIBRARY_ROLE_KEYS };\n }, [isCourseViewAllowed, querySettings]);\n\n const {\n isLoading: isLoadingUserAssignments, data: { results: userAssignments, count } = { results: [], count: 0 },\n } = useUserAssignedRoles(username, effectiveQuerySettings);\n const [roleToDelete, setRoleToDelete] = useState<RoleToDelete | null>(null);\n const [showConfirmDeletionModal, setShowConfirmDeletionModal] = useState(false);\n const {\n showToast, showErrorToast, Bold, Br,\n } = useToastManager();\n const { mutate: revokeUserRoles, isPending: isRevokingUserRolePending } = useRevokeUserRoles();\n\n const deletePermissions = useMemo(() => {\n const uniqueScopes = [...new Set(userAssignments.map(assignment => assignment.scope))];\n return uniqueScopes.map(scope => getScopeManageActionPermission(scope));\n }, [userAssignments]);\n\n const {\n data: permissionsToManageScope,\n } = useValidateUserPermissionsNonSuspense(deletePermissions);\n\n const rowsWithPermissions = useMemo(() => {\n if (!permissionsToManageScope) return userAssignments;\n\n return userAssignments.map(assignment => {\n const canManageScope = permissionsToManageScope.some(\n permission => permission.scope === assignment.scope && permission.allowed,\n );\n return {\n ...assignment,\n canManageScope,\n };\n });\n }, [userAssignments, permissionsToManageScope]);\n\n const fetchData = useMemo(() => handleTableFetch, [handleTableFetch]);\n\n useEffect(() => {\n if (!user && !isLoadingUser) {\n if (!isErrorUser || getHttpErrorStatus(errorUser) === 404) {\n navigate(AUTHZ_HOME_PATH);\n }\n }\n }, [user, isLoadingUser, navigate, isErrorUser, errorUser]);\n\n const handleShowConfirmDeletionModal = useCallback((role: RoleToDelete) => {\n if (isRevokingUserRolePending) return;\n\n setRoleToDelete(role);\n setShowConfirmDeletionModal(true);\n }, [isRevokingUserRolePending]);\n\n const navLinks = useMemo(() => [\n {\n label: formatMessage(baseMessages['authz.management.home.nav.link']),\n to: AUTHZ_HOME_PATH,\n },\n ], [formatMessage]);\n\n const additionalColumns = useMemo(() => [\n {\n id: 'view_permissions',\n Header: '',\n Cell: ViewAllPermissionsCell,\n },\n {\n id: 'action',\n Header: formatMessage(messages['authz.user.table.action.column.header']),\n Cell: createActionsCell({\n onClickDeleteButton: handleShowConfirmDeletionModal,\n isUserAuthenticatedPage: username === authenticatedUser?.username,\n }),\n },\n ], [authenticatedUser?.username, formatMessage, handleShowConfirmDeletionModal, username]);\n\n const columns = useMemo(() => [\n {\n Header: getCellHeader('role', formatMessage(messages['authz.user.table.role.column.header']), columnsWithFiltersApplied),\n accessor: 'role',\n Cell: RoleCell,\n filter: 'includesValue',\n Filter: RolesFilter,\n filterButtonText: formatMessage(messages['authz.user.table.role.column.header']),\n filterOrder: 2,\n },\n {\n Header: getCellHeader('org', formatMessage(messages['authz.user.table.organization.column.header']), columnsWithFiltersApplied),\n accessor: 'org',\n Cell: OrgCell,\n filter: 'includesValue',\n Filter: OrgFilter,\n filterButtonText: formatMessage(messages['authz.user.table.organization.column.header']),\n filterOrder: 1,\n },\n {\n Header: getCellHeader('scope', formatMessage(messages['authz.user.table.scope.column.header']), columnsWithFiltersApplied),\n accessor: 'scope',\n Cell: ScopeCell,\n disableFilters: true,\n\n },\n {\n Header: formatMessage(messages['authz.user.table.permissions.column.header']),\n Cell: PermissionsCell,\n disableFilters: true,\n disableSortBy: true,\n },\n ], [formatMessage, columnsWithFiltersApplied]);\n\n const pageCount = Math.ceil(count / TABLE_DEFAULT_PAGE_SIZE);\n\n const handleCloseConfirmDeletionModal = () => {\n setRoleToDelete(null);\n setShowConfirmDeletionModal(false);\n };\n\n const handleRevokeUserRole = () => {\n if (!user || !roleToDelete) return;\n\n const data = {\n users: user.username,\n role: roleToDelete.role,\n scope: roleToDelete.scope,\n };\n\n const runRevokeRole = (variables: { data: RevokeUserRolesRequest }) => {\n const variablesData = {\n data: {\n ...variables.data,\n querySettings,\n },\n\n };\n revokeUserRoles(variablesData, {\n onSuccess: (response) => {\n const { errors } = response;\n\n if (errors.length) {\n showToast({\n type: 'error',\n message: formatMessage(\n baseMessages['authz.team.toast.default.error.message'],\n { Bold, Br },\n ),\n });\n return;\n }\n\n const remainingRolesCount = count ? count - 1 : 0;\n showToast({\n message: formatMessage(\n baseMessages['authz.team.remove.user.toast.success.description'],\n {\n role: roleToDelete.name ?? roleToDelete.role,\n rolesCount: remainingRolesCount,\n },\n ),\n type: 'success',\n });\n handleCloseConfirmDeletionModal();\n if (remainingRolesCount === 0) {\n navigate(AUTHZ_HOME_PATH);\n }\n },\n onError: (error, retryVariables) => {\n showErrorToast(error, () => runRevokeRole(retryVariables));\n },\n });\n };\n\n runRevokeRole({ data });\n };\n\n return (\n <>\n <ConfirmDeletionModal\n isOpen={showConfirmDeletionModal}\n close={handleCloseConfirmDeletionModal}\n onSave={handleRevokeUserRole}\n isDeleting={isRevokingUserRolePending}\n context={{\n userName: user?.username || '',\n scope: roleToDelete?.scope || '',\n role: roleToDelete?.role || '',\n name: roleToDelete?.name || '',\n rolesCount: count || 0,\n }}\n />\n <AuthZLayout\n navLinks={navLinks}\n activeLabel={user?.username || ''}\n pageTitle={user?.username || ''}\n pageSubtitle={user?.email || ''}\n actions={\n [\n <AddRoleButton presetUsername={user?.username} key=\"add-role-button\" />,\n ]\n }\n showDivider\n >\n <div className=\"page-band py-3\">\n <DataTable\n isPaginated\n isFilterable\n isSortable\n manualPagination\n data={rowsWithPermissions}\n manualFilters\n manualSortBy\n fetchData={fetchData}\n itemCount={count}\n pageCount={pageCount}\n initialState={{ pageSize: TABLE_DEFAULT_PAGE_SIZE }}\n additionalColumns={additionalColumns}\n columns={columns}\n isLoading={isLoadingUserAssignments}\n isExpandable\n renderRowSubComponent={({ row }) => (\n <UserPermissions row={row} />\n )}\n >\n <TableControlBar onFilterChange={setColumnsWithFiltersApplied} />\n <DataTable.Table />\n <TableFooter />\n </DataTable>\n </div>\n </AuthZLayout>\n </>\n );\n};\n\nexport default AuditUserPage;\n"]}
|
|
@@ -2,8 +2,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useIntl } from '@openedx/frontend-base';
|
|
3
3
|
import { Tab, Tabs } from '@openedx/paragon';
|
|
4
4
|
import { useLocation, useSearchParams } from 'react-router-dom';
|
|
5
|
-
import TeamMembersTable from '../team-members
|
|
5
|
+
import { TeamMembersTable } from '../team-members';
|
|
6
6
|
import AddRoleButton from '../components/AddRoleButton';
|
|
7
|
+
import { useViewTeamPermissions } from '../hooks/useViewTeamPermissions';
|
|
8
|
+
import { CustomErrors } from '../../constants';
|
|
9
|
+
import LoadingPage from '../../components/LoadingPage';
|
|
7
10
|
import RolesPermissions from '../roles-permissions/RolesPermissions';
|
|
8
11
|
import AuthZLayout from '../components/AuthZLayout';
|
|
9
12
|
import messages from './messages';
|
|
@@ -17,7 +20,23 @@ const AuthzHome = () => {
|
|
|
17
20
|
*/
|
|
18
21
|
const presetScope = ((_a = searchParams.get('scope')) === null || _a === void 0 ? void 0 : _a.replace(/\s/g, '+')) || undefined;
|
|
19
22
|
const pageTitle = intl.formatMessage(messages['authz.manage.page.title']);
|
|
20
|
-
|
|
23
|
+
const { isCourseViewAllowed, isLibraryViewAllowed, isLoading: isLoadingPermissions, } = useViewTeamPermissions();
|
|
24
|
+
/**
|
|
25
|
+
* It gates the whole page whether the user is allowed to view the team members. If
|
|
26
|
+
* the user is not allowed, an error is thrown to display the access denied message.
|
|
27
|
+
*
|
|
28
|
+
* Rendering is held until the check settles rather than started optimistically, so a
|
|
29
|
+
* user who turns out to be denied never fires the listing and filter requests behind
|
|
30
|
+
* the page. Both flags read false while it is in flight, which would otherwise deny
|
|
31
|
+
* everyone for a frame.
|
|
32
|
+
*/
|
|
33
|
+
if (isLoadingPermissions) {
|
|
34
|
+
return _jsx(LoadingPage, {});
|
|
35
|
+
}
|
|
36
|
+
if (!isCourseViewAllowed && !isLibraryViewAllowed) {
|
|
37
|
+
throw new Error(CustomErrors.NO_ACCESS);
|
|
38
|
+
}
|
|
39
|
+
return (_jsx(AuthZLayout, { pageTitle: pageTitle, actions: [_jsx(AddRoleButton, {}, "add-role-button")], children: _jsxs(Tabs, { variant: "tabs", defaultActiveKey: hash ? 'permissionsRoles' : 'team', className: "page-band bg-light-100", children: [_jsx(Tab, { eventKey: "team", title: intl.formatMessage(messages['authz.tabs.team']), className: "page-band py-3", children: _jsx(TeamMembersTable, { presetScope: presetScope }) }), _jsx(Tab, { id: "libraries-permissions-roles-tab", eventKey: "permissionsRoles", title: intl.formatMessage(messages['authz.tabs.permissionsRoles']), className: "page-band py-3", children: _jsx(RolesPermissions, {}) })] }) }));
|
|
21
40
|
};
|
|
22
41
|
export default AuthzHome;
|
|
23
42
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authz-module/authz-home/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,gBAAgB,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authz-module/authz-home/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,aAAa,MAAM,4CAA4C,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,WAAW,MAAM,6BAA6B,CAAC;AACtD,OAAO,gBAAgB,MAAM,sDAAsD,CAAC;AACpF,OAAO,WAAW,MAAM,0CAA0C,CAAC;AAEnE,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,SAAS,GAAG,GAAG,EAAE;;IACrB,MAAM,EAAE,IAAI,EAAE,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,CAAC,YAAY,CAAC,GAAG,eAAe,EAAE,CAAC;IAEzC;;MAEE;IACF,MAAM,WAAW,GAAG,CAAA,MAAA,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,0CAAE,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,KAAI,SAAS,CAAC;IAEhF,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAE1E,MAAM,EACJ,mBAAmB,EAAE,oBAAoB,EAAE,SAAS,EAAE,oBAAoB,GAC3E,GAAG,sBAAsB,EAAE,CAAC;IAE7B;;;;;;;;OAQG;IACH,IAAI,oBAAoB,EAAE,CAAC;QACzB,OAAO,KAAC,WAAW,KAAG,CAAC;IACzB,CAAC;IAED,IAAI,CAAC,mBAAmB,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,CACL,KAAC,WAAW,IACV,SAAS,EAAE,SAAS,EACpB,OAAO,EACL,CAAC,KAAC,aAAa,MAAK,iBAAiB,CAAG,CAAC,YAG3C,MAAC,IAAI,IACH,OAAO,EAAC,MAAM,EACd,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,EACpD,SAAS,EAAC,wBAAwB,aAElC,KAAC,GAAG,IAAC,QAAQ,EAAC,MAAM,EAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,EAAE,SAAS,EAAC,gBAAgB,YACrG,KAAC,gBAAgB,IAAC,WAAW,EAAE,WAAW,GAAI,GAC1C,EACN,KAAC,GAAG,IAAC,EAAE,EAAC,iCAAiC,EAAC,QAAQ,EAAC,kBAAkB,EAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,6BAA6B,CAAC,CAAC,EAAE,SAAS,EAAC,gBAAgB,YAClK,KAAC,gBAAgB,KAAG,GAChB,IACD,GACK,CACf,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,SAAS,CAAC","sourcesContent":["import { useIntl } from '@openedx/frontend-base';\nimport { Tab, Tabs } from '@openedx/paragon';\nimport { useLocation, useSearchParams } from 'react-router-dom';\nimport { TeamMembersTable } from '@src/authz-module/team-members';\nimport AddRoleButton from '@src/authz-module/components/AddRoleButton';\nimport { useViewTeamPermissions } from '@src/authz-module/hooks/useViewTeamPermissions';\nimport { CustomErrors } from '@src/constants';\nimport LoadingPage from '@src/components/LoadingPage';\nimport RolesPermissions from '@src/authz-module/roles-permissions/RolesPermissions';\nimport AuthZLayout from '@src/authz-module/components/AuthZLayout';\n\nimport messages from './messages';\n\nconst AuthzHome = () => {\n const { hash } = useLocation();\n const intl = useIntl();\n const [searchParams] = useSearchParams();\n\n /* In the authoring repository the scope is encoded but this is to Replace spaces with '+'\n to match URL encoding format in case the 'scope' parameter is provided with spaces instead of '+'\n */\n const presetScope = searchParams.get('scope')?.replace(/\\s/g, '+') || undefined;\n\n const pageTitle = intl.formatMessage(messages['authz.manage.page.title']);\n\n const {\n isCourseViewAllowed, isLibraryViewAllowed, isLoading: isLoadingPermissions,\n } = useViewTeamPermissions();\n\n /**\n * It gates the whole page whether the user is allowed to view the team members. If\n * the user is not allowed, an error is thrown to display the access denied message.\n *\n * Rendering is held until the check settles rather than started optimistically, so a\n * user who turns out to be denied never fires the listing and filter requests behind\n * the page. Both flags read false while it is in flight, which would otherwise deny\n * everyone for a frame.\n */\n if (isLoadingPermissions) {\n return <LoadingPage />;\n }\n\n if (!isCourseViewAllowed && !isLibraryViewAllowed) {\n throw new Error(CustomErrors.NO_ACCESS);\n }\n\n return (\n <AuthZLayout\n pageTitle={pageTitle}\n actions={\n [<AddRoleButton key=\"add-role-button\" />]\n }\n >\n <Tabs\n variant=\"tabs\"\n defaultActiveKey={hash ? 'permissionsRoles' : 'team'}\n className=\"page-band bg-light-100\"\n >\n <Tab eventKey=\"team\" title={intl.formatMessage(messages['authz.tabs.team'])} className=\"page-band py-3\">\n <TeamMembersTable presetScope={presetScope} />\n </Tab>\n <Tab id=\"libraries-permissions-roles-tab\" eventKey=\"permissionsRoles\" title={intl.formatMessage(messages['authz.tabs.permissionsRoles'])} className=\"page-band py-3\">\n <RolesPermissions />\n </Tab>\n </Tabs>\n </AuthZLayout>\n );\n};\n\nexport default AuthzHome;\n"]}
|
|
@@ -16,7 +16,7 @@ const AddRoleButton = ({ presetUsername, from }) => {
|
|
|
16
16
|
const path = buildWizardPath({ from, users: presetUsername });
|
|
17
17
|
navigate(path);
|
|
18
18
|
};
|
|
19
|
-
return (canAssignRole ? (_jsx(Button, { iconBefore: Plus, onClick: handleClick, children: intl.formatMessage(baseMessages['authz.management.assign.role.title']) })) : null);
|
|
19
|
+
return (canAssignRole ? (_jsx(Button, { size: "sm", iconBefore: Plus, onClick: handleClick, children: intl.formatMessage(baseMessages['authz.management.assign.role.title']) })) : null);
|
|
20
20
|
};
|
|
21
21
|
export default AddRoleButton;
|
|
22
22
|
//# sourceMappingURL=AddRoleButton.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AddRoleButton.js","sourceRoot":"","sources":["../../../src/authz-module/components/AddRoleButton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,YAAY,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,qCAAqC,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAO9E,MAAM,aAAa,GAAG,CAAC,EAAE,cAAc,EAAE,IAAI,EAAsB,EAAE,EAAE;IACrE,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAE/B,MAAM,EAAE,IAAI,EAAE,4BAA4B,EAAE,GAAG,qCAAqC,CAAC,uBAAuB,CAAC,CAAC;IAC9G,MAAM,aAAa,GAAG,4BAA4B,aAA5B,4BAA4B,uBAA5B,4BAA4B,CAAE,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAE7F,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,MAAM,IAAI,GAAG,eAAe,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QAC9D,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC,CAAC;IAEF,OAAO,CACL,aAAa,CAAC,CAAC,CAAC,CACd,KAAC,MAAM,IACL,UAAU,EAAE,IAAI,EAChB,OAAO,EAAE,WAAW,YAEnB,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,oCAAoC,CAAC,CAAC,GAChE,CACV,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACd,CAAC,CAAC;AAEF,eAAe,aAAa,CAAC","sourcesContent":["import { useIntl } from '@openedx/frontend-base';\nimport { Button } from '@openedx/paragon';\nimport { Plus } from '@openedx/paragon/icons';\nimport { useNavigate } from 'react-router-dom';\n\nimport baseMessages from '@src/authz-module/messages';\nimport { buildWizardPath } from '@src/authz-module/constants';\nimport { useValidateUserPermissionsNonSuspense } from '@src/data/hooks';\nimport { MANAGE_TEAM_PERMISSIONS } from '@src/authz-module/roles-permissions';\n\ninterface AddRoleButtonProps {\n presetUsername?: string;\n from?: string;\n}\n\nconst AddRoleButton = ({ presetUsername, from }: AddRoleButtonProps) => {\n const intl = useIntl();\n const navigate = useNavigate();\n\n const { data: permissionValidationResponse } = useValidateUserPermissionsNonSuspense(MANAGE_TEAM_PERMISSIONS);\n const canAssignRole = permissionValidationResponse?.some((permission) => permission.allowed);\n\n const handleClick = () => {\n const path = buildWizardPath({ from, users: presetUsername });\n navigate(path);\n };\n\n return (\n canAssignRole ? (\n <Button\n iconBefore={Plus}\n onClick={handleClick}\n >\n {intl.formatMessage(baseMessages['authz.management.assign.role.title'])}\n </Button>\n ) : null);\n};\n\nexport default AddRoleButton;\n"]}
|
|
1
|
+
{"version":3,"file":"AddRoleButton.js","sourceRoot":"","sources":["../../../src/authz-module/components/AddRoleButton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,YAAY,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,qCAAqC,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAO9E,MAAM,aAAa,GAAG,CAAC,EAAE,cAAc,EAAE,IAAI,EAAsB,EAAE,EAAE;IACrE,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAE/B,MAAM,EAAE,IAAI,EAAE,4BAA4B,EAAE,GAAG,qCAAqC,CAAC,uBAAuB,CAAC,CAAC;IAC9G,MAAM,aAAa,GAAG,4BAA4B,aAA5B,4BAA4B,uBAA5B,4BAA4B,CAAE,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAE7F,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,MAAM,IAAI,GAAG,eAAe,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QAC9D,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC,CAAC;IAEF,OAAO,CACL,aAAa,CAAC,CAAC,CAAC,CACd,KAAC,MAAM,IACL,IAAI,EAAC,IAAI,EACT,UAAU,EAAE,IAAI,EAChB,OAAO,EAAE,WAAW,YAEnB,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,oCAAoC,CAAC,CAAC,GAChE,CACV,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACd,CAAC,CAAC;AAEF,eAAe,aAAa,CAAC","sourcesContent":["import { useIntl } from '@openedx/frontend-base';\nimport { Button } from '@openedx/paragon';\nimport { Plus } from '@openedx/paragon/icons';\nimport { useNavigate } from 'react-router-dom';\n\nimport baseMessages from '@src/authz-module/messages';\nimport { buildWizardPath } from '@src/authz-module/constants';\nimport { useValidateUserPermissionsNonSuspense } from '@src/data/hooks';\nimport { MANAGE_TEAM_PERMISSIONS } from '@src/authz-module/roles-permissions';\n\ninterface AddRoleButtonProps {\n presetUsername?: string;\n from?: string;\n}\n\nconst AddRoleButton = ({ presetUsername, from }: AddRoleButtonProps) => {\n const intl = useIntl();\n const navigate = useNavigate();\n\n const { data: permissionValidationResponse } = useValidateUserPermissionsNonSuspense(MANAGE_TEAM_PERMISSIONS);\n const canAssignRole = permissionValidationResponse?.some((permission) => permission.allowed);\n\n const handleClick = () => {\n const path = buildWizardPath({ from, users: presetUsername });\n navigate(path);\n };\n\n return (\n canAssignRole ? (\n <Button\n size=\"sm\"\n iconBefore={Plus}\n onClick={handleClick}\n >\n {intl.formatMessage(baseMessages['authz.management.assign.role.title'])}\n </Button>\n ) : null);\n};\n\nexport default AddRoleButton;\n"]}
|
|
@@ -2,11 +2,12 @@ import { ReactNode } from 'react';
|
|
|
2
2
|
import { AuthZTitleProps } from './AuthZTitle';
|
|
3
3
|
interface AuthZLayoutProps extends AuthZTitleProps {
|
|
4
4
|
children: ReactNode;
|
|
5
|
-
context: {
|
|
6
|
-
id: string;
|
|
7
|
-
org: string;
|
|
8
|
-
title: string;
|
|
9
|
-
};
|
|
10
5
|
}
|
|
11
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Page chrome for the authz module: the title band, then the body below it.
|
|
8
|
+
* The body only paints its colour, edge to edge. Each page marks the parts of its
|
|
9
|
+
* content that should line up with the header using `page-band`, so anything meant
|
|
10
|
+
* to bleed across the full width -- a stepper header, a toolbar -- simply omits it.
|
|
11
|
+
*/
|
|
12
|
+
declare const AuthZLayout: ({ children, ...titleProps }: AuthZLayoutProps) => import("react").JSX.Element;
|
|
12
13
|
export default AuthZLayout;
|
|
@@ -9,11 +9,17 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
9
9
|
}
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
|
-
import { jsx as _jsx,
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
13
|
import AuthZTitle from './AuthZTitle';
|
|
14
|
+
/**
|
|
15
|
+
* Page chrome for the authz module: the title band, then the body below it.
|
|
16
|
+
* The body only paints its colour, edge to edge. Each page marks the parts of its
|
|
17
|
+
* content that should line up with the header using `page-band`, so anything meant
|
|
18
|
+
* to bleed across the full width -- a stepper header, a toolbar -- simply omits it.
|
|
19
|
+
*/
|
|
14
20
|
const AuthZLayout = (_a) => {
|
|
15
|
-
var { children } = _a,
|
|
16
|
-
return (_jsxs(
|
|
21
|
+
var { children } = _a, titleProps = __rest(_a, ["children"]);
|
|
22
|
+
return (_jsxs("div", { className: "authz-module", children: [_jsx(AuthZTitle, Object.assign({}, titleProps)), children] }));
|
|
17
23
|
};
|
|
18
24
|
export default AuthZLayout;
|
|
19
25
|
//# sourceMappingURL=AuthZLayout.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthZLayout.js","sourceRoot":"","sources":["../../../src/authz-module/components/AuthZLayout.tsx"],"names":[],"mappings":";;;;;;;;;;;;AACA,OAAO,UAA+B,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"AuthZLayout.js","sourceRoot":"","sources":["../../../src/authz-module/components/AuthZLayout.tsx"],"names":[],"mappings":";;;;;;;;;;;;AACA,OAAO,UAA+B,MAAM,cAAc,CAAC;AAM3D;;;;;GAKG;AACH,MAAM,WAAW,GAAG,CAAC,EAA6C,EAAE,EAAE;QAAjD,EAAE,QAAQ,OAAmC,EAA9B,UAAU,cAAzB,YAA2B,CAAF;IAAyB,OAAA,CACrE,eAAK,SAAS,EAAC,cAAc,aAC3B,KAAC,UAAU,oBAAK,UAAU,EAAI,EAC7B,QAAQ,IACL,CACP,CAAA;CAAA,CAAC;AAEF,eAAe,WAAW,CAAC","sourcesContent":["import { ReactNode } from 'react';\nimport AuthZTitle, { AuthZTitleProps } from './AuthZTitle';\n\ninterface AuthZLayoutProps extends AuthZTitleProps {\n children: ReactNode;\n}\n\n/**\n * Page chrome for the authz module: the title band, then the body below it.\n * The body only paints its colour, edge to edge. Each page marks the parts of its\n * content that should line up with the header using `page-band`, so anything meant\n * to bleed across the full width -- a stepper header, a toolbar -- simply omits it.\n */\nconst AuthZLayout = ({ children, ...titleProps }: AuthZLayoutProps) => (\n <div className=\"authz-module\">\n <AuthZTitle {...titleProps} />\n {children}\n </div>\n);\n\nexport default AuthZLayout;\n"]}
|
|
@@ -11,10 +11,11 @@ interface Action {
|
|
|
11
11
|
export interface AuthZTitleProps {
|
|
12
12
|
activeLabel?: string;
|
|
13
13
|
pageTitle: string;
|
|
14
|
-
pageSubtitle
|
|
14
|
+
pageSubtitle?: string | ReactNode;
|
|
15
15
|
navLinks?: BreadcrumbLink[];
|
|
16
16
|
actions?: (Action | ReactNode)[];
|
|
17
|
+
showDivider?: boolean;
|
|
17
18
|
}
|
|
18
19
|
export declare const ActionButton: ({ label, icon, onClick }: Action) => import("react").JSX.Element;
|
|
19
|
-
declare const AuthZTitle: ({ activeLabel, navLinks, pageTitle, pageSubtitle, actions, }: AuthZTitleProps) => import("react").JSX.Element;
|
|
20
|
+
declare const AuthZTitle: ({ activeLabel, navLinks, pageTitle, pageSubtitle, actions, showDivider, }: AuthZTitleProps) => import("react").JSX.Element;
|
|
20
21
|
export default AuthZTitle;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { isValidElement, Fragment, } from 'react';
|
|
3
3
|
import { Link } from 'react-router-dom';
|
|
4
|
-
import { Breadcrumb, Col,
|
|
5
|
-
export const ActionButton = ({ label, icon, onClick }) => (_jsx(Button, { iconBefore: icon, onClick: onClick, children: label }));
|
|
6
|
-
const AuthZTitle = ({ activeLabel, navLinks = [], pageTitle, pageSubtitle, actions = [], }) => {
|
|
4
|
+
import { Breadcrumb, Col, Row, Button, Stack, useMediaQuery, breakpoints, } from '@openedx/paragon';
|
|
5
|
+
export const ActionButton = ({ label, icon, onClick }) => (_jsx(Button, { size: "sm", iconBefore: icon, onClick: onClick, children: label }));
|
|
6
|
+
const AuthZTitle = ({ activeLabel, navLinks = [], pageTitle, pageSubtitle, actions = [], showDivider = false, }) => {
|
|
7
|
+
const shouldRenderBreadcrumb = activeLabel || (navLinks === null || navLinks === void 0 ? void 0 : navLinks.length) > 0;
|
|
7
8
|
const isDesktop = useMediaQuery({ minWidth: breakpoints.large.minWidth });
|
|
8
|
-
return (_jsxs(
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
return (_jsxs("div", { className: `page-band py-4 bg-light-100${showDivider ? ' title-border-bottom' : ''}`, children: [shouldRenderBreadcrumb
|
|
10
|
+
&& (_jsx(Breadcrumb, { className: "text-break", linkAs: Link, links: navLinks, activeLabel: activeLabel })), _jsxs(Row, { children: [_jsx(Col, { xs: 12, md: 7, children: _jsxs("div", { className: "d-flex align-items-center flex-column-sm mb-3 mb-md-0", children: [_jsx("h2", { className: "text-break text-primary mb-0", children: pageTitle }), pageSubtitle && (_jsxs(_Fragment, { children: [_jsx("hr", { className: "authz-action-divider mx-lg-3 my-md-0 mx-md-3" }), typeof pageSubtitle === 'string'
|
|
11
|
+
? _jsx("h3", { className: "text-break mb-0 font-weight-light text-gray-700", children: pageSubtitle })
|
|
12
|
+
: _jsx("div", { className: "text-break mb-0", children: pageSubtitle })] }))] }) }), _jsx(Col, { xs: 12, md: 5, children: _jsx(Stack, { className: "justify-content-end", direction: isDesktop ? 'horizontal' : 'vertical', children: actions.map((action, index) => {
|
|
11
13
|
const content = isValidElement(action)
|
|
12
14
|
? action
|
|
13
15
|
: _jsx(ActionButton, Object.assign({}, action));
|
|
@@ -15,7 +17,7 @@ const AuthZTitle = ({ activeLabel, navLinks = [], pageTitle, pageSubtitle, actio
|
|
|
15
17
|
? action.key
|
|
16
18
|
: action.label;
|
|
17
19
|
return (_jsxs(Fragment, { children: [content, (index === actions.length - 1) ? null
|
|
18
|
-
: (_jsx("hr", { className: "mx-lg-5" }))] }, `authz-header-action-${key}`));
|
|
20
|
+
: (_jsx("hr", { className: "authz-action-divider mx-lg-5" }))] }, `authz-header-action-${key}`));
|
|
19
21
|
}) }) })] })] }));
|
|
20
22
|
};
|
|
21
23
|
export default AuthZTitle;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthZTitle.js","sourceRoot":"","sources":["../../../src/authz-module/components/AuthZTitle.tsx"],"names":[],"mappings":";AAAA,OAAO,EACU,cAAc,EAAa,QAAQ,GACnD,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EACL,UAAU,EAAE,GAAG,EAAE,
|
|
1
|
+
{"version":3,"file":"AuthZTitle.js","sourceRoot":"","sources":["../../../src/authz-module/components/AuthZTitle.tsx"],"names":[],"mappings":";AAAA,OAAO,EACU,cAAc,EAAa,QAAQ,GACnD,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EACL,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAC5B,KAAK,EACL,aAAa,EACb,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAsB1B,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAU,EAAE,EAAE,CAAC,CAChE,KAAC,MAAM,IACL,IAAI,EAAC,IAAI,EACT,UAAU,EAAE,IAAI,EAChB,OAAO,EAAE,OAAO,YAEf,KAAK,GACC,CACV,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,EAClB,WAAW,EAAE,QAAQ,GAAG,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,GAAG,EAAE,EAAE,WAAW,GAAG,KAAK,GACtE,EAAE,EAAE;IACpB,MAAM,sBAAsB,GAAG,WAAW,IAAI,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,MAAM,IAAG,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC1E,OAAO,CACL,eAAK,SAAS,EAAE,8BAA8B,WAAW,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE,EAAE,aACrF,sBAAsB;mBACrB,CACD,KAAC,UAAU,IACT,SAAS,EAAC,YAAY,EACtB,MAAM,EAAE,IAAI,EACZ,KAAK,EAAE,QAAQ,EACf,WAAW,EAAE,WAAW,GACxB,CACH,EACD,MAAC,GAAG,eACF,KAAC,GAAG,IAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,YAChB,eAAK,SAAS,EAAC,uDAAuD,aACpE,aAAI,SAAS,EAAC,8BAA8B,YAAE,SAAS,GAAM,EAC5D,YAAY,IAAI,CACf,8BACE,aAAI,SAAS,EAAC,8CAA8C,GAAG,EAC9D,OAAO,YAAY,KAAK,QAAQ;4CAC/B,CAAC,CAAC,aAAI,SAAS,EAAC,iDAAiD,YAAE,YAAY,GAAM;4CACrF,CAAC,CAAC,cAAK,SAAS,EAAC,iBAAiB,YAAE,YAAY,GAAO,IACxD,CACJ,IAEG,GACF,EACN,KAAC,GAAG,IAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,YAChB,KAAC,KAAK,IAAC,SAAS,EAAC,qBAAqB,EAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,YAEnF,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;gCAC5B,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC;oCACpC,CAAC,CAAC,MAAM;oCACR,CAAC,CAAC,KAAC,YAAY,oBAAK,MAAgB,EAAI,CAAC;gCAC3C,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,CAAC;oCAChC,CAAC,CAAC,MAAM,CAAC,GAAG;oCACZ,CAAC,CAAE,MAAiB,CAAC,KAAK,CAAC;gCAC7B,OAAO,CACL,MAAC,QAAQ,eACN,OAAO,EACP,CAAC,KAAK,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;4CACpC,CAAC,CAAC,CAAC,aAAI,SAAS,EAAC,8BAA8B,GAAG,CAAC,KAHxC,uBAAuB,GAAG,EAAE,CAIhC,CACZ,CAAC;4BACJ,CAAC,CAAC,GAEE,GACJ,IACF,IACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,UAAU,CAAC","sourcesContent":["import {\n ComponentType, isValidElement, ReactNode, Fragment,\n} from 'react';\nimport { Link } from 'react-router-dom';\nimport {\n Breadcrumb, Col, Row, Button,\n Stack,\n useMediaQuery,\n breakpoints,\n} from '@openedx/paragon';\n\ninterface BreadcrumbLink {\n label: string;\n to?: string;\n}\n\ninterface Action {\n label: string;\n icon?: ComponentType;\n onClick: () => void;\n}\n\nexport interface AuthZTitleProps {\n activeLabel?: string;\n pageTitle: string;\n pageSubtitle?: string | ReactNode;\n navLinks?: BreadcrumbLink[];\n actions?: (Action | ReactNode)[];\n showDivider?: boolean;\n}\n\nexport const ActionButton = ({ label, icon, onClick }: Action) => (\n <Button\n size=\"sm\"\n iconBefore={icon}\n onClick={onClick}\n >\n {label}\n </Button>\n);\n\nconst AuthZTitle = ({\n activeLabel, navLinks = [], pageTitle, pageSubtitle, actions = [], showDivider = false,\n}: AuthZTitleProps) => {\n const shouldRenderBreadcrumb = activeLabel || navLinks?.length > 0;\n const isDesktop = useMediaQuery({ minWidth: breakpoints.large.minWidth });\n return (\n <div className={`page-band py-4 bg-light-100${showDivider ? ' title-border-bottom' : ''}`}>\n { shouldRenderBreadcrumb\n && (\n <Breadcrumb\n className=\"text-break\"\n linkAs={Link}\n links={navLinks}\n activeLabel={activeLabel}\n />\n )}\n <Row>\n <Col xs={12} md={7}>\n <div className=\"d-flex align-items-center flex-column-sm mb-3 mb-md-0\">\n <h2 className=\"text-break text-primary mb-0\">{pageTitle}</h2>\n {pageSubtitle && (\n <>\n <hr className=\"authz-action-divider mx-lg-3 my-md-0 mx-md-3\" />\n {typeof pageSubtitle === 'string'\n ? <h3 className=\"text-break mb-0 font-weight-light text-gray-700\">{pageSubtitle}</h3>\n : <div className=\"text-break mb-0\">{pageSubtitle}</div>}\n </>\n )}\n\n </div>\n </Col>\n <Col xs={12} md={5}>\n <Stack className=\"justify-content-end\" direction={isDesktop ? 'horizontal' : 'vertical'}>\n {\n actions.map((action, index) => {\n const content = isValidElement(action)\n ? action\n : <ActionButton {...action as Action} />;\n const key = isValidElement(action)\n ? action.key\n : (action as Action).label;\n return (\n <Fragment key={`authz-header-action-${key}`}>\n {content}\n {(index === actions.length - 1) ? null\n : (<hr className=\"authz-action-divider mx-lg-5\" />)}\n </Fragment>\n );\n })\n }\n </Stack>\n </Col>\n </Row>\n </div>\n );\n};\n\nexport default AuthZTitle;\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
interface ExpandableButtonProps {
|
|
2
|
+
label: string;
|
|
3
|
+
onClick: () => void;
|
|
4
|
+
isExpanded: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Link-styled trigger that expands something in place: a table row, a list of items.
|
|
8
|
+
*
|
|
9
|
+
* A real `<button>` rather than an anchor — it navigates nowhere, and an anchor with no
|
|
10
|
+
* `href` is neither focusable nor activatable from the keyboard. `size="inline"` drops the
|
|
11
|
+
* button padding so it keeps sitting on the text baseline inside a table cell.
|
|
12
|
+
*
|
|
13
|
+
* `isExpanded` drives both halves of the state report, which have to agree: the chevron
|
|
14
|
+
* for sighted users and `aria-expanded` for a screen reader.
|
|
15
|
+
*/
|
|
16
|
+
declare const ExpandableButton: ({ label, onClick, isExpanded }: ExpandableButtonProps) => import("react").JSX.Element;
|
|
17
|
+
export default ExpandableButton;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from '@openedx/paragon';
|
|
3
|
+
import { ExpandLess, ExpandMore } from '@openedx/paragon/icons';
|
|
4
|
+
/**
|
|
5
|
+
* Link-styled trigger that expands something in place: a table row, a list of items.
|
|
6
|
+
*
|
|
7
|
+
* A real `<button>` rather than an anchor — it navigates nowhere, and an anchor with no
|
|
8
|
+
* `href` is neither focusable nor activatable from the keyboard. `size="inline"` drops the
|
|
9
|
+
* button padding so it keeps sitting on the text baseline inside a table cell.
|
|
10
|
+
*
|
|
11
|
+
* `isExpanded` drives both halves of the state report, which have to agree: the chevron
|
|
12
|
+
* for sighted users and `aria-expanded` for a screen reader.
|
|
13
|
+
*/
|
|
14
|
+
const ExpandableButton = ({ label, onClick, isExpanded }) => (_jsx(Button, { variant: "link", size: "inline", onClick: onClick, iconAfter: isExpanded ? ExpandLess : ExpandMore, "aria-expanded": isExpanded, children: label }));
|
|
15
|
+
export default ExpandableButton;
|
|
16
|
+
//# sourceMappingURL=ExpandableButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpandableButton.js","sourceRoot":"","sources":["../../../src/authz-module/components/ExpandableButton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAQhE;;;;;;;;;GASG;AACH,MAAM,gBAAgB,GAAG,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAyB,EAAE,EAAE,CAAC,CAClF,KAAC,MAAM,IACL,OAAO,EAAC,MAAM,EACd,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,mBAChC,UAAU,YAExB,KAAK,GACC,CACV,CAAC;AAEF,eAAe,gBAAgB,CAAC","sourcesContent":["import { Button } from '@openedx/paragon';\nimport { ExpandLess, ExpandMore } from '@openedx/paragon/icons';\n\ninterface ExpandableButtonProps {\n label: string;\n onClick: () => void;\n isExpanded: boolean;\n}\n\n/**\n * Link-styled trigger that expands something in place: a table row, a list of items.\n *\n * A real `<button>` rather than an anchor — it navigates nowhere, and an anchor with no\n * `href` is neither focusable nor activatable from the keyboard. `size=\"inline\"` drops the\n * button padding so it keeps sitting on the text baseline inside a table cell.\n *\n * `isExpanded` drives both halves of the state report, which have to agree: the chevron\n * for sighted users and `aria-expanded` for a screen reader.\n */\nconst ExpandableButton = ({ label, onClick, isExpanded }: ExpandableButtonProps) => (\n <Button\n variant=\"link\"\n size=\"inline\"\n onClick={onClick}\n iconAfter={isExpanded ? ExpandLess : ExpandMore}\n aria-expanded={isExpanded}\n >\n {label}\n </Button>\n);\n\nexport default ExpandableButton;\n"]}
|
|
@@ -8,7 +8,11 @@ import ResourceTooltip from './ResourceTooltip';
|
|
|
8
8
|
import messages from './messages';
|
|
9
9
|
const PermissionTable = ({ permissionsTable, roles, title }) => {
|
|
10
10
|
const { formatMessage } = useIntl();
|
|
11
|
-
return (
|
|
11
|
+
return (
|
|
12
|
+
// Only the narrowest viewports are too small for the matrix, so the card scrolls there
|
|
13
|
+
// (see `.permission-table-scroll`). Above that it is not a scroll container, which is
|
|
14
|
+
// what lets the header row stick to the viewport as the page scrolls.
|
|
15
|
+
_jsx(Card, { className: "permission-table-scroll", children: _jsxs("table", { className: "permission-table w-100", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { className: "sticky-top bg-white px-4 py-3", children: title }), roles.map(role => (_jsx("th", { className: `text-center py-3 sticky-top bg-white ${role.disabled ? 'text-gray-200' : ''}`, children: role.disabled ? (_jsx(OverlayTrigger, { placement: "top", overlay: (_jsx(Tooltip, { id: `tooltip-${role.name}`, variant: "light", children: formatMessage(messages['authz.role.card.permission.for.role.status.disabled']) })), children: _jsx("span", { style: { cursor: 'help' }, children: role.name }) })) : (role.name) }, role.name)))] }) }), _jsx("tbody", { children: permissionsTable.map(resourceGroup => (_jsxs(React.Fragment, { children: [_jsx("tr", { className: "bg-info-100 text-primary", children: _jsx("td", { colSpan: roles.length + 1, className: "text-start py-3 px-4", children: _jsxs("div", { className: "d-flex align-items-center", children: [resourceGroup.icon && _jsx(Icon, { className: "d-inline-block mr-2", size: "xs", src: resourceGroup.icon }), _jsxs("span", { className: "small", children: [" ", _jsx("strong", { children: resourceGroup.label })] }), _jsx(ResourceTooltip, { resourceGroup: resourceGroup })] }) }) }), resourceGroup.permissions.map(permission => (_jsxs("tr", { className: "border-top", children: [_jsxs("td", { className: "text-start d-flex align-items-center small px-4 py-3", children: [_jsx(Icon, { className: "d-inline-block mr-2", size: "sm", src: actionsDictionary[permission.actionKey] }), permission.label] }), roles.map(role => (_jsx("td", { className: `text-center ${role.disabled ? 'text-gray-200' : ''}`, children: permission.roles[role.name]
|
|
12
16
|
? (_jsx(Icon, { className: `d-inline-block ${role.disabled ? 'text-gray-200' : 'text-success'}`, src: Check, "aria-label": formatMessage(messages['authz.role.card.permission.for.role.status.granted'], {
|
|
13
17
|
roleName: role.name,
|
|
14
18
|
}), screenReaderText: formatMessage(messages['authz.role.card.permission.for.role.status.granted'], {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PermissionTable.js","sourceRoot":"","sources":["../../../src/authz-module/components/PermissionTable.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EACL,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,GACpC,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAChD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAQlC,MAAM,eAAe,GAAG,CAAC,EAAE,gBAAgB,EAAE,KAAK,EAAE,KAAK,EAAwB,EAAE,EAAE;IACnF,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,OAAO,
|
|
1
|
+
{"version":3,"file":"PermissionTable.js","sourceRoot":"","sources":["../../../src/authz-module/components/PermissionTable.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Check, Close } from '@openedx/paragon/icons';\nimport {\n Card, Icon, OverlayTrigger, Tooltip,\n} from '@openedx/paragon';\nimport { PermissionsResourceGrouped, Role } from '@src/types';\nimport { actionsDictionary } from './RoleCard/constants';\nimport ResourceTooltip from './ResourceTooltip';\nimport messages from './messages';\n\ninterface PermissionTableProps {\n roles: Role[];\n permissionsTable: PermissionsResourceGrouped[];\n title?: string;\n}\n\nconst PermissionTable = ({ permissionsTable, roles, title }: PermissionTableProps) => {\n const { formatMessage } = useIntl();\n return (\n // Only the narrowest viewports are too small for the matrix, so the card scrolls there\n // (see `.permission-table-scroll`). Above that it is not a scroll container, which is\n // what lets the header row stick to the viewport as the page scrolls.\n <Card className=\"permission-table-scroll\">\n <table className=\"permission-table w-100\">\n <thead>\n <tr>\n <th className=\"sticky-top bg-white px-4 py-3\">\n {title}\n </th>\n {roles.map(role => (\n <th\n key={role.name}\n className={`text-center py-3 sticky-top bg-white ${role.disabled ? 'text-gray-200' : ''}`}\n >\n {role.disabled ? (\n <OverlayTrigger\n placement=\"top\"\n overlay={(\n <Tooltip\n id={`tooltip-${role.name}`}\n variant=\"light\"\n >\n {formatMessage(messages['authz.role.card.permission.for.role.status.disabled'])}\n </Tooltip>\n )}\n >\n <span style={{ cursor: 'help' }}>{role.name}</span>\n </OverlayTrigger>\n ) : (\n role.name\n )}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {permissionsTable.map(resourceGroup => (\n <React.Fragment key={resourceGroup.key}>\n <tr className=\"bg-info-100 text-primary\">\n <td colSpan={roles.length + 1} className=\"text-start py-3 px-4\">\n <div className=\"d-flex align-items-center\">\n {resourceGroup.icon && <Icon className=\"d-inline-block mr-2\" size=\"xs\" src={resourceGroup.icon} />}\n <span className=\"small\"> <strong>{resourceGroup.label}</strong></span>\n <ResourceTooltip resourceGroup={resourceGroup} />\n </div>\n </td>\n </tr>\n {resourceGroup.permissions.map(permission => (\n <tr key={permission.key} className=\"border-top\">\n <td className=\"text-start d-flex align-items-center small px-4 py-3\">\n <Icon className=\"d-inline-block mr-2\" size=\"sm\" src={actionsDictionary[permission.actionKey]} />\n {permission.label}\n </td>\n {roles.map(role => (\n <td key={role.name} className={`text-center ${role.disabled ? 'text-gray-200' : ''}`}>\n {\n permission.roles[role.name]\n ? (\n <Icon\n className={`d-inline-block ${role.disabled ? 'text-gray-200' : 'text-success'}`}\n src={Check}\n aria-label={formatMessage(messages['authz.role.card.permission.for.role.status.granted'], {\n roleName: role.name,\n })}\n screenReaderText={formatMessage(messages['authz.role.card.permission.for.role.status.granted'], {\n roleName: role.name,\n })}\n />\n )\n : (\n <Icon\n className={`d-inline-block ${role.disabled ? 'text-gray-200' : 'text-danger'}`}\n src={Close}\n aria-label={formatMessage(messages['authz.role.card.permission.for.role.status.not.granted'], {\n roleName: role.name,\n })}\n screenReaderText={formatMessage(messages['authz.role.card.permission.for.role.status.not.granted'], {\n roleName: role.name,\n })}\n />\n )\n }\n </td>\n ))}\n </tr>\n ))}\n </React.Fragment>\n ))}\n </tbody>\n </table>\n </Card>\n );\n};\n\nexport default PermissionTable;\n"]}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { UserRoleWithPermissions, RoleToDelete } from '../../types';
|
|
2
|
-
import { type
|
|
3
|
-
|
|
4
|
-
isCourseEnabled: (scope: string) => boolean;
|
|
5
|
-
}
|
|
2
|
+
import { type ComponentProps } from 'react';
|
|
3
|
+
import { IconButton, type DataTableCellProps } from '@openedx/paragon';
|
|
6
4
|
type CellProps = DataTableCellProps<UserRoleWithPermissions>;
|
|
7
5
|
type CellPropsWithValue = CellProps & {
|
|
8
6
|
value: string;
|
|
@@ -15,15 +13,13 @@ type ExtendedCellProps = CellPropsWithValue & {
|
|
|
15
13
|
interface ActionsCellExtraProps {
|
|
16
14
|
onClickDeleteButton: (role: RoleToDelete) => void;
|
|
17
15
|
isUserAuthenticatedPage: boolean;
|
|
18
|
-
isCourseEnabled?: (scope: string) => boolean;
|
|
19
16
|
}
|
|
20
|
-
|
|
21
|
-
declare const
|
|
22
|
-
declare const createViewActionCell: (extraProps: ViewActionCellExtraProps) => (cellProps: any) => import("react").JSX.Element;
|
|
17
|
+
type DisabledCourseActionButtonProps = Pick<ComponentProps<typeof IconButton>, 'src' | 'alt' | 'size' | 'variant'>;
|
|
18
|
+
export declare const DisabledCourseActionButton: ({ src, alt, size, variant, }: DisabledCourseActionButtonProps) => import("react").JSX.Element;
|
|
23
19
|
declare const OrgCell: ({ value, row }: CellPropsWithValue) => import("react").JSX.Element;
|
|
24
20
|
declare const ScopeCell: ({ row }: CellProps) => import("react").JSX.Element;
|
|
25
21
|
declare const RoleCell: ({ value, cell }: ExtendedCellProps) => import("react").JSX.Element;
|
|
26
22
|
declare const PermissionsCell: ({ row }: CellProps) => import("react").JSX.Element;
|
|
27
23
|
declare const ViewAllPermissionsCell: ({ row }: CellProps) => import("react").JSX.Element;
|
|
28
24
|
declare const createActionsCell: (extraProps: ActionsCellExtraProps) => (cellProps: any) => import("react").JSX.Element;
|
|
29
|
-
export {
|
|
25
|
+
export { RoleCell, OrgCell, ScopeCell, PermissionsCell, ViewAllPermissionsCell, createActionsCell, };
|