@openedx/frontend-app-admin-console 1.0.0-alpha.6 → 1.0.0-alpha.7

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 (81) hide show
  1. package/dist/authz-module/authz-home/index.js +20 -1
  2. package/dist/authz-module/authz-home/index.js.map +1 -1
  3. package/dist/authz-module/components/AddRoleButton.js +1 -1
  4. package/dist/authz-module/components/AddRoleButton.js.map +1 -1
  5. package/dist/authz-module/components/AuthZTitle.js +5 -3
  6. package/dist/authz-module/components/AuthZTitle.js.map +1 -1
  7. package/dist/authz-module/components/ExpandableButton.d.ts +17 -0
  8. package/dist/authz-module/components/ExpandableButton.js +16 -0
  9. package/dist/authz-module/components/ExpandableButton.js.map +1 -0
  10. package/dist/authz-module/components/TableCells.d.ts +5 -8
  11. package/dist/authz-module/components/TableCells.js +26 -59
  12. package/dist/authz-module/components/TableCells.js.map +1 -1
  13. package/dist/authz-module/components/TableControlBar/OrgFilter.js +2 -2
  14. package/dist/authz-module/components/TableControlBar/OrgFilter.js.map +1 -1
  15. package/dist/authz-module/components/TableControlBar/TableControlBar.d.ts +4 -1
  16. package/dist/authz-module/components/TableControlBar/TableControlBar.js +24 -24
  17. package/dist/authz-module/components/TableControlBar/TableControlBar.js.map +1 -1
  18. package/dist/authz-module/components/TableFooter/TableFooter.d.ts +14 -1
  19. package/dist/authz-module/components/TableFooter/TableFooter.js +3 -2
  20. package/dist/authz-module/components/TableFooter/TableFooter.js.map +1 -1
  21. package/dist/authz-module/components/constants.d.ts +1 -0
  22. package/dist/authz-module/components/constants.js +2 -1
  23. package/dist/authz-module/components/constants.js.map +1 -1
  24. package/dist/authz-module/components/messages.d.ts +0 -5
  25. package/dist/authz-module/components/messages.js +2 -7
  26. package/dist/authz-module/components/messages.js.map +1 -1
  27. package/dist/authz-module/constants.d.ts +14 -6
  28. package/dist/authz-module/constants.js +23 -6
  29. package/dist/authz-module/constants.js.map +1 -1
  30. package/dist/authz-module/data/api.d.ts +12 -4
  31. package/dist/authz-module/data/api.js +11 -2
  32. package/dist/authz-module/data/api.js.map +1 -1
  33. package/dist/authz-module/data/hooks.d.ts +8 -8
  34. package/dist/authz-module/data/hooks.js +15 -20
  35. package/dist/authz-module/data/hooks.js.map +1 -1
  36. package/dist/authz-module/hooks/useExclusiveRowExpansion.d.ts +7 -0
  37. package/dist/authz-module/hooks/useExclusiveRowExpansion.js +24 -0
  38. package/dist/authz-module/hooks/useExclusiveRowExpansion.js.map +1 -0
  39. package/dist/authz-module/index.scss +120 -2
  40. package/dist/authz-module/messages.d.ts +23 -0
  41. package/dist/authz-module/messages.js +18 -0
  42. package/dist/authz-module/messages.js.map +1 -1
  43. package/dist/authz-module/role-assignation-wizard/hooks/useScopeListData.js.map +1 -1
  44. package/dist/authz-module/team-members/TeamMembersTable.js +55 -17
  45. package/dist/authz-module/team-members/TeamMembersTable.js.map +1 -1
  46. package/dist/authz-module/team-members/components/AssignedRolesCell.d.ts +20 -0
  47. package/dist/authz-module/team-members/components/AssignedRolesCell.js +54 -0
  48. package/dist/authz-module/team-members/components/AssignedRolesCell.js.map +1 -0
  49. package/dist/authz-module/team-members/components/MoreRolesToggle.d.ts +14 -0
  50. package/dist/authz-module/team-members/components/MoreRolesToggle.js +25 -0
  51. package/dist/authz-module/team-members/components/MoreRolesToggle.js.map +1 -0
  52. package/dist/authz-module/team-members/components/TeamMemberCells.d.ts +17 -0
  53. package/dist/authz-module/team-members/components/TeamMemberCells.js +21 -0
  54. package/dist/authz-module/team-members/components/TeamMemberCells.js.map +1 -0
  55. package/dist/authz-module/team-members/components/TeamMemberViewActionCell.d.ts +18 -0
  56. package/dist/authz-module/team-members/components/TeamMemberViewActionCell.js +42 -0
  57. package/dist/authz-module/team-members/components/TeamMemberViewActionCell.js.map +1 -0
  58. package/dist/authz-module/team-members/components/UserAssignmentsSubTable.d.ts +16 -0
  59. package/dist/authz-module/team-members/components/UserAssignmentsSubTable.js +74 -0
  60. package/dist/authz-module/team-members/components/UserAssignmentsSubTable.js.map +1 -0
  61. package/dist/authz-module/team-members/index.d.ts +1 -0
  62. package/dist/authz-module/team-members/index.js +2 -0
  63. package/dist/authz-module/team-members/index.js.map +1 -0
  64. package/dist/authz-module/team-members/messages.d.ts +56 -1
  65. package/dist/authz-module/team-members/messages.js +59 -4
  66. package/dist/authz-module/team-members/messages.js.map +1 -1
  67. package/dist/authz-module/utils.d.ts +5 -0
  68. package/dist/authz-module/utils.js +10 -10
  69. package/dist/authz-module/utils.js.map +1 -1
  70. package/dist/components/LoadingPage.d.ts +3 -0
  71. package/dist/components/LoadingPage.js +9 -1
  72. package/dist/components/LoadingPage.js.map +1 -1
  73. package/dist/components/messages.d.ts +8 -0
  74. package/dist/components/messages.js +10 -0
  75. package/dist/components/messages.js.map +1 -0
  76. package/dist/types.d.ts +29 -20
  77. package/dist/types.js.map +1 -1
  78. package/package.json +1 -1
  79. package/dist/authz-module/components/ViewMoreLink.d.ts +0 -8
  80. package/dist/authz-module/components/ViewMoreLink.js +0 -8
  81. package/dist/authz-module/components/ViewMoreLink.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"TeamMembersTable.js","sourceRoot":"","sources":["../../../src/authz-module/team-members/TeamMembersTable.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport debounce from 'lodash.debounce';\nimport { useIntl } from '@openedx/frontend-base';\nimport {\n DataTable,\n TextFilter,\n} from '@openedx/paragon';\n\nimport { useToastManager } from '@src/components/ToastManager/ToastManagerContext';\nimport { LIBRARY_ROLE_KEYS } from '@src/authz-module/roles-permissions';\nimport { useViewTeamPermissions } from '@src/authz-module/hooks/useViewTeamPermissions';\nimport { useCourseAuthoringFlag } from '@src/authz-module/hooks/useCourseAuthoringFlag';\nimport { useQuerySettings } from '@src/authz-module/hooks/useQuerySettings';\nimport OrgFilter from '@src/authz-module/components/TableControlBar/OrgFilter';\nimport RolesFilter from '@src/authz-module/components/TableControlBar/RolesFilter';\nimport ScopesFilter from '@src/authz-module/components/TableControlBar/ScopesFilter';\nimport TableControlBar from '@src/authz-module/components/TableControlBar/TableControlBar';\nimport { getCellHeader } from '@src/authz-module/utils';\nimport {\n createViewActionCell, NameCell, OrgCell, RoleCell, ScopeCell,\n} from '@src/authz-module/components/TableCells';\nimport { useAllRoleAssignments } from '@src/authz-module/data/hooks';\nimport { TABLE_DEFAULT_PAGE_SIZE } from '@src/authz-module/constants';\nimport messages from './messages';\nimport TableFooter from '@src/authz-module/components/TableFooter/TableFooter';\n\ninterface TeamMembersTableProps {\n presetScope?: string;\n}\n\nconst TeamMembersTable = ({ presetScope }: TeamMembersTableProps) => {\n const intl = useIntl();\n const { showErrorToast } = useToastManager();\n const [columnsWithFiltersApplied, setColumnsWithFiltersApplied] = useState<string[]>([]);\n\n const initialQuerySettings = presetScope ? {\n scopes: presetScope,\n pageSize: TABLE_DEFAULT_PAGE_SIZE,\n pageIndex: 0,\n roles: null,\n organizations: null,\n search: null,\n order: null,\n sortBy: null,\n } : undefined;\n\n const { querySettings, handleTableFetch } = useQuerySettings(initialQuerySettings);\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 data: { results: roleAssignments, count } = { results: [], count: 0 },\n isLoading: isLoadingAllRoleAssignments,\n error,\n refetch,\n } = useAllRoleAssignments(effectiveQuerySettings);\n\n const viewActionCell = useMemo(() => createViewActionCell({ isCourseEnabled }), [isCourseEnabled]);\n\n const initialFilters = presetScope ? [{ id: 'scope', value: [presetScope] }] : [];\n\n useEffect(() => {\n if (error) {\n showErrorToast(error, refetch);\n }\n }, [error, showErrorToast, refetch]);\n\n const pageCount = Math.ceil(count / TABLE_DEFAULT_PAGE_SIZE);\n\n const fetchData = useMemo(() => debounce(handleTableFetch, 500), [handleTableFetch]);\n\n useEffect(() => () => fetchData.cancel(), [fetchData]);\n\n return (\n <DataTable\n isFilterable\n isPaginated\n isSortable\n manualFilters\n manualPagination\n manualSortBy\n numBreakoutFilters={4}\n fetchData={fetchData}\n data={roleAssignments}\n itemCount={count}\n pageCount={pageCount}\n initialState={{ pageSize: TABLE_DEFAULT_PAGE_SIZE, filters: initialFilters }}\n isLoading={isLoadingAllRoleAssignments}\n additionalColumns={[\n {\n id: 'action',\n Header: intl.formatMessage(messages['authz.team.members.table.column.actions.title']),\n Cell: viewActionCell,\n },\n ]}\n columns={\n [\n {\n id: 'username',\n Header: intl.formatMessage(messages['authz.team.members.table.column.name.title']),\n accessor: 'username',\n Cell: NameCell,\n filter: 'text',\n Filter: TextFilter,\n filterOrder: 1,\n },\n {\n Header: intl.formatMessage(messages['authz.team.members.table.column.email.title']),\n accessor: 'email',\n disableFilters: true,\n filter: 'text',\n Filter: TextFilter,\n },\n {\n Header: getCellHeader('org', intl.formatMessage(messages['authz.team.members.table.column.organization.title']), columnsWithFiltersApplied),\n accessor: 'org',\n Cell: OrgCell,\n filter: 'includesValue',\n Filter: OrgFilter,\n filterButtonText: intl.formatMessage(messages['authz.team.members.table.column.organization.title']),\n filterOrder: 2,\n },\n {\n Header: getCellHeader('scope', intl.formatMessage(messages['authz.team.members.table.column.scope.title']), columnsWithFiltersApplied),\n accessor: 'scope',\n Cell: ScopeCell,\n filter: 'includesValue',\n Filter: ScopesFilter,\n filterButtonText: intl.formatMessage(messages['authz.team.members.table.column.scope.title']),\n filterOrder: 4,\n },\n {\n Header: getCellHeader('role', intl.formatMessage(messages['authz.team.members.table.column.role.title']), columnsWithFiltersApplied),\n accessor: 'role',\n filter: 'includesValue',\n Cell: RoleCell,\n Filter: RolesFilter,\n filterButtonText: intl.formatMessage(messages['authz.team.members.table.column.role.title']),\n filterOrder: 3,\n },\n ]\n }\n >\n <TableControlBar onFilterChange={setColumnsWithFiltersApplied} />\n <DataTable.Table />\n <TableFooter />\n </DataTable>\n );\n};\n\nexport default TeamMembersTable;\n"]}
1
+ {"version":3,"file":"TeamMembersTable.js","sourceRoot":"","sources":["../../../src/authz-module/team-members/TeamMembersTable.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport debounce from 'lodash.debounce';\nimport { useIntl } from '@openedx/frontend-base';\nimport {\n DataTable,\n TextFilter,\n} from '@openedx/paragon';\n\nimport { useToastManager } from '@src/components/ToastManager/ToastManagerContext';\nimport { LIBRARY_ROLE_KEYS } from '@src/authz-module/roles-permissions';\nimport { useViewTeamPermissions } from '@src/authz-module/hooks/useViewTeamPermissions';\nimport { useQuerySettings } from '@src/authz-module/hooks/useQuerySettings';\nimport OrgFilter from '@src/authz-module/components/TableControlBar/OrgFilter';\nimport RolesFilter from '@src/authz-module/components/TableControlBar/RolesFilter';\nimport ScopesFilter from '@src/authz-module/components/TableControlBar/ScopesFilter';\nimport TableControlBar from '@src/authz-module/components/TableControlBar/TableControlBar';\nimport { getCellHeader } from '@src/authz-module/utils';\n\nimport { useTeamMembersAssignments } from '@src/authz-module/data/hooks';\nimport type { GetTeamMembersAssignmentsResponse } from '@src/authz-module/data/api';\nimport { TABLE_DEFAULT_PAGE_SIZE } from '@src/authz-module/constants';\nimport messages from './messages';\nimport TableFooter from '@src/authz-module/components/TableFooter/TableFooter';\nimport AssignedRolesCell from './components/AssignedRolesCell';\nimport { EmailCell, NameCell } from './components/TeamMemberCells';\nimport MoreRolesToggle from './components/MoreRolesToggle';\nimport UserAssignmentsSubTable from './components/UserAssignmentsSubTable';\nimport TeamMemberViewActionCell from './components/TeamMemberViewActionCell';\n\ninterface TeamMembersTableProps {\n presetScope?: string;\n}\n\nconst toastedErrors = new WeakSet<Error>();\n\n/**\n * Stable stand-in for a query that has not resolved. A fresh object literal here would\n * hand `DataTable` a new `data` array on every render, and react-table resets its\n * expanded-row state whenever `data` changes identity.\n */\nconst EMPTY_ASSIGNMENTS: GetTeamMembersAssignmentsResponse = {\n results: [], count: 0, next: null, previous: null,\n};\n\n// Org, scope and role stay in the column set — TableControlBar derives its filter\n// controls from the columns — but are hidden, since the design surfaces them inside\n// each user's role breakdown instead of as top-level columns. They carry no accessor\n// (a user row has no single org/scope/role), so each opts into filtering with\n// `defaultCanFilter`, which react-table otherwise infers from the accessor.\nconst HIDDEN_FILTER_COLUMNS = ['org', 'scope', 'role'];\n\nconst TeamMembersTable = ({ presetScope }: TeamMembersTableProps) => {\n const intl = useIntl();\n const { showErrorToast } = useToastManager();\n const [columnsWithFiltersApplied, setColumnsWithFiltersApplied] = useState<string[]>([]);\n\n const initialQuerySettings = presetScope ? {\n scopes: presetScope,\n pageSize: TABLE_DEFAULT_PAGE_SIZE,\n pageIndex: 0,\n roles: null,\n organizations: null,\n search: null,\n order: null,\n sortBy: null,\n } : undefined;\n\n const { querySettings, handleTableFetch } = useQuerySettings(initialQuerySettings);\n\n const { isCourseViewAllowed } = useViewTeamPermissions();\n\n const effectiveQuerySettings = useMemo(() => {\n if (isCourseViewAllowed || querySettings.roles) return querySettings;\n return { ...querySettings, roles: LIBRARY_ROLE_KEYS };\n }, [isCourseViewAllowed, querySettings]);\n\n const {\n data: { results: teamMembers, count } = EMPTY_ASSIGNMENTS,\n isLoading: isLoadingTeamMembers,\n error,\n refetch,\n } = useTeamMembersAssignments(effectiveQuerySettings);\n\n const initialFilters = presetScope ? [{ id: 'scope', value: [presetScope] }] : [];\n\n /**\n * Only transient failures reach here.\n */\n useEffect(() => {\n if (error && !toastedErrors.has(error)) {\n toastedErrors.add(error);\n showErrorToast(error, refetch);\n }\n }, [error, showErrorToast, refetch]);\n\n const pageCount = Math.ceil(count / TABLE_DEFAULT_PAGE_SIZE);\n\n const fetchData = useMemo(() => debounce(handleTableFetch, 500), [handleTableFetch]);\n\n useEffect(() => () => fetchData.cancel(), [fetchData]);\n\n const showingUsersLabel = intl.formatMessage(\n messages['authz.team.members.table.showing.users.text'],\n { pageSize: teamMembers.length, itemCount: count },\n );\n\n return (\n <DataTable\n isExpandable\n isFilterable\n isPaginated\n isSortable\n manualFilters\n manualPagination\n manualSortBy\n numBreakoutFilters={4}\n fetchData={fetchData}\n data={teamMembers}\n itemCount={count}\n pageCount={pageCount}\n initialState={{\n pageSize: TABLE_DEFAULT_PAGE_SIZE,\n filters: initialFilters,\n hiddenColumns: HIDDEN_FILTER_COLUMNS,\n }}\n isLoading={isLoadingTeamMembers}\n renderRowSubComponent={({ row }) => (\n <UserAssignmentsSubTable row={row} />\n )}\n additionalColumns={[\n {\n id: 'moreRoles',\n Header: '',\n Cell: MoreRolesToggle,\n },\n {\n id: 'action',\n Header: intl.formatMessage(messages['authz.team.members.table.column.actions.title']),\n Cell: TeamMemberViewActionCell,\n },\n ]}\n columns={\n [\n {\n id: 'username',\n Header: intl.formatMessage(messages['authz.team.members.table.column.username.title']),\n accessor: 'username',\n Cell: NameCell,\n filter: 'text',\n Filter: TextFilter,\n filterOrder: 1,\n },\n {\n Header: intl.formatMessage(messages['authz.team.members.table.column.email.title']),\n accessor: 'email',\n Cell: EmailCell,\n disableFilters: true,\n filter: 'text',\n Filter: TextFilter,\n },\n {\n id: 'assignedRoles',\n Header: intl.formatMessage(messages['authz.team.members.table.column.assigned.roles.title']),\n Cell: AssignedRolesCell,\n disableFilters: true,\n disableSortBy: true,\n },\n {\n id: 'org',\n Header: getCellHeader('org', intl.formatMessage(messages['authz.team.members.table.column.organization.title']), columnsWithFiltersApplied),\n filter: 'includesValue',\n defaultCanFilter: true,\n Filter: OrgFilter,\n filterButtonText: intl.formatMessage(messages['authz.team.members.table.column.organization.title']),\n filterOrder: 2,\n },\n {\n id: 'scope',\n Header: getCellHeader('scope', intl.formatMessage(messages['authz.team.members.table.column.scope.title']), columnsWithFiltersApplied),\n filter: 'includesValue',\n defaultCanFilter: true,\n Filter: ScopesFilter,\n filterButtonText: intl.formatMessage(messages['authz.team.members.table.column.scope.title']),\n filterOrder: 4,\n },\n {\n id: 'role',\n Header: getCellHeader('role', intl.formatMessage(messages['authz.team.members.table.column.role.title']), columnsWithFiltersApplied),\n filter: 'includesValue',\n defaultCanFilter: true,\n Filter: RolesFilter,\n filterButtonText: intl.formatMessage(messages['authz.team.members.table.column.role.title']),\n filterOrder: 3,\n },\n ]\n }\n >\n <TableControlBar onFilterChange={setColumnsWithFiltersApplied} countLabel={showingUsersLabel} />\n <DataTable.Table />\n <TableFooter showingMessage={messages['authz.team.members.table.showing.users.text']} />\n </DataTable>\n );\n};\n\nexport default TeamMembersTable;\n"]}
@@ -0,0 +1,20 @@
1
+ import type { TeamMember } from '../../../types';
2
+ interface AssignedRolesCellProps {
3
+ row: {
4
+ original: TeamMember;
5
+ };
6
+ }
7
+ /** The role pill: a light rounded block with the person icon, not a Paragon Chip. */
8
+ export declare const RoleBadge: ({ role }: {
9
+ role: string;
10
+ }) => import("react").JSX.Element;
11
+ /**
12
+ * Collapsed-row cell: the user's first assignment, as "[Role] In <scope>" with the
13
+ * organization on a subline.
14
+ *
15
+ * Renders `assignments[0]` exactly as the API returns it — the sub-table's first row must
16
+ * match it, so no client-side reordering happens here. The badge stays visible while the
17
+ * row is expanded, for visual continuity.
18
+ */
19
+ declare const AssignedRolesCell: ({ row }: AssignedRolesCellProps) => import("react").JSX.Element | null;
20
+ export default AssignedRolesCell;
@@ -0,0 +1,54 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { FormattedMessage, useIntl } from '@openedx/frontend-base';
3
+ import { Icon } from '@openedx/paragon';
4
+ import { Person } from '@openedx/paragon/icons';
5
+ import { ALL_ORGS_KEY, getAggregateScopeType, MAP_ROLE_KEY_TO_LABEL, } from '../../constants';
6
+ import { getScopeResourceIcon } from '../../utils';
7
+ import componentMessages from '../../components/messages';
8
+ import { RESOURCE_ICONS } from '../../components/constants';
9
+ import messages from '../messages';
10
+ /** The role pill: a light rounded block with the person icon, not a Paragon Chip. */
11
+ export const RoleBadge = ({ role }) => (_jsxs("div", { className: "authz-role-badge d-inline-flex align-items-center flex-shrink-0 text-nowrap rounded bg-light-300 text-gray-700 mr-3 px-2 py-1", children: [_jsx(Icon, { src: Person, size: "xs", className: "mr-1" }), MAP_ROLE_KEY_TO_LABEL[role] || role] }));
12
+ /**
13
+ * Collapsed-row cell: the user's first assignment, as "[Role] In <scope>" with the
14
+ * organization on a subline.
15
+ *
16
+ * Renders `assignments[0]` exactly as the API returns it — the sub-table's first row must
17
+ * match it, so no client-side reordering happens here. The badge stays visible while the
18
+ * row is expanded, for visual continuity.
19
+ */
20
+ const AssignedRolesCell = ({ row }) => {
21
+ var _a;
22
+ const { formatMessage } = useIntl();
23
+ const [assignment] = (_a = row.original.assignments) !== null && _a !== void 0 ? _a : [];
24
+ if (!assignment) {
25
+ return null;
26
+ }
27
+ const { role, scope, scopeDisplayName, org, } = assignment;
28
+ /*
29
+ * A wildcard scope names no single resource, so the row summarises it by reach alone:
30
+ * the organization it covers, or the whole platform. The kind of resource ("All
31
+ * courses in this organization") is left to the breakdown, and the organization line
32
+ * is dropped since the scope line already says it.
33
+ */
34
+ const aggregateType = getAggregateScopeType(scope, org);
35
+ let scopeIcon = getScopeResourceIcon(scope);
36
+ let scopeText = scopeDisplayName || scope;
37
+ if (aggregateType === 'platform') {
38
+ scopeIcon = RESOURCE_ICONS.GLOBAL;
39
+ scopeText = formatMessage(componentMessages['authz.user.table.org.all.organizations.label']);
40
+ }
41
+ else if (aggregateType === 'org') {
42
+ scopeIcon = RESOURCE_ICONS.ORGANIZATION;
43
+ scopeText = org;
44
+ }
45
+ const orgText = org === ALL_ORGS_KEY
46
+ ? formatMessage(componentMessages['authz.user.table.org.all.organizations.label'])
47
+ : org;
48
+ return (_jsx("div", { className: "authz-assigned-roles d-flex align-items-center text-gray-500", children: _jsx(FormattedMessage, Object.assign({}, messages['authz.team.members.table.assigned.roles'], { values: {
49
+ role: _jsx(RoleBadge, { role: role }),
50
+ scope: (_jsxs("div", { className: "authz-scope-cell ml-3", children: [_jsxs("span", { className: "d-flex align-items-center", children: [_jsx(Icon, { src: scopeIcon, className: "mr-2 flex-shrink-0 text-primary", size: "xs" }), _jsx("span", { className: "text-truncate text-gray-700 authz-scope-cell__name", title: scopeText, children: scopeText })] }), !aggregateType && (_jsxs("span", { className: "d-flex align-items-center small text-gray-500 authz-scope-cell__org ml-4", children: [_jsx(Icon, { src: RESOURCE_ICONS.ORGANIZATION, className: "mr-2 flex-shrink-0", size: "xs" }), _jsx("span", { className: "text-truncate", title: orgText, children: orgText })] }))] })),
51
+ } })) }));
52
+ };
53
+ export default AssignedRolesCell;
54
+ //# sourceMappingURL=AssignedRolesCell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssignedRolesCell.js","sourceRoot":"","sources":["../../../../src/authz-module/team-members/components/AssignedRolesCell.tsx"],"names":[],"mappings":"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","sourcesContent":["import { FormattedMessage, useIntl } from '@openedx/frontend-base';\nimport { Icon } from '@openedx/paragon';\nimport { Person } from '@openedx/paragon/icons';\nimport {\n ALL_ORGS_KEY, getAggregateScopeType, MAP_ROLE_KEY_TO_LABEL,\n} from '@src/authz-module/constants';\nimport { getScopeResourceIcon } from '@src/authz-module/utils';\nimport componentMessages from '@src/authz-module/components/messages';\nimport { RESOURCE_ICONS } from '@src/authz-module/components/constants';\nimport type { TeamMember } from '@src/types';\nimport messages from '../messages';\n\ninterface AssignedRolesCellProps {\n row: { original: TeamMember };\n}\n\n/** The role pill: a light rounded block with the person icon, not a Paragon Chip. */\nexport const RoleBadge = ({ role }: { role: string }) => (\n <div className=\"authz-role-badge d-inline-flex align-items-center flex-shrink-0 text-nowrap rounded bg-light-300 text-gray-700 mr-3 px-2 py-1\">\n <Icon src={Person} size=\"xs\" className=\"mr-1\" />\n {MAP_ROLE_KEY_TO_LABEL[role] || role}\n </div>\n);\n\n/**\n * Collapsed-row cell: the user's first assignment, as \"[Role] In <scope>\" with the\n * organization on a subline.\n *\n * Renders `assignments[0]` exactly as the API returns it — the sub-table's first row must\n * match it, so no client-side reordering happens here. The badge stays visible while the\n * row is expanded, for visual continuity.\n */\nconst AssignedRolesCell = ({ row }: AssignedRolesCellProps) => {\n const { formatMessage } = useIntl();\n const [assignment] = row.original.assignments ?? [];\n\n if (!assignment) {\n return null;\n }\n\n const {\n role, scope, scopeDisplayName, org,\n } = assignment;\n /*\n * A wildcard scope names no single resource, so the row summarises it by reach alone:\n * the organization it covers, or the whole platform. The kind of resource (\"All\n * courses in this organization\") is left to the breakdown, and the organization line\n * is dropped since the scope line already says it.\n */\n const aggregateType = getAggregateScopeType(scope, org);\n let scopeIcon = getScopeResourceIcon(scope);\n let scopeText = scopeDisplayName || scope;\n if (aggregateType === 'platform') {\n scopeIcon = RESOURCE_ICONS.GLOBAL;\n scopeText = formatMessage(componentMessages['authz.user.table.org.all.organizations.label']);\n } else if (aggregateType === 'org') {\n scopeIcon = RESOURCE_ICONS.ORGANIZATION;\n scopeText = org;\n }\n\n const orgText = org === ALL_ORGS_KEY\n ? formatMessage(componentMessages['authz.user.table.org.all.organizations.label'])\n : org;\n\n return (\n <div className=\"authz-assigned-roles d-flex align-items-center text-gray-500\">\n <FormattedMessage\n {...messages['authz.team.members.table.assigned.roles']}\n values={{\n role: <RoleBadge role={role} />,\n scope: (\n <div className=\"authz-scope-cell ml-3\">\n <span className=\"d-flex align-items-center\">\n <Icon src={scopeIcon} className=\"mr-2 flex-shrink-0 text-primary\" size=\"xs\" />\n <span className=\"text-truncate text-gray-700 authz-scope-cell__name\" title={scopeText}>{scopeText}</span>\n </span>\n {!aggregateType && (\n <span className=\"d-flex align-items-center small text-gray-500 authz-scope-cell__org ml-4\">\n <Icon src={RESOURCE_ICONS.ORGANIZATION} className=\"mr-2 flex-shrink-0\" size=\"xs\" />\n <span className=\"text-truncate\" title={orgText}>{orgText}</span>\n </span>\n )}\n </div>\n ),\n }}\n />\n </div>\n );\n};\n\nexport default AssignedRolesCell;\n"]}
@@ -0,0 +1,14 @@
1
+ import type { DataTableRow } from '@openedx/paragon';
2
+ import type { TeamMember } from '../../../types';
3
+ interface MoreRolesToggleProps {
4
+ row: DataTableRow<TeamMember>;
5
+ }
6
+ /**
7
+ * Expands a team member row to reveal their full role breakdown.
8
+ *
9
+ * The count is `assignmentCount - 1`: the collapsed row already shows the first role, so
10
+ * only the remaining ones are "more". Renders nothing when the user has a single role,
11
+ * since there is nothing further to reveal.
12
+ */
13
+ declare const MoreRolesToggle: ({ row }: MoreRolesToggleProps) => import("react").JSX.Element | null;
14
+ export default MoreRolesToggle;
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useIntl } from '@openedx/frontend-base';
3
+ import ExpandableButton from '../../components/ExpandableButton';
4
+ import { useExclusiveRowExpansion } from '../../hooks/useExclusiveRowExpansion';
5
+ import messages from '../messages';
6
+ /**
7
+ * Expands a team member row to reveal their full role breakdown.
8
+ *
9
+ * The count is `assignmentCount - 1`: the collapsed row already shows the first role, so
10
+ * only the remaining ones are "more". Renders nothing when the user has a single role,
11
+ * since there is nothing further to reveal.
12
+ */
13
+ const MoreRolesToggle = ({ row }) => {
14
+ const { formatMessage } = useIntl();
15
+ const toggleExpanded = useExclusiveRowExpansion(row);
16
+ const { assignmentCount } = row.original;
17
+ if (!assignmentCount || assignmentCount <= 1) {
18
+ return null;
19
+ }
20
+ return (_jsx(ExpandableButton, { label: row.isExpanded
21
+ ? formatMessage(messages['authz.team.members.table.hide.roles'])
22
+ : formatMessage(messages['authz.team.members.table.more.roles'], { count: assignmentCount - 1 }), onClick: toggleExpanded, isExpanded: !!row.isExpanded }));
23
+ };
24
+ export default MoreRolesToggle;
25
+ //# sourceMappingURL=MoreRolesToggle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MoreRolesToggle.js","sourceRoot":"","sources":["../../../../src/authz-module/team-members/components/MoreRolesToggle.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,gBAAgB,MAAM,+CAA+C,CAAC;AAC7E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kDAAkD,CAAC;AAE5F,OAAO,QAAQ,MAAM,aAAa,CAAC;AAMnC;;;;;;GAMG;AACH,MAAM,eAAe,GAAG,CAAC,EAAE,GAAG,EAAwB,EAAE,EAAE;IACxD,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,cAAc,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;IACrD,MAAM,EAAE,eAAe,EAAE,GAAG,GAAG,CAAC,QAAQ,CAAC;IAEzC,IAAI,CAAC,eAAe,IAAI,eAAe,IAAI,CAAC,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CACL,KAAC,gBAAgB,IACf,KAAK,EAAE,GAAG,CAAC,UAAU;YACnB,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,qCAAqC,CAAC,CAAC;YAChE,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,qCAAqC,CAAC,EAAE,EAAE,KAAK,EAAE,eAAe,GAAG,CAAC,EAAE,CAAC,EAClG,OAAO,EAAE,cAAc,EACvB,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,GAC5B,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,eAAe,CAAC","sourcesContent":["import { useIntl } from '@openedx/frontend-base';\nimport type { DataTableRow } from '@openedx/paragon';\nimport ExpandableButton from '@src/authz-module/components/ExpandableButton';\nimport { useExclusiveRowExpansion } from '@src/authz-module/hooks/useExclusiveRowExpansion';\nimport type { TeamMember } from '@src/types';\nimport messages from '../messages';\n\ninterface MoreRolesToggleProps {\n row: DataTableRow<TeamMember>;\n}\n\n/**\n * Expands a team member row to reveal their full role breakdown.\n *\n * The count is `assignmentCount - 1`: the collapsed row already shows the first role, so\n * only the remaining ones are \"more\". Renders nothing when the user has a single role,\n * since there is nothing further to reveal.\n */\nconst MoreRolesToggle = ({ row }: MoreRolesToggleProps) => {\n const { formatMessage } = useIntl();\n const toggleExpanded = useExclusiveRowExpansion(row);\n const { assignmentCount } = row.original;\n\n if (!assignmentCount || assignmentCount <= 1) {\n return null;\n }\n\n return (\n <ExpandableButton\n label={row.isExpanded\n ? formatMessage(messages['authz.team.members.table.hide.roles'])\n : formatMessage(messages['authz.team.members.table.more.roles'], { count: assignmentCount - 1 })}\n onClick={toggleExpanded}\n isExpanded={!!row.isExpanded}\n />\n );\n};\n\nexport default MoreRolesToggle;\n"]}
@@ -0,0 +1,17 @@
1
+ import type { TeamMember } from '../../../types';
2
+ interface NameCellProps {
3
+ row: {
4
+ original: TeamMember;
5
+ };
6
+ }
7
+ interface EmailCellProps {
8
+ value: string;
9
+ }
10
+ /**
11
+ * Username column. Shows the username verbatim — the API also sends `fullName`, but this
12
+ * column is headed "Username" and is what the table sorts and searches on. The row for the
13
+ * signed-in user is marked so they can find themselves in the list.
14
+ */
15
+ export declare const NameCell: ({ row }: NameCellProps) => import("react").JSX.Element;
16
+ export declare const EmailCell: ({ value }: EmailCellProps) => import("react").JSX.Element;
17
+ export {};
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useContext } from 'react';
3
+ import { FormattedMessage, SiteContext } from '@openedx/frontend-base';
4
+ import messages from '../messages';
5
+ /**
6
+ * Username column. Shows the username verbatim — the API also sends `fullName`, but this
7
+ * column is headed "Username" and is what the table sorts and searches on. The row for the
8
+ * signed-in user is marked so they can find themselves in the list.
9
+ */
10
+ export const NameCell = ({ row }) => {
11
+ const { authenticatedUser } = useContext(SiteContext);
12
+ const { username = '' } = row.original;
13
+ const isCurrentUser = username === (authenticatedUser === null || authenticatedUser === void 0 ? void 0 : authenticatedUser.username);
14
+ // The cell is muted so the bare "(Me)" reads as a marker; the username is content.
15
+ const name = _jsx("span", { className: "text-gray-700", children: username });
16
+ return (_jsx("span", { className: "d-block text-truncate authz-cell-username text-gray-500", title: username, children: isCurrentUser
17
+ ? (_jsx(FormattedMessage, Object.assign({}, messages['authz.team.members.table.username.current'], { values: { username: name } })))
18
+ : name }));
19
+ };
20
+ export const EmailCell = ({ value }) => (_jsx("span", { className: "d-block text-truncate authz-cell-email", title: value, children: value }));
21
+ //# sourceMappingURL=TeamMemberCells.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TeamMemberCells.js","sourceRoot":"","sources":["../../../../src/authz-module/team-members/components/TeamMemberCells.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEvE,OAAO,QAAQ,MAAM,aAAa,CAAC;AAUnC;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,EAAE,GAAG,EAAiB,EAAE,EAAE;IACjD,MAAM,EAAE,iBAAiB,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACtD,MAAM,EAAE,QAAQ,GAAG,EAAE,EAAE,GAAG,GAAG,CAAC,QAAQ,CAAC;IACvC,MAAM,aAAa,GAAG,QAAQ,MAAK,iBAAiB,aAAjB,iBAAiB,uBAAjB,iBAAiB,CAAE,QAAQ,CAAA,CAAC;IAC/D,mFAAmF;IACnF,MAAM,IAAI,GAAG,eAAM,SAAS,EAAC,eAAe,YAAE,QAAQ,GAAQ,CAAC;IAE/D,OAAO,CACL,eAAM,SAAS,EAAC,yDAAyD,EAAC,KAAK,EAAE,QAAQ,YACtF,aAAa;YACZ,CAAC,CAAC,CACE,KAAC,gBAAgB,oBACX,QAAQ,CAAC,2CAA2C,CAAC,IACzD,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,IAC1B,CACH;YACH,CAAC,CAAC,IAAI,GACH,CACR,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EAAE,KAAK,EAAkB,EAAE,EAAE,CAAC,CACtD,eAAM,SAAS,EAAC,wCAAwC,EAAC,KAAK,EAAE,KAAK,YAAG,KAAK,GAAQ,CACtF,CAAC","sourcesContent":["import { useContext } from 'react';\nimport { FormattedMessage, SiteContext } from '@openedx/frontend-base';\nimport type { TeamMember } from '@src/types';\nimport messages from '../messages';\n\ninterface NameCellProps {\n row: { original: TeamMember };\n}\n\ninterface EmailCellProps {\n value: string;\n}\n\n/**\n * Username column. Shows the username verbatim — the API also sends `fullName`, but this\n * column is headed \"Username\" and is what the table sorts and searches on. The row for the\n * signed-in user is marked so they can find themselves in the list.\n */\nexport const NameCell = ({ row }: NameCellProps) => {\n const { authenticatedUser } = useContext(SiteContext);\n const { username = '' } = row.original;\n const isCurrentUser = username === authenticatedUser?.username;\n // The cell is muted so the bare \"(Me)\" reads as a marker; the username is content.\n const name = <span className=\"text-gray-700\">{username}</span>;\n\n return (\n <span className=\"d-block text-truncate authz-cell-username text-gray-500\" title={username}>\n {isCurrentUser\n ? (\n <FormattedMessage\n {...messages['authz.team.members.table.username.current']}\n values={{ username: name }}\n />\n )\n : name}\n </span>\n );\n};\n\nexport const EmailCell = ({ value }: EmailCellProps) => (\n <span className=\"d-block text-truncate authz-cell-email\" title={value}>{value}</span>\n);\n"]}
@@ -0,0 +1,18 @@
1
+ import type { TeamMember } from '../../../types';
2
+ interface TeamMemberViewActionCellProps {
3
+ row: {
4
+ original: TeamMember;
5
+ };
6
+ }
7
+ /**
8
+ * Opens a team member's audit page.
9
+ *
10
+ * Rows are users rather than single assignments, so the course-authoring flag is evaluated
11
+ * across the user's assignments: the action stays enabled while at least one of them is
12
+ * viewable, and is only disabled when every one sits in a course that hasn't moved to the
13
+ * new roles experience. `assignments` is capped by `assignments_limit`, so a user whose
14
+ * total exceeds the returned slice may hold viewable roles it does not contain; those rows
15
+ * stay enabled rather than being blocked on incomplete evidence.
16
+ */
17
+ declare const TeamMemberViewActionCell: ({ row }: TeamMemberViewActionCellProps) => import("react").JSX.Element;
18
+ export default TeamMemberViewActionCell;
@@ -0,0 +1,42 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useIntl } from '@openedx/frontend-base';
3
+ import { IconButton } from '@openedx/paragon';
4
+ import { Visibility } from '@openedx/paragon/icons';
5
+ import { useNavigate } from 'react-router-dom';
6
+ import { buildAuditUserPath, CONTEXT_TYPES, getScopeContextType } from '../../constants';
7
+ import { useCourseAuthoringFlag } from '../../hooks/useCourseAuthoringFlag';
8
+ import { DisabledCourseActionButton } from '../../components/TableCells';
9
+ import componentMessages from '../../components/messages';
10
+ const isViewable = (assignment, isCourseEnabled) => {
11
+ if (getScopeContextType(assignment.scope) === CONTEXT_TYPES.LIBRARY) {
12
+ return true;
13
+ }
14
+ return isCourseEnabled(assignment.scope);
15
+ };
16
+ /**
17
+ * Opens a team member's audit page.
18
+ *
19
+ * Rows are users rather than single assignments, so the course-authoring flag is evaluated
20
+ * across the user's assignments: the action stays enabled while at least one of them is
21
+ * viewable, and is only disabled when every one sits in a course that hasn't moved to the
22
+ * new roles experience. `assignments` is capped by `assignments_limit`, so a user whose
23
+ * total exceeds the returned slice may hold viewable roles it does not contain; those rows
24
+ * stay enabled rather than being blocked on incomplete evidence.
25
+ */
26
+ const TeamMemberViewActionCell = ({ row }) => {
27
+ const { formatMessage } = useIntl();
28
+ const navigate = useNavigate();
29
+ // Read here rather than threaded down from the table: the flag is a react-query query,
30
+ // so every row shares one request no matter how many cells ask for it.
31
+ const { isCourseEnabled } = useCourseAuthoringFlag();
32
+ const { assignments = [], assignmentCount, username } = row.original;
33
+ const hasViewableAssignment = assignments.length === 0
34
+ || assignmentCount > assignments.length
35
+ || assignments.some((assignment) => isViewable(assignment, isCourseEnabled));
36
+ if (!hasViewableAssignment) {
37
+ return (_jsx(DisabledCourseActionButton, { src: Visibility, alt: formatMessage(componentMessages['authz.table.column.actions.view.title']), size: "sm" }));
38
+ }
39
+ return (_jsx(IconButton, { src: Visibility, alt: formatMessage(componentMessages['authz.table.column.actions.view.title']), size: "sm", onClick: () => navigate(buildAuditUserPath(username)) }));
40
+ };
41
+ export default TeamMemberViewActionCell;
42
+ //# sourceMappingURL=TeamMemberViewActionCell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TeamMemberViewActionCell.js","sourceRoot":"","sources":["../../../../src/authz-module/team-members/components/TeamMemberViewActionCell.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACrG,OAAO,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AACxF,OAAO,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAC;AACrF,OAAO,iBAAiB,MAAM,uCAAuC,CAAC;AAOtE,MAAM,UAAU,GAAG,CAAC,UAAgC,EAAE,eAA2C,EAAE,EAAE;IACnG,IAAI,mBAAmB,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,aAAa,CAAC,OAAO,EAAE,CAAC;QACpE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,eAAe,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AAC3C,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,wBAAwB,GAAG,CAAC,EAAE,GAAG,EAAiC,EAAE,EAAE;IAC1E,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,uFAAuF;IACvF,uEAAuE;IACvE,MAAM,EAAE,eAAe,EAAE,GAAG,sBAAsB,EAAE,CAAC;IACrD,MAAM,EAAE,WAAW,GAAG,EAAE,EAAE,eAAe,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC,QAAQ,CAAC;IAErE,MAAM,qBAAqB,GAAG,WAAW,CAAC,MAAM,KAAK,CAAC;WACjD,eAAe,GAAG,WAAW,CAAC,MAAM;WACpC,WAAW,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC;IAE/E,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,OAAO,CACL,KAAC,0BAA0B,IACzB,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,aAAa,CAAC,iBAAiB,CAAC,uCAAuC,CAAC,CAAC,EAC9E,IAAI,EAAC,IAAI,GACT,CACH,CAAC;IACJ,CAAC;IAED,OAAO,CACL,KAAC,UAAU,IACT,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,aAAa,CAAC,iBAAiB,CAAC,uCAAuC,CAAC,CAAC,EAC9E,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,GACrD,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,wBAAwB,CAAC","sourcesContent":["import { useIntl } from '@openedx/frontend-base';\nimport { IconButton } from '@openedx/paragon';\nimport { Visibility } from '@openedx/paragon/icons';\nimport { useNavigate } from 'react-router-dom';\nimport { buildAuditUserPath, CONTEXT_TYPES, getScopeContextType } from '@src/authz-module/constants';\nimport { useCourseAuthoringFlag } from '@src/authz-module/hooks/useCourseAuthoringFlag';\nimport { DisabledCourseActionButton } from '@src/authz-module/components/TableCells';\nimport componentMessages from '@src/authz-module/components/messages';\nimport type { TeamMember, TeamMemberAssignment } from '@src/types';\n\ninterface TeamMemberViewActionCellProps {\n row: { original: TeamMember };\n}\n\nconst isViewable = (assignment: TeamMemberAssignment, isCourseEnabled: (scope: string) => boolean) => {\n if (getScopeContextType(assignment.scope) === CONTEXT_TYPES.LIBRARY) {\n return true;\n }\n return isCourseEnabled(assignment.scope);\n};\n\n/**\n * Opens a team member's audit page.\n *\n * Rows are users rather than single assignments, so the course-authoring flag is evaluated\n * across the user's assignments: the action stays enabled while at least one of them is\n * viewable, and is only disabled when every one sits in a course that hasn't moved to the\n * new roles experience. `assignments` is capped by `assignments_limit`, so a user whose\n * total exceeds the returned slice may hold viewable roles it does not contain; those rows\n * stay enabled rather than being blocked on incomplete evidence.\n */\nconst TeamMemberViewActionCell = ({ row }: TeamMemberViewActionCellProps) => {\n const { formatMessage } = useIntl();\n const navigate = useNavigate();\n // Read here rather than threaded down from the table: the flag is a react-query query,\n // so every row shares one request no matter how many cells ask for it.\n const { isCourseEnabled } = useCourseAuthoringFlag();\n const { assignments = [], assignmentCount, username } = row.original;\n\n const hasViewableAssignment = assignments.length === 0\n || assignmentCount > assignments.length\n || assignments.some((assignment) => isViewable(assignment, isCourseEnabled));\n\n if (!hasViewableAssignment) {\n return (\n <DisabledCourseActionButton\n src={Visibility}\n alt={formatMessage(componentMessages['authz.table.column.actions.view.title'])}\n size=\"sm\"\n />\n );\n }\n\n return (\n <IconButton\n src={Visibility}\n alt={formatMessage(componentMessages['authz.table.column.actions.view.title'])}\n size=\"sm\"\n onClick={() => navigate(buildAuditUserPath(username))}\n />\n );\n};\n\nexport default TeamMemberViewActionCell;\n"]}
@@ -0,0 +1,16 @@
1
+ import type { TeamMember } from '../../../types';
2
+ interface UserAssignmentsSubTableProps {
3
+ row: {
4
+ original: TeamMember;
5
+ };
6
+ }
7
+ /**
8
+ * Role breakdown revealed when a team member row is expanded.
9
+ *
10
+ * Lists the assignments the API returned, in order, so the first entry matches the badge
11
+ * still shown in the collapsed row above. The footer total is `assignmentCount`, which
12
+ * may exceed the rows listed here — `View all roles` leads to the audit page when it
13
+ * does.
14
+ */
15
+ declare const UserAssignmentsSubTable: ({ row }: UserAssignmentsSubTableProps) => import("react").JSX.Element;
16
+ export default UserAssignmentsSubTable;
@@ -0,0 +1,74 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useMemo } from 'react';
3
+ import { useIntl } from '@openedx/frontend-base';
4
+ import { Card, DataTable, Icon, TableFooter, } from '@openedx/paragon';
5
+ import { ArrowForward } from '@openedx/paragon/icons';
6
+ import { Link } from 'react-router-dom';
7
+ import { ALL_ORGS_KEY, buildAuditUserPath, getAggregateScopeType, getScopeContextType, } from '../../constants';
8
+ import { getScopeResourceIcon } from '../../utils';
9
+ import componentMessages from '../../components/messages';
10
+ import { RESOURCE_ICONS } from '../../components/constants';
11
+ import { AGGREGATE_SCOPE_LABELS } from '../../messages';
12
+ import messages from '../messages';
13
+ import { RoleBadge } from './AssignedRolesCell';
14
+ // Same badge as the collapsed row above, so the breakdown reads consistently.
15
+ const RoleBadgeCell = ({ row: assignmentRow }) => (_jsx(RoleBadge, { role: assignmentRow.original.role }));
16
+ const ScopeNameCell = ({ row: assignmentRow }) => {
17
+ const { formatMessage } = useIntl();
18
+ const { scope, scopeDisplayName, org } = assignmentRow.original;
19
+ const aggregateType = getAggregateScopeType(scope, org);
20
+ const scopeText = aggregateType
21
+ ? formatMessage(AGGREGATE_SCOPE_LABELS[getScopeContextType(scope)])
22
+ : scopeDisplayName || scope;
23
+ return (_jsxs("span", { className: "d-flex align-items-center", children: [_jsx(Icon, { src: getScopeResourceIcon(scope), className: "mr-2 flex-shrink-0 text-primary", size: "xs" }), _jsx("span", { className: "text-truncate", title: scopeText, children: scopeText })] }));
24
+ };
25
+ // Mirrors ScopeNameCell's icon treatment so all three columns read alike. A wildcard org
26
+ // reaches past any one organization, so it gets the same globe and label as the row above.
27
+ const OrgIconCell = ({ row: assignmentRow }) => {
28
+ const { formatMessage } = useIntl();
29
+ const { org } = assignmentRow.original;
30
+ const isAllOrgs = org === ALL_ORGS_KEY;
31
+ const orgText = isAllOrgs
32
+ ? formatMessage(componentMessages['authz.user.table.org.all.organizations.label'])
33
+ : org;
34
+ return (_jsxs("span", { className: "d-flex align-items-center", children: [_jsx(Icon, { src: isAllOrgs ? RESOURCE_ICONS.GLOBAL : RESOURCE_ICONS.ORGANIZATION, className: "mr-2 flex-shrink-0 text-primary", size: "xs" }), _jsx("span", { className: "text-truncate", title: orgText, children: orgText })] }));
35
+ };
36
+ /**
37
+ * Role breakdown revealed when a team member row is expanded.
38
+ *
39
+ * Lists the assignments the API returned, in order, so the first entry matches the badge
40
+ * still shown in the collapsed row above. The footer total is `assignmentCount`, which
41
+ * may exceed the rows listed here — `View all roles` leads to the audit page when it
42
+ * does.
43
+ */
44
+ const UserAssignmentsSubTable = ({ row }) => {
45
+ const { formatMessage } = useIntl();
46
+ const { assignments = [], assignmentCount, username } = row.original;
47
+ const hasMoreAssignments = assignmentCount > assignments.length;
48
+ const columns = useMemo(() => [
49
+ {
50
+ id: 'role',
51
+ Header: formatMessage(messages['authz.team.members.subtable.column.role.title']),
52
+ accessor: 'role',
53
+ Cell: RoleBadgeCell,
54
+ },
55
+ {
56
+ id: 'scope',
57
+ Header: formatMessage(messages['authz.team.members.subtable.column.scope.title']),
58
+ accessor: 'scope',
59
+ Cell: ScopeNameCell,
60
+ },
61
+ {
62
+ id: 'org',
63
+ Header: formatMessage(messages['authz.team.members.subtable.column.organization.title']),
64
+ accessor: 'org',
65
+ Cell: OrgIconCell,
66
+ },
67
+ ], [formatMessage]);
68
+ return (_jsx(Card, { className: "team-members-table__subtable my-3", children: _jsxs(DataTable, { columns: columns, data: assignments, itemCount: assignments.length, children: [_jsx(DataTable.Table, { isStriped: false }), _jsx(TableFooter, { children: _jsxs("div", { className: "d-flex align-items-center justify-content-center w-100", children: [_jsx("span", { className: "text-gray-500", children: formatMessage(messages['authz.team.members.subtable.showing.text'], {
69
+ shown: String(assignments.length).padStart(2, '0'),
70
+ total: String(assignmentCount).padStart(2, '0'),
71
+ }) }), hasMoreAssignments && (_jsxs(_Fragment, { children: [_jsx("hr", { className: "mx-3" }), _jsxs(Link, { className: "d-inline-flex align-items-center", to: buildAuditUserPath(username), children: [formatMessage(messages['authz.team.members.subtable.view.all.roles']), _jsx(Icon, { src: ArrowForward, size: "xs", className: "ml-1" })] })] }))] }) })] }) }));
72
+ };
73
+ export default UserAssignmentsSubTable;
74
+ //# sourceMappingURL=UserAssignmentsSubTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserAssignmentsSubTable.js","sourceRoot":"","sources":["../../../../src/authz-module/team-members/components/UserAssignmentsSubTable.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport {\n Card, DataTable, Icon, TableFooter,\n} from '@openedx/paragon';\nimport { ArrowForward } from '@openedx/paragon/icons';\nimport { Link } from 'react-router-dom';\nimport {\n ALL_ORGS_KEY, buildAuditUserPath, getAggregateScopeType, getScopeContextType,\n} from '@src/authz-module/constants';\nimport { getScopeResourceIcon } from '@src/authz-module/utils';\nimport componentMessages from '@src/authz-module/components/messages';\nimport { RESOURCE_ICONS } from '@src/authz-module/components/constants';\nimport type { TeamMember, TeamMemberAssignment } from '@src/types';\nimport { AGGREGATE_SCOPE_LABELS } from '@src/authz-module/messages';\nimport messages from '../messages';\nimport { RoleBadge } from './AssignedRolesCell';\n\ninterface UserAssignmentsSubTableProps {\n row: { original: TeamMember };\n}\n\ninterface AssignmentCellProps {\n row: { original: TeamMemberAssignment };\n}\n\n// Same badge as the collapsed row above, so the breakdown reads consistently.\nconst RoleBadgeCell = ({ row: assignmentRow }: AssignmentCellProps) => (\n <RoleBadge role={assignmentRow.original.role} />\n);\n\nconst ScopeNameCell = ({ row: assignmentRow }: AssignmentCellProps) => {\n const { formatMessage } = useIntl();\n const { scope, scopeDisplayName, org } = assignmentRow.original;\n const aggregateType = getAggregateScopeType(scope, org);\n const scopeText = aggregateType\n ? formatMessage(AGGREGATE_SCOPE_LABELS[getScopeContextType(scope)])\n : scopeDisplayName || scope;\n\n return (\n <span className=\"d-flex align-items-center\">\n <Icon src={getScopeResourceIcon(scope)} className=\"mr-2 flex-shrink-0 text-primary\" size=\"xs\" />\n <span className=\"text-truncate\" title={scopeText}>{scopeText}</span>\n </span>\n );\n};\n\n// Mirrors ScopeNameCell's icon treatment so all three columns read alike. A wildcard org\n// reaches past any one organization, so it gets the same globe and label as the row above.\nconst OrgIconCell = ({ row: assignmentRow }: AssignmentCellProps) => {\n const { formatMessage } = useIntl();\n const { org } = assignmentRow.original;\n const isAllOrgs = org === ALL_ORGS_KEY;\n const orgText = isAllOrgs\n ? formatMessage(componentMessages['authz.user.table.org.all.organizations.label'])\n : org;\n\n return (\n <span className=\"d-flex align-items-center\">\n <Icon src={isAllOrgs ? RESOURCE_ICONS.GLOBAL : RESOURCE_ICONS.ORGANIZATION} className=\"mr-2 flex-shrink-0 text-primary\" size=\"xs\" />\n <span className=\"text-truncate\" title={orgText}>{orgText}</span>\n </span>\n );\n};\n\n/**\n * Role breakdown revealed when a team member row is expanded.\n *\n * Lists the assignments the API returned, in order, so the first entry matches the badge\n * still shown in the collapsed row above. The footer total is `assignmentCount`, which\n * may exceed the rows listed here — `View all roles` leads to the audit page when it\n * does.\n */\nconst UserAssignmentsSubTable = ({ row }: UserAssignmentsSubTableProps) => {\n const { formatMessage } = useIntl();\n const { assignments = [], assignmentCount, username } = row.original;\n const hasMoreAssignments = assignmentCount > assignments.length;\n\n const columns = useMemo(() => [\n {\n id: 'role',\n Header: formatMessage(messages['authz.team.members.subtable.column.role.title']),\n accessor: 'role',\n Cell: RoleBadgeCell,\n },\n {\n id: 'scope',\n Header: formatMessage(messages['authz.team.members.subtable.column.scope.title']),\n accessor: 'scope',\n Cell: ScopeNameCell,\n },\n {\n id: 'org',\n Header: formatMessage(messages['authz.team.members.subtable.column.organization.title']),\n accessor: 'org',\n Cell: OrgIconCell,\n },\n ], [formatMessage]);\n\n return (\n <Card className=\"team-members-table__subtable my-3\">\n <DataTable\n columns={columns}\n data={assignments}\n itemCount={assignments.length}\n >\n <DataTable.Table isStriped={false} />\n <TableFooter>\n <div className=\"d-flex align-items-center justify-content-center w-100\">\n <span className=\"text-gray-500\">\n {formatMessage(messages['authz.team.members.subtable.showing.text'], {\n shown: String(assignments.length).padStart(2, '0'),\n total: String(assignmentCount).padStart(2, '0'),\n })}\n </span>\n {hasMoreAssignments && (\n <>\n {/* Reuses the module's vertical `hr` divider (see index.scss). */}\n <hr className=\"mx-3\" />\n <Link className=\"d-inline-flex align-items-center\" to={buildAuditUserPath(username)}>\n {formatMessage(messages['authz.team.members.subtable.view.all.roles'])}\n <Icon src={ArrowForward} size=\"xs\" className=\"ml-1\" />\n </Link>\n </>\n )}\n </div>\n </TableFooter>\n </DataTable>\n </Card>\n );\n};\n\nexport default UserAssignmentsSubTable;\n"]}
@@ -0,0 +1 @@
1
+ export { default as TeamMembersTable } from './TeamMembersTable';
@@ -0,0 +1,2 @@
1
+ export { default as TeamMembersTable } from './TeamMembersTable';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authz-module/team-members/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["export { default as TeamMembersTable } from './TeamMembersTable';\n"]}
@@ -1,5 +1,10 @@
1
1
  declare const messages: {
2
- 'authz.team.members.table.column.name.title': {
2
+ 'authz.team.members.table.column.username.title': {
3
+ id: string;
4
+ defaultMessage: string;
5
+ description: string;
6
+ };
7
+ 'authz.team.members.table.username.current': {
3
8
  id: string;
4
9
  defaultMessage: string;
5
10
  description: string;
@@ -29,5 +34,55 @@ declare const messages: {
29
34
  defaultMessage: string;
30
35
  description: string;
31
36
  };
37
+ 'authz.team.members.table.column.assigned.roles.title': {
38
+ id: string;
39
+ defaultMessage: string;
40
+ description: string;
41
+ };
42
+ 'authz.team.members.table.assigned.roles': {
43
+ id: string;
44
+ defaultMessage: string;
45
+ description: string;
46
+ };
47
+ 'authz.team.members.table.more.roles': {
48
+ id: string;
49
+ defaultMessage: string;
50
+ description: string;
51
+ };
52
+ 'authz.team.members.table.hide.roles': {
53
+ id: string;
54
+ defaultMessage: string;
55
+ description: string;
56
+ };
57
+ 'authz.team.members.subtable.column.role.title': {
58
+ id: string;
59
+ defaultMessage: string;
60
+ description: string;
61
+ };
62
+ 'authz.team.members.subtable.column.scope.title': {
63
+ id: string;
64
+ defaultMessage: string;
65
+ description: string;
66
+ };
67
+ 'authz.team.members.subtable.column.organization.title': {
68
+ id: string;
69
+ defaultMessage: string;
70
+ description: string;
71
+ };
72
+ 'authz.team.members.subtable.showing.text': {
73
+ id: string;
74
+ defaultMessage: string;
75
+ description: string;
76
+ };
77
+ 'authz.team.members.subtable.view.all.roles': {
78
+ id: string;
79
+ defaultMessage: string;
80
+ description: string;
81
+ };
82
+ 'authz.team.members.table.showing.users.text': {
83
+ id: string;
84
+ defaultMessage: string;
85
+ description: string;
86
+ };
32
87
  };
33
88
  export default messages;
@@ -1,9 +1,14 @@
1
1
  import { defineMessages } from '@openedx/frontend-base';
2
2
  const messages = defineMessages({
3
- 'authz.team.members.table.column.name.title': {
4
- id: 'authz.team.members.table.column.name.title',
5
- defaultMessage: 'Name',
6
- description: 'Team members table name column header',
3
+ 'authz.team.members.table.column.username.title': {
4
+ id: 'authz.team.members.table.column.username.title',
5
+ defaultMessage: 'Username',
6
+ description: 'Team members table username column header',
7
+ },
8
+ 'authz.team.members.table.username.current': {
9
+ id: 'authz.team.members.table.username.current',
10
+ defaultMessage: '{username} (Me)',
11
+ description: 'Indicates the current user in the team members table',
7
12
  },
8
13
  'authz.team.members.table.column.email.title': {
9
14
  id: 'authz.team.members.table.column.email.title',
@@ -30,6 +35,56 @@ const messages = defineMessages({
30
35
  defaultMessage: 'Actions',
31
36
  description: 'Team members table actions column header',
32
37
  },
38
+ 'authz.team.members.table.column.assigned.roles.title': {
39
+ id: 'authz.team.members.table.column.assigned.roles.title',
40
+ defaultMessage: 'Assigned roles',
41
+ description: 'Team members table assigned roles column header',
42
+ },
43
+ 'authz.team.members.table.assigned.roles': {
44
+ id: 'authz.team.members.table.assigned.roles',
45
+ defaultMessage: '{role} in {scope}',
46
+ description: 'One role assignment on a team member row, e.g. "Course Admin in Introduction to Data Analysis". {role} is the role badge and {scope} the course or library it applies to, so both the order and the connecting word can be changed per language.',
47
+ },
48
+ 'authz.team.members.table.more.roles': {
49
+ id: 'authz.team.members.table.more.roles',
50
+ defaultMessage: '+{count, plural, one {# more role} other {# more roles}}',
51
+ description: 'Link expanding a team member row to reveal their remaining roles. The count excludes the role already shown in the collapsed row.',
52
+ },
53
+ 'authz.team.members.table.hide.roles': {
54
+ id: 'authz.team.members.table.hide.roles',
55
+ defaultMessage: 'Hide roles',
56
+ description: 'Link collapsing an expanded team member row',
57
+ },
58
+ 'authz.team.members.subtable.column.role.title': {
59
+ id: 'authz.team.members.subtable.column.role.title',
60
+ defaultMessage: 'Role',
61
+ description: 'Role column header of the nested assignments table inside an expanded team member row',
62
+ },
63
+ 'authz.team.members.subtable.column.scope.title': {
64
+ id: 'authz.team.members.subtable.column.scope.title',
65
+ defaultMessage: 'Scope',
66
+ description: 'Scope column header of the nested assignments table inside an expanded team member row',
67
+ },
68
+ 'authz.team.members.subtable.column.organization.title': {
69
+ id: 'authz.team.members.subtable.column.organization.title',
70
+ defaultMessage: 'Organization',
71
+ description: 'Organization column header of the nested assignments table inside an expanded team member row',
72
+ },
73
+ 'authz.team.members.subtable.showing.text': {
74
+ id: 'authz.team.members.subtable.showing.text',
75
+ defaultMessage: 'Showing {shown} of {total}',
76
+ description: 'Footer of the nested assignments table stating how many of the user total number of roles are listed',
77
+ },
78
+ 'authz.team.members.subtable.view.all.roles': {
79
+ id: 'authz.team.members.subtable.view.all.roles',
80
+ defaultMessage: 'View all roles',
81
+ description: 'Link taking the user to the full profile listing every role assigned to a team member',
82
+ },
83
+ 'authz.team.members.table.showing.users.text': {
84
+ id: 'authz.team.members.table.showing.users.text',
85
+ defaultMessage: 'Showing {pageSize, plural, one {# user} other {# users}} of {itemCount}.',
86
+ description: 'Text stating how many team members are listed on the current page out of the total count',
87
+ },
33
88
  });
34
89
  export default messages;
35
90
  //# sourceMappingURL=messages.js.map