@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.
Files changed (236) hide show
  1. package/LICENSE +661 -0
  2. package/README.rst +164 -0
  3. package/dist/Main.d.ts +3 -0
  4. package/dist/Main.js +15 -0
  5. package/dist/Main.js.map +1 -0
  6. package/dist/app.d.ts +3 -0
  7. package/dist/app.js +10 -0
  8. package/dist/app.js.map +1 -0
  9. package/dist/authz-module/audit-user/index.d.ts +2 -0
  10. package/dist/authz-module/audit-user/index.js +191 -0
  11. package/dist/authz-module/audit-user/index.js.map +1 -0
  12. package/dist/authz-module/audit-user/messages.d.ts +58 -0
  13. package/dist/authz-module/audit-user/messages.js +60 -0
  14. package/dist/authz-module/audit-user/messages.js.map +1 -0
  15. package/dist/authz-module/authz-home/index.d.ts +2 -0
  16. package/dist/authz-module/authz-home/index.js +23 -0
  17. package/dist/authz-module/authz-home/index.js.map +1 -0
  18. package/dist/authz-module/authz-home/messages.d.ts +23 -0
  19. package/dist/authz-module/authz-home/messages.js +25 -0
  20. package/dist/authz-module/authz-home/messages.js.map +1 -0
  21. package/dist/authz-module/components/AddRoleButton.d.ts +6 -0
  22. package/dist/authz-module/components/AddRoleButton.js +22 -0
  23. package/dist/authz-module/components/AddRoleButton.js.map +1 -0
  24. package/dist/authz-module/components/AnchorButton.d.ts +2 -0
  25. package/dist/authz-module/components/AnchorButton.js +35 -0
  26. package/dist/authz-module/components/AnchorButton.js.map +1 -0
  27. package/dist/authz-module/components/AuthZLayout.d.ts +12 -0
  28. package/dist/authz-module/components/AuthZLayout.js +19 -0
  29. package/dist/authz-module/components/AuthZLayout.js.map +1 -0
  30. package/dist/authz-module/components/AuthZTitle.d.ts +20 -0
  31. package/dist/authz-module/components/AuthZTitle.js +22 -0
  32. package/dist/authz-module/components/AuthZTitle.js.map +1 -0
  33. package/dist/authz-module/components/ConfirmDeletionModal.d.ts +15 -0
  34. package/dist/authz-module/components/ConfirmDeletionModal.js +21 -0
  35. package/dist/authz-module/components/ConfirmDeletionModal.js.map +1 -0
  36. package/dist/authz-module/components/ErrorPage/index.d.ts +3 -0
  37. package/dist/authz-module/components/ErrorPage/index.js +59 -0
  38. package/dist/authz-module/components/ErrorPage/index.js.map +1 -0
  39. package/dist/authz-module/components/ErrorPage/messages.d.ts +53 -0
  40. package/dist/authz-module/components/ErrorPage/messages.js +55 -0
  41. package/dist/authz-module/components/ErrorPage/messages.js.map +1 -0
  42. package/dist/authz-module/components/PermissionTable.d.ts +9 -0
  43. package/dist/authz-module/components/PermissionTable.js +24 -0
  44. package/dist/authz-module/components/PermissionTable.js.map +1 -0
  45. package/dist/authz-module/components/RenderAdminRole.d.ts +5 -0
  46. package/dist/authz-module/components/RenderAdminRole.js +13 -0
  47. package/dist/authz-module/components/RenderAdminRole.js.map +1 -0
  48. package/dist/authz-module/components/RenderPermissionColumn.d.ts +6 -0
  49. package/dist/authz-module/components/RenderPermissionColumn.js +8 -0
  50. package/dist/authz-module/components/RenderPermissionColumn.js.map +1 -0
  51. package/dist/authz-module/components/RenderPermissionInLine.d.ts +6 -0
  52. package/dist/authz-module/components/RenderPermissionInLine.js +8 -0
  53. package/dist/authz-module/components/RenderPermissionInLine.js.map +1 -0
  54. package/dist/authz-module/components/ResourceTooltip.d.ts +11 -0
  55. package/dist/authz-module/components/ResourceTooltip.js +9 -0
  56. package/dist/authz-module/components/ResourceTooltip.js.map +1 -0
  57. package/dist/authz-module/components/RoleCard/constants.d.ts +14 -0
  58. package/dist/authz-module/components/RoleCard/constants.js +15 -0
  59. package/dist/authz-module/components/RoleCard/constants.js.map +1 -0
  60. package/dist/authz-module/components/RoleCard/messages.d.ts +73 -0
  61. package/dist/authz-module/components/RoleCard/messages.js +75 -0
  62. package/dist/authz-module/components/RoleCard/messages.js.map +1 -0
  63. package/dist/authz-module/components/TableCells.d.ts +29 -0
  64. package/dist/authz-module/components/TableCells.js +137 -0
  65. package/dist/authz-module/components/TableCells.js.map +1 -0
  66. package/dist/authz-module/components/TableControlBar/MultipleChoiceFilter.d.ts +3 -0
  67. package/dist/authz-module/components/TableControlBar/MultipleChoiceFilter.js +47 -0
  68. package/dist/authz-module/components/TableControlBar/MultipleChoiceFilter.js.map +1 -0
  69. package/dist/authz-module/components/TableControlBar/OrgFilter.d.ts +5 -0
  70. package/dist/authz-module/components/TableControlBar/OrgFilter.js +36 -0
  71. package/dist/authz-module/components/TableControlBar/OrgFilter.js.map +1 -0
  72. package/dist/authz-module/components/TableControlBar/RolesFilter.d.ts +4 -0
  73. package/dist/authz-module/components/TableControlBar/RolesFilter.js +29 -0
  74. package/dist/authz-module/components/TableControlBar/RolesFilter.js.map +1 -0
  75. package/dist/authz-module/components/TableControlBar/ScopesFilter.d.ts +4 -0
  76. package/dist/authz-module/components/TableControlBar/ScopesFilter.js +45 -0
  77. package/dist/authz-module/components/TableControlBar/ScopesFilter.js.map +1 -0
  78. package/dist/authz-module/components/TableControlBar/SearchFilter.d.ts +7 -0
  79. package/dist/authz-module/components/TableControlBar/SearchFilter.js +8 -0
  80. package/dist/authz-module/components/TableControlBar/SearchFilter.js.map +1 -0
  81. package/dist/authz-module/components/TableControlBar/TableControlBar.d.ts +5 -0
  82. package/dist/authz-module/components/TableControlBar/TableControlBar.js +99 -0
  83. package/dist/authz-module/components/TableControlBar/TableControlBar.js.map +1 -0
  84. package/dist/authz-module/components/TableControlBar/types.d.ts +18 -0
  85. package/dist/authz-module/components/TableControlBar/types.js +2 -0
  86. package/dist/authz-module/components/TableControlBar/types.js.map +1 -0
  87. package/dist/authz-module/components/TableFooter/TableFooter.d.ts +2 -0
  88. package/dist/authz-module/components/TableFooter/TableFooter.js +15 -0
  89. package/dist/authz-module/components/TableFooter/TableFooter.js.map +1 -0
  90. package/dist/authz-module/components/UserPermissions.d.ts +9 -0
  91. package/dist/authz-module/components/UserPermissions.js +56 -0
  92. package/dist/authz-module/components/UserPermissions.js.map +1 -0
  93. package/dist/authz-module/components/ViewMoreLink.d.ts +8 -0
  94. package/dist/authz-module/components/ViewMoreLink.js +8 -0
  95. package/dist/authz-module/components/ViewMoreLink.js.map +1 -0
  96. package/dist/authz-module/components/constants.d.ts +13 -0
  97. package/dist/authz-module/components/constants.js +80 -0
  98. package/dist/authz-module/components/constants.js.map +1 -0
  99. package/dist/authz-module/components/messages.d.ts +183 -0
  100. package/dist/authz-module/components/messages.js +185 -0
  101. package/dist/authz-module/components/messages.js.map +1 -0
  102. package/dist/authz-module/constants.d.ts +38 -0
  103. package/dist/authz-module/constants.js +77 -0
  104. package/dist/authz-module/constants.js.map +1 -0
  105. package/dist/authz-module/data/api.d.ts +109 -0
  106. package/dist/authz-module/data/api.js +107 -0
  107. package/dist/authz-module/data/api.js.map +1 -0
  108. package/dist/authz-module/data/hooks.d.ts +94 -0
  109. package/dist/authz-module/data/hooks.js +191 -0
  110. package/dist/authz-module/data/hooks.js.map +1 -0
  111. package/dist/authz-module/hooks/useCourseAuthoringFlag.d.ts +26 -0
  112. package/dist/authz-module/hooks/useCourseAuthoringFlag.js +86 -0
  113. package/dist/authz-module/hooks/useCourseAuthoringFlag.js.map +1 -0
  114. package/dist/authz-module/hooks/useQuerySettings.d.ts +27 -0
  115. package/dist/authz-module/hooks/useQuerySettings.js +72 -0
  116. package/dist/authz-module/hooks/useQuerySettings.js.map +1 -0
  117. package/dist/authz-module/hooks/useViewTeamPermissions.d.ts +5 -0
  118. package/dist/authz-module/hooks/useViewTeamPermissions.js +13 -0
  119. package/dist/authz-module/hooks/useViewTeamPermissions.js.map +1 -0
  120. package/dist/authz-module/index.d.ts +3 -0
  121. package/dist/authz-module/index.js +20 -0
  122. package/dist/authz-module/index.js.map +1 -0
  123. package/dist/authz-module/index.scss +131 -0
  124. package/dist/authz-module/messages.d.ts +48 -0
  125. package/dist/authz-module/messages.js +50 -0
  126. package/dist/authz-module/messages.js.map +1 -0
  127. package/dist/authz-module/role-assignation-wizard/AssignRoleWizard.d.ts +8 -0
  128. package/dist/authz-module/role-assignation-wizard/AssignRoleWizard.js +154 -0
  129. package/dist/authz-module/role-assignation-wizard/AssignRoleWizard.js.map +1 -0
  130. package/dist/authz-module/role-assignation-wizard/AssignRoleWizardPage.d.ts +2 -0
  131. package/dist/authz-module/role-assignation-wizard/AssignRoleWizardPage.js +39 -0
  132. package/dist/authz-module/role-assignation-wizard/AssignRoleWizardPage.js.map +1 -0
  133. package/dist/authz-module/role-assignation-wizard/components/DefineApplicationScopeStep.d.ts +8 -0
  134. package/dist/authz-module/role-assignation-wizard/components/DefineApplicationScopeStep.js +39 -0
  135. package/dist/authz-module/role-assignation-wizard/components/DefineApplicationScopeStep.js.map +1 -0
  136. package/dist/authz-module/role-assignation-wizard/components/HighlightedUsersInput.d.ts +11 -0
  137. package/dist/authz-module/role-assignation-wizard/components/HighlightedUsersInput.js +36 -0
  138. package/dist/authz-module/role-assignation-wizard/components/HighlightedUsersInput.js.map +1 -0
  139. package/dist/authz-module/role-assignation-wizard/components/OrgSection.d.ts +10 -0
  140. package/dist/authz-module/role-assignation-wizard/components/OrgSection.js +14 -0
  141. package/dist/authz-module/role-assignation-wizard/components/OrgSection.js.map +1 -0
  142. package/dist/authz-module/role-assignation-wizard/components/ScopeCheckboxItem.d.ts +8 -0
  143. package/dist/authz-module/role-assignation-wizard/components/ScopeCheckboxItem.js +5 -0
  144. package/dist/authz-module/role-assignation-wizard/components/ScopeCheckboxItem.js.map +1 -0
  145. package/dist/authz-module/role-assignation-wizard/components/ScopeFilterBar.d.ts +12 -0
  146. package/dist/authz-module/role-assignation-wizard/components/ScopeFilterBar.js +12 -0
  147. package/dist/authz-module/role-assignation-wizard/components/ScopeFilterBar.js.map +1 -0
  148. package/dist/authz-module/role-assignation-wizard/components/ScopeList.d.ts +20 -0
  149. package/dist/authz-module/role-assignation-wizard/components/ScopeList.js +30 -0
  150. package/dist/authz-module/role-assignation-wizard/components/ScopeList.js.map +1 -0
  151. package/dist/authz-module/role-assignation-wizard/components/SelectUsersAndRoleStep.d.ts +12 -0
  152. package/dist/authz-module/role-assignation-wizard/components/SelectUsersAndRoleStep.js +34 -0
  153. package/dist/authz-module/role-assignation-wizard/components/SelectUsersAndRoleStep.js.map +1 -0
  154. package/dist/authz-module/role-assignation-wizard/constants.d.ts +5 -0
  155. package/dist/authz-module/role-assignation-wizard/constants.js +6 -0
  156. package/dist/authz-module/role-assignation-wizard/constants.js.map +1 -0
  157. package/dist/authz-module/role-assignation-wizard/hooks/useScopeListData.d.ts +23 -0
  158. package/dist/authz-module/role-assignation-wizard/hooks/useScopeListData.js +112 -0
  159. package/dist/authz-module/role-assignation-wizard/hooks/useScopeListData.js.map +1 -0
  160. package/dist/authz-module/role-assignation-wizard/hooks/useScopePermissions.d.ts +10 -0
  161. package/dist/authz-module/role-assignation-wizard/hooks/useScopePermissions.js +54 -0
  162. package/dist/authz-module/role-assignation-wizard/hooks/useScopePermissions.js.map +1 -0
  163. package/dist/authz-module/role-assignation-wizard/messages.d.ts +243 -0
  164. package/dist/authz-module/role-assignation-wizard/messages.js +258 -0
  165. package/dist/authz-module/role-assignation-wizard/messages.js.map +1 -0
  166. package/dist/authz-module/role-assignation-wizard/utils.d.ts +5 -0
  167. package/dist/authz-module/role-assignation-wizard/utils.js +16 -0
  168. package/dist/authz-module/role-assignation-wizard/utils.js.map +1 -0
  169. package/dist/authz-module/roles-permissions/RolesPermissions.d.ts +2 -0
  170. package/dist/authz-module/roles-permissions/RolesPermissions.js +35 -0
  171. package/dist/authz-module/roles-permissions/RolesPermissions.js.map +1 -0
  172. package/dist/authz-module/roles-permissions/course/constants.d.ts +39 -0
  173. package/dist/authz-module/roles-permissions/course/constants.js +474 -0
  174. package/dist/authz-module/roles-permissions/course/constants.js.map +1 -0
  175. package/dist/authz-module/roles-permissions/index.d.ts +10 -0
  176. package/dist/authz-module/roles-permissions/index.js +15 -0
  177. package/dist/authz-module/roles-permissions/index.js.map +1 -0
  178. package/dist/authz-module/roles-permissions/library/constants.d.ts +18 -0
  179. package/dist/authz-module/roles-permissions/library/constants.js +193 -0
  180. package/dist/authz-module/roles-permissions/library/constants.js.map +1 -0
  181. package/dist/authz-module/roles-permissions/messages.d.ts +63 -0
  182. package/dist/authz-module/roles-permissions/messages.js +65 -0
  183. package/dist/authz-module/roles-permissions/messages.js.map +1 -0
  184. package/dist/authz-module/roles-permissions/utils.d.ts +41 -0
  185. package/dist/authz-module/roles-permissions/utils.js +70 -0
  186. package/dist/authz-module/roles-permissions/utils.js.map +1 -0
  187. package/dist/authz-module/team-members/TeamMembersTable.d.ts +5 -0
  188. package/dist/authz-module/team-members/TeamMembersTable.js +107 -0
  189. package/dist/authz-module/team-members/TeamMembersTable.js.map +1 -0
  190. package/dist/authz-module/team-members/messages.d.ts +33 -0
  191. package/dist/authz-module/team-members/messages.js +35 -0
  192. package/dist/authz-module/team-members/messages.js.map +1 -0
  193. package/dist/authz-module/utils.d.ts +24 -0
  194. package/dist/authz-module/utils.js +45 -0
  195. package/dist/authz-module/utils.js.map +1 -0
  196. package/dist/components/LoadingPage.d.ts +2 -0
  197. package/dist/components/LoadingPage.js +5 -0
  198. package/dist/components/LoadingPage.js.map +1 -0
  199. package/dist/components/ToastManager/ToastManagerContext.d.ts +24 -0
  200. package/dist/components/ToastManager/ToastManagerContext.js +91 -0
  201. package/dist/components/ToastManager/ToastManagerContext.js.map +1 -0
  202. package/dist/constants.d.ts +11 -0
  203. package/dist/constants.js +15 -0
  204. package/dist/constants.js.map +1 -0
  205. package/dist/data/api.d.ts +4 -0
  206. package/dist/data/api.js +21 -0
  207. package/dist/data/api.js.map +1 -0
  208. package/dist/data/hooks.d.ts +38 -0
  209. package/dist/data/hooks.js +69 -0
  210. package/dist/data/hooks.js.map +1 -0
  211. package/dist/data/types.d.ts +38 -0
  212. package/dist/data/types.js +2 -0
  213. package/dist/data/types.js.map +1 -0
  214. package/dist/data/utils.d.ts +6 -0
  215. package/dist/data/utils.js +11 -0
  216. package/dist/data/utils.js.map +1 -0
  217. package/dist/i18n/index.d.ts +1 -0
  218. package/dist/i18n/index.js +2 -0
  219. package/dist/i18n/index.js.map +1 -0
  220. package/dist/index.d.ts +3 -0
  221. package/dist/index.js +4 -0
  222. package/dist/index.js.map +1 -0
  223. package/dist/messages.d.ts +8 -0
  224. package/dist/messages.js +10 -0
  225. package/dist/messages.js.map +1 -0
  226. package/dist/providers.d.ts +3 -0
  227. package/dist/providers.js +4 -0
  228. package/dist/providers.js.map +1 -0
  229. package/dist/routes.d.ts +11 -0
  230. package/dist/routes.js +16 -0
  231. package/dist/routes.js.map +1 -0
  232. package/dist/style.scss +15 -0
  233. package/dist/types.d.ts +93 -0
  234. package/dist/types.js +2 -0
  235. package/dist/types.js.map +1 -0
  236. 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
@@ -0,0 +1,3 @@
1
+ import './style.scss';
2
+ declare const Main: () => import("react").JSX.Element;
3
+ export default Main;
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
@@ -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
@@ -0,0 +1,3 @@
1
+ import { App } from '@openedx/frontend-base';
2
+ declare const app: App;
3
+ export default app;
package/dist/app.js ADDED
@@ -0,0 +1,10 @@
1
+ import { appId } from './constants';
2
+ import routes from './routes';
3
+ import providers from './providers';
4
+ const app = {
5
+ appId,
6
+ routes,
7
+ providers,
8
+ };
9
+ export default app;
10
+ //# sourceMappingURL=app.js.map
@@ -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,2 @@
1
+ declare const AuditUserPage: () => import("react").JSX.Element;
2
+ export default AuditUserPage;
@@ -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":";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"]}
@@ -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,2 @@
1
+ declare const AuthzHome: () => import("react").JSX.Element;
2
+ export default AuthzHome;
@@ -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"]}