@openedx/frontend-app-admin-console 1.0.0-alpha.0
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/LICENSE +661 -0
- package/README.rst +164 -0
- package/dist/Main.d.ts +3 -0
- package/dist/Main.js +15 -0
- package/dist/Main.js.map +1 -0
- package/dist/app.d.ts +3 -0
- package/dist/app.js +10 -0
- package/dist/app.js.map +1 -0
- package/dist/authz-module/audit-user/index.d.ts +2 -0
- package/dist/authz-module/audit-user/index.js +191 -0
- package/dist/authz-module/audit-user/index.js.map +1 -0
- package/dist/authz-module/audit-user/messages.d.ts +58 -0
- package/dist/authz-module/audit-user/messages.js +60 -0
- package/dist/authz-module/audit-user/messages.js.map +1 -0
- package/dist/authz-module/authz-home/index.d.ts +2 -0
- package/dist/authz-module/authz-home/index.js +23 -0
- package/dist/authz-module/authz-home/index.js.map +1 -0
- package/dist/authz-module/authz-home/messages.d.ts +23 -0
- package/dist/authz-module/authz-home/messages.js +25 -0
- package/dist/authz-module/authz-home/messages.js.map +1 -0
- package/dist/authz-module/components/AddRoleButton.d.ts +6 -0
- package/dist/authz-module/components/AddRoleButton.js +22 -0
- package/dist/authz-module/components/AddRoleButton.js.map +1 -0
- package/dist/authz-module/components/AnchorButton.d.ts +2 -0
- package/dist/authz-module/components/AnchorButton.js +35 -0
- package/dist/authz-module/components/AnchorButton.js.map +1 -0
- package/dist/authz-module/components/AuthZLayout.d.ts +12 -0
- package/dist/authz-module/components/AuthZLayout.js +19 -0
- package/dist/authz-module/components/AuthZLayout.js.map +1 -0
- package/dist/authz-module/components/AuthZTitle.d.ts +20 -0
- package/dist/authz-module/components/AuthZTitle.js +22 -0
- package/dist/authz-module/components/AuthZTitle.js.map +1 -0
- package/dist/authz-module/components/ConfirmDeletionModal.d.ts +15 -0
- package/dist/authz-module/components/ConfirmDeletionModal.js +21 -0
- package/dist/authz-module/components/ConfirmDeletionModal.js.map +1 -0
- package/dist/authz-module/components/ErrorPage/index.d.ts +3 -0
- package/dist/authz-module/components/ErrorPage/index.js +59 -0
- package/dist/authz-module/components/ErrorPage/index.js.map +1 -0
- package/dist/authz-module/components/ErrorPage/messages.d.ts +53 -0
- package/dist/authz-module/components/ErrorPage/messages.js +55 -0
- package/dist/authz-module/components/ErrorPage/messages.js.map +1 -0
- package/dist/authz-module/components/PermissionTable.d.ts +9 -0
- package/dist/authz-module/components/PermissionTable.js +24 -0
- package/dist/authz-module/components/PermissionTable.js.map +1 -0
- package/dist/authz-module/components/RenderAdminRole.d.ts +5 -0
- package/dist/authz-module/components/RenderAdminRole.js +13 -0
- package/dist/authz-module/components/RenderAdminRole.js.map +1 -0
- package/dist/authz-module/components/RenderPermissionColumn.d.ts +6 -0
- package/dist/authz-module/components/RenderPermissionColumn.js +8 -0
- package/dist/authz-module/components/RenderPermissionColumn.js.map +1 -0
- package/dist/authz-module/components/RenderPermissionInLine.d.ts +6 -0
- package/dist/authz-module/components/RenderPermissionInLine.js +8 -0
- package/dist/authz-module/components/RenderPermissionInLine.js.map +1 -0
- package/dist/authz-module/components/ResourceTooltip.d.ts +11 -0
- package/dist/authz-module/components/ResourceTooltip.js +9 -0
- package/dist/authz-module/components/ResourceTooltip.js.map +1 -0
- package/dist/authz-module/components/RoleCard/constants.d.ts +14 -0
- package/dist/authz-module/components/RoleCard/constants.js +15 -0
- package/dist/authz-module/components/RoleCard/constants.js.map +1 -0
- package/dist/authz-module/components/RoleCard/messages.d.ts +73 -0
- package/dist/authz-module/components/RoleCard/messages.js +75 -0
- package/dist/authz-module/components/RoleCard/messages.js.map +1 -0
- package/dist/authz-module/components/TableCells.d.ts +29 -0
- package/dist/authz-module/components/TableCells.js +137 -0
- package/dist/authz-module/components/TableCells.js.map +1 -0
- package/dist/authz-module/components/TableControlBar/MultipleChoiceFilter.d.ts +3 -0
- package/dist/authz-module/components/TableControlBar/MultipleChoiceFilter.js +47 -0
- package/dist/authz-module/components/TableControlBar/MultipleChoiceFilter.js.map +1 -0
- package/dist/authz-module/components/TableControlBar/OrgFilter.d.ts +5 -0
- package/dist/authz-module/components/TableControlBar/OrgFilter.js +36 -0
- package/dist/authz-module/components/TableControlBar/OrgFilter.js.map +1 -0
- package/dist/authz-module/components/TableControlBar/RolesFilter.d.ts +4 -0
- package/dist/authz-module/components/TableControlBar/RolesFilter.js +29 -0
- package/dist/authz-module/components/TableControlBar/RolesFilter.js.map +1 -0
- package/dist/authz-module/components/TableControlBar/ScopesFilter.d.ts +4 -0
- package/dist/authz-module/components/TableControlBar/ScopesFilter.js +45 -0
- package/dist/authz-module/components/TableControlBar/ScopesFilter.js.map +1 -0
- package/dist/authz-module/components/TableControlBar/SearchFilter.d.ts +7 -0
- package/dist/authz-module/components/TableControlBar/SearchFilter.js +8 -0
- package/dist/authz-module/components/TableControlBar/SearchFilter.js.map +1 -0
- package/dist/authz-module/components/TableControlBar/TableControlBar.d.ts +5 -0
- package/dist/authz-module/components/TableControlBar/TableControlBar.js +99 -0
- package/dist/authz-module/components/TableControlBar/TableControlBar.js.map +1 -0
- package/dist/authz-module/components/TableControlBar/types.d.ts +18 -0
- package/dist/authz-module/components/TableControlBar/types.js +2 -0
- package/dist/authz-module/components/TableControlBar/types.js.map +1 -0
- package/dist/authz-module/components/TableFooter/TableFooter.d.ts +2 -0
- package/dist/authz-module/components/TableFooter/TableFooter.js +15 -0
- package/dist/authz-module/components/TableFooter/TableFooter.js.map +1 -0
- package/dist/authz-module/components/UserPermissions.d.ts +9 -0
- package/dist/authz-module/components/UserPermissions.js +56 -0
- package/dist/authz-module/components/UserPermissions.js.map +1 -0
- package/dist/authz-module/components/ViewMoreLink.d.ts +8 -0
- package/dist/authz-module/components/ViewMoreLink.js +8 -0
- package/dist/authz-module/components/ViewMoreLink.js.map +1 -0
- package/dist/authz-module/components/constants.d.ts +13 -0
- package/dist/authz-module/components/constants.js +80 -0
- package/dist/authz-module/components/constants.js.map +1 -0
- package/dist/authz-module/components/messages.d.ts +183 -0
- package/dist/authz-module/components/messages.js +185 -0
- package/dist/authz-module/components/messages.js.map +1 -0
- package/dist/authz-module/constants.d.ts +38 -0
- package/dist/authz-module/constants.js +77 -0
- package/dist/authz-module/constants.js.map +1 -0
- package/dist/authz-module/data/api.d.ts +109 -0
- package/dist/authz-module/data/api.js +107 -0
- package/dist/authz-module/data/api.js.map +1 -0
- package/dist/authz-module/data/hooks.d.ts +94 -0
- package/dist/authz-module/data/hooks.js +191 -0
- package/dist/authz-module/data/hooks.js.map +1 -0
- package/dist/authz-module/hooks/useCourseAuthoringFlag.d.ts +26 -0
- package/dist/authz-module/hooks/useCourseAuthoringFlag.js +86 -0
- package/dist/authz-module/hooks/useCourseAuthoringFlag.js.map +1 -0
- package/dist/authz-module/hooks/useQuerySettings.d.ts +27 -0
- package/dist/authz-module/hooks/useQuerySettings.js +72 -0
- package/dist/authz-module/hooks/useQuerySettings.js.map +1 -0
- package/dist/authz-module/hooks/useViewTeamPermissions.d.ts +5 -0
- package/dist/authz-module/hooks/useViewTeamPermissions.js +13 -0
- package/dist/authz-module/hooks/useViewTeamPermissions.js.map +1 -0
- package/dist/authz-module/index.d.ts +3 -0
- package/dist/authz-module/index.js +20 -0
- package/dist/authz-module/index.js.map +1 -0
- package/dist/authz-module/index.scss +131 -0
- package/dist/authz-module/messages.d.ts +48 -0
- package/dist/authz-module/messages.js +50 -0
- package/dist/authz-module/messages.js.map +1 -0
- package/dist/authz-module/role-assignation-wizard/AssignRoleWizard.d.ts +8 -0
- package/dist/authz-module/role-assignation-wizard/AssignRoleWizard.js +154 -0
- package/dist/authz-module/role-assignation-wizard/AssignRoleWizard.js.map +1 -0
- package/dist/authz-module/role-assignation-wizard/AssignRoleWizardPage.d.ts +2 -0
- package/dist/authz-module/role-assignation-wizard/AssignRoleWizardPage.js +39 -0
- package/dist/authz-module/role-assignation-wizard/AssignRoleWizardPage.js.map +1 -0
- package/dist/authz-module/role-assignation-wizard/components/DefineApplicationScopeStep.d.ts +8 -0
- package/dist/authz-module/role-assignation-wizard/components/DefineApplicationScopeStep.js +39 -0
- package/dist/authz-module/role-assignation-wizard/components/DefineApplicationScopeStep.js.map +1 -0
- package/dist/authz-module/role-assignation-wizard/components/HighlightedUsersInput.d.ts +11 -0
- package/dist/authz-module/role-assignation-wizard/components/HighlightedUsersInput.js +36 -0
- package/dist/authz-module/role-assignation-wizard/components/HighlightedUsersInput.js.map +1 -0
- package/dist/authz-module/role-assignation-wizard/components/OrgSection.d.ts +10 -0
- package/dist/authz-module/role-assignation-wizard/components/OrgSection.js +14 -0
- package/dist/authz-module/role-assignation-wizard/components/OrgSection.js.map +1 -0
- package/dist/authz-module/role-assignation-wizard/components/ScopeCheckboxItem.d.ts +8 -0
- package/dist/authz-module/role-assignation-wizard/components/ScopeCheckboxItem.js +5 -0
- package/dist/authz-module/role-assignation-wizard/components/ScopeCheckboxItem.js.map +1 -0
- package/dist/authz-module/role-assignation-wizard/components/ScopeFilterBar.d.ts +12 -0
- package/dist/authz-module/role-assignation-wizard/components/ScopeFilterBar.js +12 -0
- package/dist/authz-module/role-assignation-wizard/components/ScopeFilterBar.js.map +1 -0
- package/dist/authz-module/role-assignation-wizard/components/ScopeList.d.ts +20 -0
- package/dist/authz-module/role-assignation-wizard/components/ScopeList.js +30 -0
- package/dist/authz-module/role-assignation-wizard/components/ScopeList.js.map +1 -0
- package/dist/authz-module/role-assignation-wizard/components/SelectUsersAndRoleStep.d.ts +12 -0
- package/dist/authz-module/role-assignation-wizard/components/SelectUsersAndRoleStep.js +34 -0
- package/dist/authz-module/role-assignation-wizard/components/SelectUsersAndRoleStep.js.map +1 -0
- package/dist/authz-module/role-assignation-wizard/constants.d.ts +5 -0
- package/dist/authz-module/role-assignation-wizard/constants.js +6 -0
- package/dist/authz-module/role-assignation-wizard/constants.js.map +1 -0
- package/dist/authz-module/role-assignation-wizard/hooks/useScopeListData.d.ts +23 -0
- package/dist/authz-module/role-assignation-wizard/hooks/useScopeListData.js +112 -0
- package/dist/authz-module/role-assignation-wizard/hooks/useScopeListData.js.map +1 -0
- package/dist/authz-module/role-assignation-wizard/hooks/useScopePermissions.d.ts +10 -0
- package/dist/authz-module/role-assignation-wizard/hooks/useScopePermissions.js +54 -0
- package/dist/authz-module/role-assignation-wizard/hooks/useScopePermissions.js.map +1 -0
- package/dist/authz-module/role-assignation-wizard/messages.d.ts +243 -0
- package/dist/authz-module/role-assignation-wizard/messages.js +258 -0
- package/dist/authz-module/role-assignation-wizard/messages.js.map +1 -0
- package/dist/authz-module/role-assignation-wizard/utils.d.ts +5 -0
- package/dist/authz-module/role-assignation-wizard/utils.js +16 -0
- package/dist/authz-module/role-assignation-wizard/utils.js.map +1 -0
- package/dist/authz-module/roles-permissions/RolesPermissions.d.ts +2 -0
- package/dist/authz-module/roles-permissions/RolesPermissions.js +35 -0
- package/dist/authz-module/roles-permissions/RolesPermissions.js.map +1 -0
- package/dist/authz-module/roles-permissions/course/constants.d.ts +39 -0
- package/dist/authz-module/roles-permissions/course/constants.js +474 -0
- package/dist/authz-module/roles-permissions/course/constants.js.map +1 -0
- package/dist/authz-module/roles-permissions/index.d.ts +10 -0
- package/dist/authz-module/roles-permissions/index.js +15 -0
- package/dist/authz-module/roles-permissions/index.js.map +1 -0
- package/dist/authz-module/roles-permissions/library/constants.d.ts +18 -0
- package/dist/authz-module/roles-permissions/library/constants.js +193 -0
- package/dist/authz-module/roles-permissions/library/constants.js.map +1 -0
- package/dist/authz-module/roles-permissions/messages.d.ts +63 -0
- package/dist/authz-module/roles-permissions/messages.js +65 -0
- package/dist/authz-module/roles-permissions/messages.js.map +1 -0
- package/dist/authz-module/roles-permissions/utils.d.ts +41 -0
- package/dist/authz-module/roles-permissions/utils.js +70 -0
- package/dist/authz-module/roles-permissions/utils.js.map +1 -0
- package/dist/authz-module/team-members/TeamMembersTable.d.ts +5 -0
- package/dist/authz-module/team-members/TeamMembersTable.js +107 -0
- package/dist/authz-module/team-members/TeamMembersTable.js.map +1 -0
- package/dist/authz-module/team-members/messages.d.ts +33 -0
- package/dist/authz-module/team-members/messages.js +35 -0
- package/dist/authz-module/team-members/messages.js.map +1 -0
- package/dist/authz-module/utils.d.ts +24 -0
- package/dist/authz-module/utils.js +45 -0
- package/dist/authz-module/utils.js.map +1 -0
- package/dist/components/LoadingPage.d.ts +2 -0
- package/dist/components/LoadingPage.js +5 -0
- package/dist/components/LoadingPage.js.map +1 -0
- package/dist/components/ToastManager/ToastManagerContext.d.ts +24 -0
- package/dist/components/ToastManager/ToastManagerContext.js +91 -0
- package/dist/components/ToastManager/ToastManagerContext.js.map +1 -0
- package/dist/constants.d.ts +11 -0
- package/dist/constants.js +15 -0
- package/dist/constants.js.map +1 -0
- package/dist/data/api.d.ts +4 -0
- package/dist/data/api.js +21 -0
- package/dist/data/api.js.map +1 -0
- package/dist/data/hooks.d.ts +38 -0
- package/dist/data/hooks.js +69 -0
- package/dist/data/hooks.js.map +1 -0
- package/dist/data/types.d.ts +38 -0
- package/dist/data/types.js +2 -0
- package/dist/data/types.js.map +1 -0
- package/dist/data/utils.d.ts +6 -0
- package/dist/data/utils.js +11 -0
- package/dist/data/utils.js.map +1 -0
- package/dist/i18n/index.d.ts +1 -0
- package/dist/i18n/index.js +2 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/messages.d.ts +8 -0
- package/dist/messages.js +10 -0
- package/dist/messages.js.map +1 -0
- package/dist/providers.d.ts +3 -0
- package/dist/providers.js +4 -0
- package/dist/providers.js.map +1 -0
- package/dist/routes.d.ts +11 -0
- package/dist/routes.js +16 -0
- package/dist/routes.js.map +1 -0
- package/dist/style.scss +15 -0
- package/dist/types.d.ts +93 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +88 -0
package/README.rst
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
frontend-app-admin-console
|
|
2
|
+
##########################
|
|
3
|
+
|
|
4
|
+
|license-badge| |status-badge| |ci-badge| |codecov-badge|
|
|
5
|
+
|
|
6
|
+
.. |license-badge| image:: https://img.shields.io/github/license/openedx/frontend-app-admin-console.svg
|
|
7
|
+
:target: https://github.com/openedx/frontend-app-admin-console/blob/master/LICENSE
|
|
8
|
+
:alt: License
|
|
9
|
+
|
|
10
|
+
.. |status-badge| image:: https://img.shields.io/badge/Status-Maintained-brightgreen
|
|
11
|
+
|
|
12
|
+
.. |ci-badge| image:: https://github.com/openedx/frontend-app-admin-console/actions/workflows/ci.yml/badge.svg
|
|
13
|
+
:target: https://github.com/openedx/frontend-app-admin-console/actions/workflows/ci.yml
|
|
14
|
+
:alt: Continuous Integration
|
|
15
|
+
|
|
16
|
+
.. |codecov-badge| image:: https://codecov.io/github/openedx/frontend-app-admin-console/coverage.svg?branch=master
|
|
17
|
+
:target: https://codecov.io/github/openedx/frontend-app-admin-console?branch=master
|
|
18
|
+
:alt: Codecov
|
|
19
|
+
|
|
20
|
+
Purpose
|
|
21
|
+
=======
|
|
22
|
+
|
|
23
|
+
The console aims to centralize platform-level settings and administrative tasks—including authorization (AuthZ) and,
|
|
24
|
+
eventually, other key configurations—into a single, extensible UI. It reduces platform fragmentation and improves
|
|
25
|
+
administrator efficiency.
|
|
26
|
+
|
|
27
|
+
Branches and Releases
|
|
28
|
+
=====================
|
|
29
|
+
|
|
30
|
+
This app is published to NPM by ``semantic-release``, and its branches
|
|
31
|
+
follow `OEP-10 ADR 0002`_:
|
|
32
|
+
|
|
33
|
+
``master``
|
|
34
|
+
Unstable. Every merge publishes a prerelease on the ``alpha``
|
|
35
|
+
dist-tag. Breaking changes land here with no DEPR process and no
|
|
36
|
+
warning, so it is not supported in production. All changes, including
|
|
37
|
+
bug fixes, should target this branch first.
|
|
38
|
+
|
|
39
|
+
``stable``
|
|
40
|
+
Carries the newest stable major and owns the ``latest`` dist-tag.
|
|
41
|
+
Changes arrive here as backports from ``master``, and no breaking
|
|
42
|
+
change lands after publication.
|
|
43
|
+
|
|
44
|
+
``n.x`` and ``n.m.x``
|
|
45
|
+
Maintenance branches for majors and minors that ``stable`` has moved
|
|
46
|
+
past. Each owns the dist-tag matching its own name, so consumers
|
|
47
|
+
select a maintained line by semver range, e.g. ``"1.x"``.
|
|
48
|
+
|
|
49
|
+
``stable`` has not been cut yet: until this app is first ready for
|
|
50
|
+
production use, ``master`` and its alphas are all there is. Both
|
|
51
|
+
``.releaserc`` and the ``Release CI`` workflow already know the whole
|
|
52
|
+
layout, including the maintenance branch patterns, so a new line starts
|
|
53
|
+
publishing as soon as it is pushed.
|
|
54
|
+
|
|
55
|
+
This repository is no longer branched or tagged for Open edX releases in
|
|
56
|
+
its own right. It participates by published version instead, per
|
|
57
|
+
`OEP-10 ADR 0003`_.
|
|
58
|
+
|
|
59
|
+
The micro-frontend this app replaces goes on living on `legacy-mfe`_,
|
|
60
|
+
which is where any further ``release/RELEASENAME`` branches for it are
|
|
61
|
+
cut, for as long as a supported release still ships it. Ulmo and
|
|
62
|
+
Verawood both do.
|
|
63
|
+
|
|
64
|
+
.. _OEP-10 ADR 0002: https://docs.openedx.org/projects/openedx-proposals/en/latest/processes/oep-0010/decisions/0002-frontend-stable-branches.html
|
|
65
|
+
.. _OEP-10 ADR 0003: https://docs.openedx.org/projects/openedx-proposals/en/latest/processes/oep-0010/decisions/0003-frontend-release-strategy.html
|
|
66
|
+
.. _legacy-mfe: https://github.com/openedx/frontend-app-admin-console/tree/legacy-mfe
|
|
67
|
+
|
|
68
|
+
Getting Started
|
|
69
|
+
===============
|
|
70
|
+
|
|
71
|
+
A running Open edX instance is needed to serve this app's backend APIs.
|
|
72
|
+
`Tutor`_ in development mode is the usual choice, and
|
|
73
|
+
``site.config.dev.tsx`` already points at its default hostnames.
|
|
74
|
+
|
|
75
|
+
Unlike a micro-frontend, this app is neither built nor served by
|
|
76
|
+
``tutor-mfe``. Install dependencies with ``npm ci`` (using the Node
|
|
77
|
+
version in ``.nvmrc``), then start the dev server on the host with
|
|
78
|
+
``npm run dev``; it serves the app at
|
|
79
|
+
`http://apps.local.openedx.io:2025/admin-console <http://apps.local.openedx.io:2025/admin-console>`_.
|
|
80
|
+
|
|
81
|
+
.. _Tutor: https://github.com/overhangio/tutor
|
|
82
|
+
|
|
83
|
+
Configuration
|
|
84
|
+
-------------
|
|
85
|
+
This repository works with `openedx-authz <https://github.com/openedx/openedx-authz>`_
|
|
86
|
+
|
|
87
|
+
Plugins
|
|
88
|
+
=======
|
|
89
|
+
This frontend app can be customized using the `<Slot />` component from `frontend-base <https://github.com/openedx/frontend-base>`_. See the `slot naming and lifecycle ADR <https://github.com/openedx/frontend-base/blob/main/docs/decisions/0009-slot-naming-and-lifecycle.rst>`_ for the slot API and conventions.
|
|
90
|
+
|
|
91
|
+
The parts of this frontend app that can be customized in that manner are documented `here </src/slots>`_.
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
Development Roadmap
|
|
95
|
+
===================
|
|
96
|
+
|
|
97
|
+
* `Technical Approach: Console MVP (AuthZ-Scoped, Ulmo Release) <https://openedx.atlassian.net/wiki/x/M4B4MgE>`_.
|
|
98
|
+
* `Administrative Console Long-Term Technical Approach <https://openedx.atlassian.net/wiki/x/AgAwMQE>`_.
|
|
99
|
+
|
|
100
|
+
Getting Help
|
|
101
|
+
============
|
|
102
|
+
|
|
103
|
+
If you're having trouble, we have discussion forums at
|
|
104
|
+
https://discuss.openedx.org where you can connect with others in the community.
|
|
105
|
+
|
|
106
|
+
Our real-time conversations are on Slack. You can request a `Slack
|
|
107
|
+
invitation`_, then join our `community Slack workspace`_. Because this is a
|
|
108
|
+
frontend repository, the best place to discuss it would be in the `#wg-frontend
|
|
109
|
+
channel`_.
|
|
110
|
+
|
|
111
|
+
For anything non-trivial, the best path is to open an issue in this repository
|
|
112
|
+
with as many details about the issue you are facing as you can provide.
|
|
113
|
+
|
|
114
|
+
https://github.com/openedx/frontend-app-admin-console/issues
|
|
115
|
+
|
|
116
|
+
For more information about these options, see the `Getting Help`_ page.
|
|
117
|
+
|
|
118
|
+
.. _Slack invitation: https://openedx.org/slack
|
|
119
|
+
.. _community Slack workspace: https://openedx.slack.com/
|
|
120
|
+
.. _#wg-frontend channel: https://openedx.slack.com/archives/C04BM6YC7A6
|
|
121
|
+
.. _Getting Help: https://openedx.org/getting-help
|
|
122
|
+
|
|
123
|
+
License
|
|
124
|
+
=======
|
|
125
|
+
|
|
126
|
+
The code in this repository is licensed under the AGPLv3 unless otherwise
|
|
127
|
+
noted.
|
|
128
|
+
|
|
129
|
+
Please see `LICENSE <LICENSE>`_ for details.
|
|
130
|
+
|
|
131
|
+
Contributing
|
|
132
|
+
============
|
|
133
|
+
|
|
134
|
+
Contributions are very welcome. Please read `How To Contribute`_ for details.
|
|
135
|
+
|
|
136
|
+
.. _How To Contribute: https://openedx.org/r/how-to-contribute
|
|
137
|
+
|
|
138
|
+
This project is currently accepting all types of contributions, bug fixes,
|
|
139
|
+
security fixes, maintenance work, or new features. However, please make sure
|
|
140
|
+
to have a discussion about your new feature idea with the maintainers prior to
|
|
141
|
+
beginning development to maximize the chances of your change being accepted.
|
|
142
|
+
You can start a conversation by creating a new issue on this repo summarizing
|
|
143
|
+
your idea.
|
|
144
|
+
|
|
145
|
+
The Open edX Code of Conduct
|
|
146
|
+
============================
|
|
147
|
+
|
|
148
|
+
All community members are expected to follow the `Open edX Code of Conduct`_.
|
|
149
|
+
|
|
150
|
+
.. _Open edX Code of Conduct: https://openedx.org/code-of-conduct/
|
|
151
|
+
|
|
152
|
+
People
|
|
153
|
+
======
|
|
154
|
+
|
|
155
|
+
The assigned maintainers for this component and other project details may be
|
|
156
|
+
found in `Backstage`_. Backstage pulls this data from the ``catalog-info.yaml``
|
|
157
|
+
file in this repo.
|
|
158
|
+
|
|
159
|
+
.. _Backstage: https://open-edx-backstage.herokuapp.com/catalog/default/component/frontend-app-admin-console
|
|
160
|
+
|
|
161
|
+
Reporting Security Issues
|
|
162
|
+
=========================
|
|
163
|
+
|
|
164
|
+
Please do not report security issues in public. Email security@openedx.org instead.
|
package/dist/Main.d.ts
ADDED
package/dist/Main.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { CurrentAppProvider, PageWrap, getSiteConfig, useIntl } from '@openedx/frontend-base';
|
|
3
|
+
import { Helmet } from 'react-helmet';
|
|
4
|
+
import { appId } from './constants';
|
|
5
|
+
import messages from './messages';
|
|
6
|
+
import AuthZModule from './authz-module';
|
|
7
|
+
import './style.scss';
|
|
8
|
+
const Main = () => {
|
|
9
|
+
const { formatMessage } = useIntl();
|
|
10
|
+
return (_jsxs(CurrentAppProvider, { appId: appId, children: [_jsx(Helmet, { children: _jsx("title", { children: formatMessage(messages['admin.console.page.title'], {
|
|
11
|
+
siteName: getSiteConfig().siteName,
|
|
12
|
+
}) }) }), _jsx(PageWrap, { children: _jsx(AuthZModule, {}) })] }));
|
|
13
|
+
};
|
|
14
|
+
export default Main;
|
|
15
|
+
//# sourceMappingURL=Main.js.map
|
package/dist/Main.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Main.js","sourceRoot":"","sources":["../src/Main.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAC9F,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,WAAW,MAAM,gBAAgB,CAAC;AACzC,OAAO,cAAc,CAAC;AAEtB,MAAM,IAAI,GAAG,GAAG,EAAE;IAChB,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IAEpC,OAAO,CACL,MAAC,kBAAkB,IAAC,KAAK,EAAE,KAAK,aAC9B,KAAC,MAAM,cACL,0BACG,aAAa,CAAC,QAAQ,CAAC,0BAA0B,CAAC,EAAE;wBACnD,QAAQ,EAAE,aAAa,EAAE,CAAC,QAAQ;qBACnC,CAAC,GACI,GACD,EACT,KAAC,QAAQ,cACP,KAAC,WAAW,KAAG,GACN,IACQ,CACtB,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,IAAI,CAAC","sourcesContent":["import { CurrentAppProvider, PageWrap, getSiteConfig, useIntl } from '@openedx/frontend-base';\nimport { Helmet } from 'react-helmet';\n\nimport { appId } from './constants';\nimport messages from './messages';\nimport AuthZModule from './authz-module';\nimport './style.scss';\n\nconst Main = () => {\n const { formatMessage } = useIntl();\n\n return (\n <CurrentAppProvider appId={appId}>\n <Helmet>\n <title>\n {formatMessage(messages['admin.console.page.title'], {\n siteName: getSiteConfig().siteName,\n })}\n </title>\n </Helmet>\n <PageWrap>\n <AuthZModule />\n </PageWrap>\n </CurrentAppProvider>\n );\n};\n\nexport default Main;\n"]}
|
package/dist/app.d.ts
ADDED
package/dist/app.js
ADDED
package/dist/app.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,SAAS,MAAM,aAAa,CAAC;AAEpC,MAAM,GAAG,GAAQ;IACf,KAAK;IACL,MAAM;IACN,SAAS;CACV,CAAC;AAEF,eAAe,GAAG,CAAC","sourcesContent":["import { App } from '@openedx/frontend-base';\nimport { appId } from './constants';\nimport routes from './routes';\nimport providers from './providers';\n\nconst app: App = {\n appId,\n routes,\n providers,\n};\n\nexport default app;\n"]}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useContext, useEffect, useMemo, useState, } from 'react';
|
|
3
|
+
import { SiteContext, useIntl } from '@openedx/frontend-base';
|
|
4
|
+
import { Container, DataTable, } from '@openedx/paragon';
|
|
5
|
+
import TableFooter from '../components/TableFooter/TableFooter';
|
|
6
|
+
import { AUTHZ_HOME_PATH, TABLE_DEFAULT_PAGE_SIZE, } from '../constants';
|
|
7
|
+
import AuthZLayout from '../components/AuthZLayout';
|
|
8
|
+
import { useNavigate, useParams } from 'react-router-dom';
|
|
9
|
+
import { useUserAccount, useValidateUserPermissionsNonSuspense } from '../../data/hooks';
|
|
10
|
+
import { LIBRARY_ROLE_KEYS } from '../roles-permissions';
|
|
11
|
+
import { useViewTeamPermissions } from '../hooks/useViewTeamPermissions';
|
|
12
|
+
import { getHttpErrorStatus } from '../../data/utils';
|
|
13
|
+
import baseMessages from '../messages';
|
|
14
|
+
import AddRoleButton from '../components/AddRoleButton';
|
|
15
|
+
import { OrgCell, RoleCell, ScopeCell, PermissionsCell, ViewAllPermissionsCell, createActionsCell, } from '../components/TableCells';
|
|
16
|
+
import { useQuerySettings } from '../hooks/useQuerySettings';
|
|
17
|
+
import { useCourseAuthoringFlag } from '../hooks/useCourseAuthoringFlag';
|
|
18
|
+
import { useRevokeUserRoles, useUserAssignedRoles } from '../data/hooks';
|
|
19
|
+
import { useToastManager } from '../../components/ToastManager/ToastManagerContext';
|
|
20
|
+
import UserPermissions from '../components/UserPermissions';
|
|
21
|
+
import OrgFilter from '../components/TableControlBar/OrgFilter';
|
|
22
|
+
import RolesFilter from '../components/TableControlBar/RolesFilter';
|
|
23
|
+
import TableControlBar from '../components/TableControlBar/TableControlBar';
|
|
24
|
+
import messages from './messages';
|
|
25
|
+
import ConfirmDeletionModal from '../components/ConfirmDeletionModal';
|
|
26
|
+
import { getCellHeader, getScopeManageActionPermission } from '../utils';
|
|
27
|
+
const AuditUserPage = () => {
|
|
28
|
+
const { formatMessage } = useIntl();
|
|
29
|
+
const [columnsWithFiltersApplied, setColumnsWithFiltersApplied] = useState([]);
|
|
30
|
+
const { username } = useParams();
|
|
31
|
+
const { authenticatedUser } = useContext(SiteContext);
|
|
32
|
+
const navigate = useNavigate();
|
|
33
|
+
const { isLoading: isLoadingUser, data: user, isError: isErrorUser, error: errorUser, } = useUserAccount(username);
|
|
34
|
+
const { querySettings, handleTableFetch } = useQuerySettings();
|
|
35
|
+
const { isCourseViewAllowed } = useViewTeamPermissions();
|
|
36
|
+
const { isCourseEnabled } = useCourseAuthoringFlag();
|
|
37
|
+
const effectiveQuerySettings = useMemo(() => {
|
|
38
|
+
if (isCourseViewAllowed || querySettings.roles)
|
|
39
|
+
return querySettings;
|
|
40
|
+
return Object.assign(Object.assign({}, querySettings), { roles: LIBRARY_ROLE_KEYS });
|
|
41
|
+
}, [isCourseViewAllowed, querySettings]);
|
|
42
|
+
const { isLoading: isLoadingUserAssignments, data: { results: userAssignments, count } = { results: [], count: 0 }, } = useUserAssignedRoles(username, effectiveQuerySettings);
|
|
43
|
+
const [roleToDelete, setRoleToDelete] = useState(null);
|
|
44
|
+
const [showConfirmDeletionModal, setShowConfirmDeletionModal] = useState(false);
|
|
45
|
+
const { showToast, showErrorToast, Bold, Br, } = useToastManager();
|
|
46
|
+
const { mutate: revokeUserRoles, isPending: isRevokingUserRolePending } = useRevokeUserRoles();
|
|
47
|
+
const deletePermissions = useMemo(() => {
|
|
48
|
+
const uniqueScopes = [...new Set(userAssignments.map(assignment => assignment.scope))];
|
|
49
|
+
return uniqueScopes.map(scope => getScopeManageActionPermission(scope));
|
|
50
|
+
}, [userAssignments]);
|
|
51
|
+
const { data: permissionsToManageScope, } = useValidateUserPermissionsNonSuspense(deletePermissions);
|
|
52
|
+
const rowsWithPermissions = useMemo(() => {
|
|
53
|
+
if (!permissionsToManageScope)
|
|
54
|
+
return userAssignments;
|
|
55
|
+
return userAssignments.map(assignment => {
|
|
56
|
+
const canManageScope = permissionsToManageScope.some(permission => permission.scope === assignment.scope && permission.allowed);
|
|
57
|
+
return Object.assign(Object.assign({}, assignment), { canManageScope });
|
|
58
|
+
});
|
|
59
|
+
}, [userAssignments, permissionsToManageScope]);
|
|
60
|
+
const fetchData = useMemo(() => handleTableFetch, [handleTableFetch]);
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
if (!user && !isLoadingUser) {
|
|
63
|
+
if (!isErrorUser || getHttpErrorStatus(errorUser) === 404) {
|
|
64
|
+
navigate(AUTHZ_HOME_PATH);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}, [user, isLoadingUser, navigate, isErrorUser, errorUser]);
|
|
68
|
+
const handleShowConfirmDeletionModal = useCallback((role) => {
|
|
69
|
+
if (isRevokingUserRolePending)
|
|
70
|
+
return;
|
|
71
|
+
setRoleToDelete(role);
|
|
72
|
+
setShowConfirmDeletionModal(true);
|
|
73
|
+
}, [isRevokingUserRolePending]);
|
|
74
|
+
const navLinks = useMemo(() => [
|
|
75
|
+
{
|
|
76
|
+
label: formatMessage(baseMessages['authz.management.home.nav.link']),
|
|
77
|
+
to: AUTHZ_HOME_PATH,
|
|
78
|
+
},
|
|
79
|
+
], [formatMessage]);
|
|
80
|
+
const additionalColumns = useMemo(() => [
|
|
81
|
+
{
|
|
82
|
+
id: 'view_permissions',
|
|
83
|
+
Header: '',
|
|
84
|
+
Cell: ViewAllPermissionsCell,
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: 'action',
|
|
88
|
+
Header: formatMessage(messages['authz.user.table.action.column.header']),
|
|
89
|
+
Cell: createActionsCell({
|
|
90
|
+
onClickDeleteButton: handleShowConfirmDeletionModal,
|
|
91
|
+
isUserAuthenticatedPage: username === (authenticatedUser === null || authenticatedUser === void 0 ? void 0 : authenticatedUser.username),
|
|
92
|
+
isCourseEnabled,
|
|
93
|
+
}),
|
|
94
|
+
},
|
|
95
|
+
], [authenticatedUser === null || authenticatedUser === void 0 ? void 0 : authenticatedUser.username, formatMessage, handleShowConfirmDeletionModal, username, isCourseEnabled]);
|
|
96
|
+
const columns = useMemo(() => [
|
|
97
|
+
{
|
|
98
|
+
Header: getCellHeader('role', formatMessage(messages['authz.user.table.role.column.header']), columnsWithFiltersApplied),
|
|
99
|
+
accessor: 'role',
|
|
100
|
+
Cell: RoleCell,
|
|
101
|
+
filter: 'includesValue',
|
|
102
|
+
Filter: RolesFilter,
|
|
103
|
+
filterButtonText: formatMessage(messages['authz.user.table.role.column.header']),
|
|
104
|
+
filterOrder: 2,
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
Header: getCellHeader('org', formatMessage(messages['authz.user.table.organization.column.header']), columnsWithFiltersApplied),
|
|
108
|
+
accessor: 'org',
|
|
109
|
+
Cell: OrgCell,
|
|
110
|
+
filter: 'includesValue',
|
|
111
|
+
Filter: OrgFilter,
|
|
112
|
+
filterButtonText: formatMessage(messages['authz.user.table.organization.column.header']),
|
|
113
|
+
filterOrder: 1,
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
Header: getCellHeader('scope', formatMessage(messages['authz.user.table.scope.column.header']), columnsWithFiltersApplied),
|
|
117
|
+
accessor: 'scope',
|
|
118
|
+
Cell: ScopeCell,
|
|
119
|
+
disableFilters: true,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
Header: formatMessage(messages['authz.user.table.permissions.column.header']),
|
|
123
|
+
Cell: PermissionsCell,
|
|
124
|
+
disableFilters: true,
|
|
125
|
+
disableSortBy: true,
|
|
126
|
+
},
|
|
127
|
+
], [formatMessage, columnsWithFiltersApplied]);
|
|
128
|
+
const pageCount = Math.ceil(count / TABLE_DEFAULT_PAGE_SIZE);
|
|
129
|
+
const handleCloseConfirmDeletionModal = () => {
|
|
130
|
+
setRoleToDelete(null);
|
|
131
|
+
setShowConfirmDeletionModal(false);
|
|
132
|
+
};
|
|
133
|
+
const handleRevokeUserRole = () => {
|
|
134
|
+
if (!user || !roleToDelete)
|
|
135
|
+
return;
|
|
136
|
+
const data = {
|
|
137
|
+
users: user.username,
|
|
138
|
+
role: roleToDelete.role,
|
|
139
|
+
scope: roleToDelete.scope,
|
|
140
|
+
};
|
|
141
|
+
const runRevokeRole = (variables) => {
|
|
142
|
+
const variablesData = {
|
|
143
|
+
data: Object.assign(Object.assign({}, variables.data), { querySettings }),
|
|
144
|
+
};
|
|
145
|
+
revokeUserRoles(variablesData, {
|
|
146
|
+
onSuccess: (response) => {
|
|
147
|
+
var _a;
|
|
148
|
+
const { errors } = response;
|
|
149
|
+
if (errors.length) {
|
|
150
|
+
showToast({
|
|
151
|
+
type: 'error',
|
|
152
|
+
message: formatMessage(baseMessages['authz.team.toast.default.error.message'], { Bold, Br }),
|
|
153
|
+
});
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const remainingRolesCount = count ? count - 1 : 0;
|
|
157
|
+
showToast({
|
|
158
|
+
message: formatMessage(baseMessages['authz.team.remove.user.toast.success.description'], {
|
|
159
|
+
role: (_a = roleToDelete.name) !== null && _a !== void 0 ? _a : roleToDelete.role,
|
|
160
|
+
rolesCount: remainingRolesCount,
|
|
161
|
+
}),
|
|
162
|
+
type: 'success',
|
|
163
|
+
});
|
|
164
|
+
handleCloseConfirmDeletionModal();
|
|
165
|
+
if (remainingRolesCount === 0) {
|
|
166
|
+
navigate(AUTHZ_HOME_PATH);
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
onError: (error, retryVariables) => {
|
|
170
|
+
showErrorToast(error, () => runRevokeRole(retryVariables));
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
};
|
|
174
|
+
runRevokeRole({ data });
|
|
175
|
+
};
|
|
176
|
+
return (_jsxs("div", { className: "authz-module", children: [_jsx(ConfirmDeletionModal, { isOpen: showConfirmDeletionModal, close: handleCloseConfirmDeletionModal, onSave: handleRevokeUserRole, isDeleting: isRevokingUserRolePending, context: {
|
|
177
|
+
userName: (user === null || user === void 0 ? void 0 : user.username) || '',
|
|
178
|
+
scope: (roleToDelete === null || roleToDelete === void 0 ? void 0 : roleToDelete.scope) || '',
|
|
179
|
+
role: (roleToDelete === null || roleToDelete === void 0 ? void 0 : roleToDelete.role) || '',
|
|
180
|
+
name: (roleToDelete === null || roleToDelete === void 0 ? void 0 : roleToDelete.name) || '',
|
|
181
|
+
rolesCount: count || 0,
|
|
182
|
+
} }), _jsx(AuthZLayout, { context: {
|
|
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: [
|
|
187
|
+
_jsx(AddRoleButton, { presetUsername: user === null || user === void 0 ? void 0 : user.username }, "add-role-button"),
|
|
188
|
+
], children: _jsx(Container, { className: "bg-light-200 p-5", 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
|
+
};
|
|
190
|
+
export default AuditUserPage;
|
|
191
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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 {\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"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
declare const messages: {
|
|
2
|
+
'authz.user.table.role.column.header': {
|
|
3
|
+
id: string;
|
|
4
|
+
defaultMessage: string;
|
|
5
|
+
description: string;
|
|
6
|
+
};
|
|
7
|
+
'authz.user.table.organization.column.header': {
|
|
8
|
+
id: string;
|
|
9
|
+
defaultMessage: string;
|
|
10
|
+
description: string;
|
|
11
|
+
};
|
|
12
|
+
'authz.user.table.scope.column.header': {
|
|
13
|
+
id: string;
|
|
14
|
+
defaultMessage: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
'authz.user.table.permissions.column.header': {
|
|
18
|
+
id: string;
|
|
19
|
+
defaultMessage: string;
|
|
20
|
+
description: string;
|
|
21
|
+
};
|
|
22
|
+
'authz.user.table.action.column.header': {
|
|
23
|
+
id: string;
|
|
24
|
+
defaultMessage: string;
|
|
25
|
+
description: string;
|
|
26
|
+
};
|
|
27
|
+
'authz.user.table.delete.action.alt': {
|
|
28
|
+
id: string;
|
|
29
|
+
defaultMessage: string;
|
|
30
|
+
description: string;
|
|
31
|
+
};
|
|
32
|
+
'authz.user.table.permissions.available.count': {
|
|
33
|
+
id: string;
|
|
34
|
+
defaultMessage: string;
|
|
35
|
+
description: string;
|
|
36
|
+
};
|
|
37
|
+
'authz.user.table.permissions.total.access': {
|
|
38
|
+
id: string;
|
|
39
|
+
defaultMessage: string;
|
|
40
|
+
description: string;
|
|
41
|
+
};
|
|
42
|
+
'authz.user.table.permissions.partial.access': {
|
|
43
|
+
id: string;
|
|
44
|
+
defaultMessage: string;
|
|
45
|
+
description: string;
|
|
46
|
+
};
|
|
47
|
+
'authz.user.table.permissions.role.admin': {
|
|
48
|
+
id: string;
|
|
49
|
+
defaultMessage: string;
|
|
50
|
+
description: string;
|
|
51
|
+
};
|
|
52
|
+
'authz.user.table.permissions.role.staff': {
|
|
53
|
+
id: string;
|
|
54
|
+
defaultMessage: string;
|
|
55
|
+
description: string;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
export default messages;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { defineMessages } from '@openedx/frontend-base';
|
|
2
|
+
const messages = defineMessages({
|
|
3
|
+
'authz.user.table.role.column.header': {
|
|
4
|
+
id: 'authz.user.table.role.column.header',
|
|
5
|
+
defaultMessage: 'Role',
|
|
6
|
+
description: 'Header for the role column in the user table',
|
|
7
|
+
},
|
|
8
|
+
'authz.user.table.organization.column.header': {
|
|
9
|
+
id: 'authz.user.table.organization.column.header',
|
|
10
|
+
defaultMessage: 'Organization',
|
|
11
|
+
description: 'Header for the organization column in the user table',
|
|
12
|
+
},
|
|
13
|
+
'authz.user.table.scope.column.header': {
|
|
14
|
+
id: 'authz.user.table.scope.column.header',
|
|
15
|
+
defaultMessage: 'Scope',
|
|
16
|
+
description: 'Header for the scope column in the user table',
|
|
17
|
+
},
|
|
18
|
+
'authz.user.table.permissions.column.header': {
|
|
19
|
+
id: 'authz.user.table.permissions.column.header',
|
|
20
|
+
defaultMessage: 'Permissions',
|
|
21
|
+
description: 'Header for the permissions column in the user table',
|
|
22
|
+
},
|
|
23
|
+
'authz.user.table.action.column.header': {
|
|
24
|
+
id: 'authz.user.table.action.column.header',
|
|
25
|
+
defaultMessage: 'Actions',
|
|
26
|
+
description: 'Header for the actions column in the user table',
|
|
27
|
+
},
|
|
28
|
+
'authz.user.table.delete.action.alt': {
|
|
29
|
+
id: 'authz.user.table.delete.action.alt',
|
|
30
|
+
defaultMessage: 'Delete role action',
|
|
31
|
+
description: 'Alt description for delete button',
|
|
32
|
+
},
|
|
33
|
+
'authz.user.table.permissions.available.count': {
|
|
34
|
+
id: 'authz.user.table.permissions.available.count',
|
|
35
|
+
defaultMessage: '{count, plural, one {# permission available} other {# permissions available}}',
|
|
36
|
+
description: 'Text showing the number of permissions available, with proper pluralization',
|
|
37
|
+
},
|
|
38
|
+
'authz.user.table.permissions.total.access': {
|
|
39
|
+
id: 'authz.user.table.permissions.total.access',
|
|
40
|
+
defaultMessage: 'Total access',
|
|
41
|
+
description: 'Label indicating Super Admin has total access to all permissions',
|
|
42
|
+
},
|
|
43
|
+
'authz.user.table.permissions.partial.access': {
|
|
44
|
+
id: 'authz.user.table.permissions.partial.access',
|
|
45
|
+
defaultMessage: 'Partial access',
|
|
46
|
+
description: 'Label indicating Global Staff has partial access to permissions',
|
|
47
|
+
},
|
|
48
|
+
'authz.user.table.permissions.role.admin': {
|
|
49
|
+
id: 'authz.user.table.permissions.role.admin',
|
|
50
|
+
defaultMessage: 'Super Admins have full access to all areas of the platform, including content, settings, and user management. This role is managed at the platform level and cannot be changed from here. To modify it, go to Django Admin.',
|
|
51
|
+
description: 'Description for the permissions of the Super Admin role',
|
|
52
|
+
},
|
|
53
|
+
'authz.user.table.permissions.role.staff': {
|
|
54
|
+
id: 'authz.user.table.permissions.role.staff',
|
|
55
|
+
defaultMessage: 'Global Staff have access to all areas of the platform, similar to Super Admin, but cannot grant or revoke Super Admin or Global Staff roles to other users. This role is managed at the platform level and cannot be changed from here. To modify it, go to Django Admin.',
|
|
56
|
+
description: 'Description for the permissions of the Global Staff role',
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
export default messages;
|
|
60
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/authz-module/audit-user/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAC7B;IACE,qCAAqC,EAAE;QACrC,EAAE,EAAE,qCAAqC;QACzC,cAAc,EAAE,MAAM;QACtB,WAAW,EAAE,8CAA8C;KAC5D;IACD,6CAA6C,EAAE;QAC7C,EAAE,EAAE,6CAA6C;QACjD,cAAc,EAAE,cAAc;QAC9B,WAAW,EAAE,sDAAsD;KACpE;IACD,sCAAsC,EAAE;QACtC,EAAE,EAAE,sCAAsC;QAC1C,cAAc,EAAE,OAAO;QACvB,WAAW,EAAE,+CAA+C;KAC7D;IACD,4CAA4C,EAAE;QAC5C,EAAE,EAAE,4CAA4C;QAChD,cAAc,EAAE,aAAa;QAC7B,WAAW,EAAE,qDAAqD;KACnE;IACD,uCAAuC,EAAE;QACvC,EAAE,EAAE,uCAAuC;QAC3C,cAAc,EAAE,SAAS;QACzB,WAAW,EAAE,iDAAiD;KAC/D;IACD,oCAAoC,EAAE;QACpC,EAAE,EAAE,oCAAoC;QACxC,cAAc,EAAE,oBAAoB;QACpC,WAAW,EAAE,mCAAmC;KACjD;IACD,8CAA8C,EAAE;QAC9C,EAAE,EAAE,8CAA8C;QAClD,cAAc,EAAE,+EAA+E;QAC/F,WAAW,EAAE,6EAA6E;KAC3F;IACD,2CAA2C,EAAE;QAC3C,EAAE,EAAE,2CAA2C;QAC/C,cAAc,EAAE,cAAc;QAC9B,WAAW,EAAE,kEAAkE;KAChF;IACD,6CAA6C,EAAE;QAC7C,EAAE,EAAE,6CAA6C;QACjD,cAAc,EAAE,gBAAgB;QAChC,WAAW,EAAE,iEAAiE;KAC/E;IACD,yCAAyC,EAAE;QACzC,EAAE,EAAE,yCAAyC;QAC7C,cAAc,EAAE,6NAA6N;QAC7O,WAAW,EAAE,yDAAyD;KACvE;IACD,yCAAyC,EAAE;QACzC,EAAE,EAAE,yCAAyC;QAC7C,cAAc,EAAE,2QAA2Q;QAC3R,WAAW,EAAE,0DAA0D;KACxE;CACF,CACF,CAAC;AAEF,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages(\n {\n 'authz.user.table.role.column.header': {\n id: 'authz.user.table.role.column.header',\n defaultMessage: 'Role',\n description: 'Header for the role column in the user table',\n },\n 'authz.user.table.organization.column.header': {\n id: 'authz.user.table.organization.column.header',\n defaultMessage: 'Organization',\n description: 'Header for the organization column in the user table',\n },\n 'authz.user.table.scope.column.header': {\n id: 'authz.user.table.scope.column.header',\n defaultMessage: 'Scope',\n description: 'Header for the scope column in the user table',\n },\n 'authz.user.table.permissions.column.header': {\n id: 'authz.user.table.permissions.column.header',\n defaultMessage: 'Permissions',\n description: 'Header for the permissions column in the user table',\n },\n 'authz.user.table.action.column.header': {\n id: 'authz.user.table.action.column.header',\n defaultMessage: 'Actions',\n description: 'Header for the actions column in the user table',\n },\n 'authz.user.table.delete.action.alt': {\n id: 'authz.user.table.delete.action.alt',\n defaultMessage: 'Delete role action',\n description: 'Alt description for delete button',\n },\n 'authz.user.table.permissions.available.count': {\n id: 'authz.user.table.permissions.available.count',\n defaultMessage: '{count, plural, one {# permission available} other {# permissions available}}',\n description: 'Text showing the number of permissions available, with proper pluralization',\n },\n 'authz.user.table.permissions.total.access': {\n id: 'authz.user.table.permissions.total.access',\n defaultMessage: 'Total access',\n description: 'Label indicating Super Admin has total access to all permissions',\n },\n 'authz.user.table.permissions.partial.access': {\n id: 'authz.user.table.permissions.partial.access',\n defaultMessage: 'Partial access',\n description: 'Label indicating Global Staff has partial access to permissions',\n },\n 'authz.user.table.permissions.role.admin': {\n id: 'authz.user.table.permissions.role.admin',\n defaultMessage: 'Super Admins have full access to all areas of the platform, including content, settings, and user management. This role is managed at the platform level and cannot be changed from here. To modify it, go to Django Admin.',\n description: 'Description for the permissions of the Super Admin role',\n },\n 'authz.user.table.permissions.role.staff': {\n id: 'authz.user.table.permissions.role.staff',\n defaultMessage: 'Global Staff have access to all areas of the platform, similar to Super Admin, but cannot grant or revoke Super Admin or Global Staff roles to other users. This role is managed at the platform level and cannot be changed from here. To modify it, go to Django Admin.',\n description: 'Description for the permissions of the Global Staff role',\n },\n },\n);\n\nexport default messages;\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
3
|
+
import { Tab, Tabs } from '@openedx/paragon';
|
|
4
|
+
import { useLocation, useSearchParams } from 'react-router-dom';
|
|
5
|
+
import TeamMembersTable from '../team-members/TeamMembersTable';
|
|
6
|
+
import AddRoleButton from '../components/AddRoleButton';
|
|
7
|
+
import RolesPermissions from '../roles-permissions/RolesPermissions';
|
|
8
|
+
import AuthZLayout from '../components/AuthZLayout';
|
|
9
|
+
import messages from './messages';
|
|
10
|
+
const AuthzHome = () => {
|
|
11
|
+
var _a;
|
|
12
|
+
const { hash } = useLocation();
|
|
13
|
+
const intl = useIntl();
|
|
14
|
+
const [searchParams] = useSearchParams();
|
|
15
|
+
/* In the authoring repository the scope is encoded but this is to Replace spaces with '+'
|
|
16
|
+
to match URL encoding format in case the 'scope' parameter is provided with spaces instead of '+'
|
|
17
|
+
*/
|
|
18
|
+
const presetScope = ((_a = searchParams.get('scope')) === null || _a === void 0 ? void 0 : _a.replace(/\s/g, '+')) || undefined;
|
|
19
|
+
const pageTitle = intl.formatMessage(messages['authz.manage.page.title']);
|
|
20
|
+
return (_jsx("div", { className: "authz-module", children: _jsx(AuthZLayout, { context: { id: '', title: '', org: '' }, pageTitle: pageTitle, pageSubtitle: "", actions: [_jsx(AddRoleButton, {}, "add-role-button")], children: _jsxs(Tabs, { variant: "tabs", defaultActiveKey: hash ? 'permissionsRoles' : 'team', className: "bg-light-100 px-5", children: [_jsx(Tab, { eventKey: "team", title: intl.formatMessage(messages['authz.tabs.team']), className: "p-5 bg-light-200", children: _jsx(TeamMembersTable, { presetScope: presetScope }) }), _jsx(Tab, { id: "libraries-permissions-roles-tab", eventKey: "permissionsRoles", title: intl.formatMessage(messages['authz.tabs.permissionsRoles']), children: _jsx(RolesPermissions, {}) })] }) }) }));
|
|
21
|
+
};
|
|
22
|
+
export default AuthzHome;
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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,iDAAiD,CAAC;AAC/E,OAAO,aAAa,MAAM,4CAA4C,CAAC;AACvE,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,OAAO,CACL,cAAK,SAAS,EAAC,cAAc,YAC3B,KAAC,WAAW,IACV,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EACvC,SAAS,EAAE,SAAS,EACpB,YAAY,EAAC,EAAE,EACf,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,mBAAmB,aAE7B,KAAC,GAAG,IAAC,QAAQ,EAAC,MAAM,EAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,EAAE,SAAS,EAAC,kBAAkB,YACvG,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,YACtI,KAAC,gBAAgB,KAAG,GAChB,IACD,GACK,GACV,CACP,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/TeamMembersTable';\nimport AddRoleButton from '@src/authz-module/components/AddRoleButton';\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 return (\n <div className=\"authz-module\">\n <AuthZLayout\n context={{ id: '', title: '', org: '' }}\n pageTitle={pageTitle}\n pageSubtitle=\"\"\n actions={\n [<AddRoleButton key=\"add-role-button\" />]\n }\n >\n <Tabs\n variant=\"tabs\"\n defaultActiveKey={hash ? 'permissionsRoles' : 'team'}\n className=\"bg-light-100 px-5\"\n >\n <Tab eventKey=\"team\" title={intl.formatMessage(messages['authz.tabs.team'])} className=\"p-5 bg-light-200\">\n <TeamMembersTable presetScope={presetScope} />\n </Tab>\n <Tab id=\"libraries-permissions-roles-tab\" eventKey=\"permissionsRoles\" title={intl.formatMessage(messages['authz.tabs.permissionsRoles'])}>\n <RolesPermissions />\n </Tab>\n </Tabs>\n </AuthZLayout>\n </div>\n );\n};\n\nexport default AuthzHome;\n"]}
|