@openedx/frontend-app-admin-console 1.0.0-alpha.0 → 1.0.0-alpha.10

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 (112) hide show
  1. package/dist/authz-module/audit-user/index.js +5 -9
  2. package/dist/authz-module/audit-user/index.js.map +1 -1
  3. package/dist/authz-module/authz-home/index.js +21 -2
  4. package/dist/authz-module/authz-home/index.js.map +1 -1
  5. package/dist/authz-module/components/AddRoleButton.js +1 -1
  6. package/dist/authz-module/components/AddRoleButton.js.map +1 -1
  7. package/dist/authz-module/components/AuthZLayout.d.ts +7 -6
  8. package/dist/authz-module/components/AuthZLayout.js +9 -3
  9. package/dist/authz-module/components/AuthZLayout.js.map +1 -1
  10. package/dist/authz-module/components/AuthZTitle.d.ts +3 -2
  11. package/dist/authz-module/components/AuthZTitle.js +9 -7
  12. package/dist/authz-module/components/AuthZTitle.js.map +1 -1
  13. package/dist/authz-module/components/ExpandableButton.d.ts +17 -0
  14. package/dist/authz-module/components/ExpandableButton.js +16 -0
  15. package/dist/authz-module/components/ExpandableButton.js.map +1 -0
  16. package/dist/authz-module/components/PermissionTable.js +5 -1
  17. package/dist/authz-module/components/PermissionTable.js.map +1 -1
  18. package/dist/authz-module/components/TableCells.d.ts +5 -8
  19. package/dist/authz-module/components/TableCells.js +26 -59
  20. package/dist/authz-module/components/TableCells.js.map +1 -1
  21. package/dist/authz-module/components/TableControlBar/MultipleChoiceFilter.d.ts +1 -1
  22. package/dist/authz-module/components/TableControlBar/MultipleChoiceFilter.js +4 -3
  23. package/dist/authz-module/components/TableControlBar/MultipleChoiceFilter.js.map +1 -1
  24. package/dist/authz-module/components/TableControlBar/OrgFilter.js +2 -2
  25. package/dist/authz-module/components/TableControlBar/OrgFilter.js.map +1 -1
  26. package/dist/authz-module/components/TableControlBar/SearchFilter.d.ts +2 -1
  27. package/dist/authz-module/components/TableControlBar/SearchFilter.js +2 -1
  28. package/dist/authz-module/components/TableControlBar/SearchFilter.js.map +1 -1
  29. package/dist/authz-module/components/TableControlBar/TableControlBar.d.ts +4 -1
  30. package/dist/authz-module/components/TableControlBar/TableControlBar.js +24 -24
  31. package/dist/authz-module/components/TableControlBar/TableControlBar.js.map +1 -1
  32. package/dist/authz-module/components/TableControlBar/types.d.ts +1 -0
  33. package/dist/authz-module/components/TableControlBar/types.js.map +1 -1
  34. package/dist/authz-module/components/TableFooter/TableFooter.d.ts +14 -1
  35. package/dist/authz-module/components/TableFooter/TableFooter.js +3 -2
  36. package/dist/authz-module/components/TableFooter/TableFooter.js.map +1 -1
  37. package/dist/authz-module/components/constants.d.ts +1 -0
  38. package/dist/authz-module/components/constants.js +2 -1
  39. package/dist/authz-module/components/constants.js.map +1 -1
  40. package/dist/authz-module/components/messages.d.ts +0 -5
  41. package/dist/authz-module/components/messages.js +2 -7
  42. package/dist/authz-module/components/messages.js.map +1 -1
  43. package/dist/authz-module/constants.d.ts +18 -8
  44. package/dist/authz-module/constants.js +30 -11
  45. package/dist/authz-module/constants.js.map +1 -1
  46. package/dist/authz-module/data/api.d.ts +12 -4
  47. package/dist/authz-module/data/api.js +11 -2
  48. package/dist/authz-module/data/api.js.map +1 -1
  49. package/dist/authz-module/data/hooks.d.ts +8 -8
  50. package/dist/authz-module/data/hooks.js +15 -20
  51. package/dist/authz-module/data/hooks.js.map +1 -1
  52. package/dist/authz-module/hooks/useExclusiveRowExpansion.d.ts +7 -0
  53. package/dist/authz-module/hooks/useExclusiveRowExpansion.js +24 -0
  54. package/dist/authz-module/hooks/useExclusiveRowExpansion.js.map +1 -0
  55. package/dist/authz-module/index.scss +150 -13
  56. package/dist/authz-module/messages.d.ts +23 -0
  57. package/dist/authz-module/messages.js +18 -0
  58. package/dist/authz-module/messages.js.map +1 -1
  59. package/dist/authz-module/role-assignation-wizard/AssignRoleWizard.js +1 -1
  60. package/dist/authz-module/role-assignation-wizard/AssignRoleWizard.js.map +1 -1
  61. package/dist/authz-module/role-assignation-wizard/AssignRoleWizardPage.js +4 -4
  62. package/dist/authz-module/role-assignation-wizard/AssignRoleWizardPage.js.map +1 -1
  63. package/dist/authz-module/role-assignation-wizard/components/ScopeFilterBar.js +1 -1
  64. package/dist/authz-module/role-assignation-wizard/components/ScopeFilterBar.js.map +1 -1
  65. package/dist/authz-module/role-assignation-wizard/hooks/useScopeListData.js.map +1 -1
  66. package/dist/authz-module/roles-permissions/RolesPermissions.js +3 -3
  67. package/dist/authz-module/roles-permissions/RolesPermissions.js.map +1 -1
  68. package/dist/authz-module/team-members/TeamMembersTable.js +102 -58
  69. package/dist/authz-module/team-members/TeamMembersTable.js.map +1 -1
  70. package/dist/authz-module/team-members/components/AssignedRolesCell.d.ts +20 -0
  71. package/dist/authz-module/team-members/components/AssignedRolesCell.js +54 -0
  72. package/dist/authz-module/team-members/components/AssignedRolesCell.js.map +1 -0
  73. package/dist/authz-module/team-members/components/MoreRolesToggle.d.ts +14 -0
  74. package/dist/authz-module/team-members/components/MoreRolesToggle.js +25 -0
  75. package/dist/authz-module/team-members/components/MoreRolesToggle.js.map +1 -0
  76. package/dist/authz-module/team-members/components/TeamMemberCells.d.ts +17 -0
  77. package/dist/authz-module/team-members/components/TeamMemberCells.js +21 -0
  78. package/dist/authz-module/team-members/components/TeamMemberCells.js.map +1 -0
  79. package/dist/authz-module/team-members/components/TeamMemberViewActionCell.d.ts +18 -0
  80. package/dist/authz-module/team-members/components/TeamMemberViewActionCell.js +42 -0
  81. package/dist/authz-module/team-members/components/TeamMemberViewActionCell.js.map +1 -0
  82. package/dist/authz-module/team-members/components/UserAssignmentsSubTable.d.ts +16 -0
  83. package/dist/authz-module/team-members/components/UserAssignmentsSubTable.js +74 -0
  84. package/dist/authz-module/team-members/components/UserAssignmentsSubTable.js.map +1 -0
  85. package/dist/authz-module/team-members/index.d.ts +1 -0
  86. package/dist/authz-module/team-members/index.js +2 -0
  87. package/dist/authz-module/team-members/index.js.map +1 -0
  88. package/dist/authz-module/team-members/messages.d.ts +56 -1
  89. package/dist/authz-module/team-members/messages.js +59 -4
  90. package/dist/authz-module/team-members/messages.js.map +1 -1
  91. package/dist/authz-module/utils.d.ts +6 -0
  92. package/dist/authz-module/utils.js +12 -10
  93. package/dist/authz-module/utils.js.map +1 -1
  94. package/dist/components/LoadingPage.d.ts +3 -0
  95. package/dist/components/LoadingPage.js +9 -1
  96. package/dist/components/LoadingPage.js.map +1 -1
  97. package/dist/components/messages.d.ts +8 -0
  98. package/dist/components/messages.js +10 -0
  99. package/dist/components/messages.js.map +1 -0
  100. package/dist/index.d.ts +0 -1
  101. package/dist/index.js +0 -1
  102. package/dist/index.js.map +1 -1
  103. package/dist/routes.d.ts +3 -1
  104. package/dist/routes.js +17 -4
  105. package/dist/routes.js.map +1 -1
  106. package/dist/style.scss +19 -2
  107. package/dist/types.d.ts +29 -20
  108. package/dist/types.js.map +1 -1
  109. package/package.json +6 -3
  110. package/dist/authz-module/components/ViewMoreLink.d.ts +0 -8
  111. package/dist/authz-module/components/ViewMoreLink.js +0 -8
  112. package/dist/authz-module/components/ViewMoreLink.js.map +0 -1
@@ -10,65 +10,47 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
- import { SiteContext, useIntl } from '@openedx/frontend-base';
14
- import { RemoveRedEye, Delete, ExpandMore, Info, } from '@openedx/paragon/icons';
15
- import { useNavigate } from 'react-router-dom';
16
- import { useContext, useMemo } from 'react';
17
- import { ADMIN_ROLES, DJANGO_MANAGED_ROLES, MAP_ROLE_KEY_TO_LABEL, } from '../constants';
18
- import { Icon, IconButton, OverlayTrigger, Tooltip, DataTableContext, } from '@openedx/paragon';
13
+ import { useIntl } from '@openedx/frontend-base';
14
+ import { Delete, Info, } from '@openedx/paragon/icons';
15
+ import { useMemo } from 'react';
16
+ import { ADMIN_ROLES, ALL_ORGS_KEY, DJANGO_MANAGED_ROLES, getAggregateScopeType, getScopeContextType, MAP_ROLE_KEY_TO_LABEL, } from '../constants';
17
+ import { Icon, IconButton, OverlayTrigger, Tooltip, } from '@openedx/paragon';
18
+ import { useExclusiveRowExpansion } from '../hooks/useExclusiveRowExpansion';
19
+ import { getScopeResourceIcon } from '../utils';
20
+ import { AGGREGATE_SCOPE_LABELS } from '../messages';
19
21
  import { RESOURCE_ICONS } from './constants';
20
22
  import messages from './messages';
21
- import ViewMoreLink from './ViewMoreLink';
23
+ import ExpandableButton from './ExpandableButton';
22
24
  // A disabled button can't trigger its own tooltip (Paragon sets pointer-events: none on it),
23
25
  // so the OverlayTrigger must live on a wrapper element that still receives hover events.
24
- const DisabledCourseActionButton = ({ src, alt, size, variant, }) => {
26
+ export const DisabledCourseActionButton = ({ src, alt, size, variant, }) => {
25
27
  const { formatMessage } = useIntl();
26
28
  return (_jsx(OverlayTrigger, { placement: "left", overlay: (_jsx(Tooltip, { variant: "light", id: "tooltip-left", children: formatMessage(messages['authz.table.actions.course.disabled.tooltip']) })), children: _jsx("span", { className: "d-inline-block", children: _jsx(IconButton, { src: src, alt: alt, size: size, variant: variant, disabled: true }) }) }));
27
29
  };
28
- const NameCell = ({ row }) => {
29
- const intl = useIntl();
30
- const { authenticatedUser } = useContext(SiteContext);
31
- const username = authenticatedUser === null || authenticatedUser === void 0 ? void 0 : authenticatedUser.username;
32
- if (row.original.username === username) {
33
- return (_jsxs("span", { children: [row.original.fullName || row.original.username, _jsx("span", { className: "text-gray-500", children: intl.formatMessage(messages['authz.table.username.current']) })] }));
34
- }
35
- return _jsx("span", { children: row.original.fullName || row.original.username || '' });
36
- };
37
- const ViewActionCell = ({ row, isCourseEnabled }) => {
38
- var _a;
39
- const { formatMessage } = useIntl();
40
- const navigate = useNavigate();
41
- const viewPath = `/authz/user/${row.original.username}`;
42
- const isCourseScope = !((_a = row.original.role) === null || _a === void 0 ? void 0 : _a.startsWith('lib')) && !DJANGO_MANAGED_ROLES.includes(row.original.role);
43
- const isDisabled = isCourseEnabled !== undefined && isCourseScope && !isCourseEnabled(row.original.scope);
44
- if (isDisabled) {
45
- return (_jsx(DisabledCourseActionButton, { src: RemoveRedEye, alt: formatMessage(messages['authz.table.column.actions.view.title']), size: "sm" }));
46
- }
47
- return (_jsx(IconButton, { src: RemoveRedEye, alt: formatMessage(messages['authz.table.column.actions.view.title']), size: "sm", onClick: () => navigate(viewPath) }));
48
- };
49
- const createViewActionCell = (extraProps) => function customViewActionCell(cellProps) {
50
- return _jsx(ViewActionCell, Object.assign({}, cellProps, extraProps));
51
- };
52
30
  const OrgCell = ({ value, row }) => {
53
31
  const { formatMessage } = useIntl();
54
- return (_jsx("span", { children: DJANGO_MANAGED_ROLES.includes(row.original.role) ? formatMessage(messages['authz.user.table.org.all.organizations.label']) : value }));
32
+ // The backend returns '*' as the org wildcard, meaning the role spans every organization.
33
+ const isAllOrgs = DJANGO_MANAGED_ROLES.includes(row.original.role) || value === ALL_ORGS_KEY;
34
+ return (_jsx("span", { children: isAllOrgs ? formatMessage(messages['authz.user.table.org.all.organizations.label']) : value }));
55
35
  };
56
36
  const ScopeCell = ({ row }) => {
57
37
  const { formatMessage } = useIntl();
58
38
  const { scopeText, iconSrc } = useMemo(() => {
59
- var _a;
60
- if (DJANGO_MANAGED_ROLES.includes(row.original.role)) {
39
+ const { role, scope, org } = row.original;
40
+ if (DJANGO_MANAGED_ROLES.includes(role)) {
61
41
  return {
62
42
  scopeText: formatMessage(messages['authz.user.table.scope.global.label']),
63
43
  iconSrc: RESOURCE_ICONS.GLOBAL,
64
44
  };
65
45
  }
66
- const scopeIcon = ((_a = row.original.role) === null || _a === void 0 ? void 0 : _a.startsWith('lib')) ? RESOURCE_ICONS.LIBRARY : RESOURCE_ICONS.COURSE;
46
+ const aggregateType = getAggregateScopeType(scope, org);
67
47
  return {
68
- scopeText: row.original.scope,
69
- iconSrc: scopeIcon,
48
+ scopeText: aggregateType
49
+ ? formatMessage(AGGREGATE_SCOPE_LABELS[getScopeContextType(scope)])
50
+ : scope,
51
+ iconSrc: getScopeResourceIcon(scope),
70
52
  };
71
- }, [row.original.role, row.original.scope, formatMessage]);
53
+ }, [row.original, formatMessage]);
72
54
  return (_jsxs("span", { className: "d-flex align-items-center", children: [iconSrc && _jsx(Icon, { color: "primary", src: iconSrc, className: "mr-2", size: "xs" }), scopeText] }));
73
55
  };
74
56
  const RoleCell = ({ value, cell }) => {
@@ -85,25 +67,10 @@ const PermissionsCell = ({ row }) => {
85
67
  };
86
68
  const ViewAllPermissionsCell = ({ row }) => {
87
69
  const { formatMessage } = useIntl();
88
- const instance = useContext(DataTableContext);
89
- const handleToggleExpanded = () => {
90
- var _a, _b;
91
- if (!row.isExpanded && instance) {
92
- // Close all other expanded rows first
93
- const expanded = ((_a = instance.state) === null || _a === void 0 ? void 0 : _a.expanded) || {};
94
- Object.keys(expanded).forEach(rowId => {
95
- var _a;
96
- if (rowId !== row.id && expanded[rowId]) {
97
- (_a = instance.toggleRowExpanded) === null || _a === void 0 ? void 0 : _a.call(instance, rowId, false);
98
- }
99
- });
100
- }
101
- // Toggle the current row
102
- (_b = row.toggleRowExpanded) === null || _b === void 0 ? void 0 : _b.call(row);
103
- };
104
- return (_jsx("div", { role: "button", children: _jsx(ViewMoreLink, { label: formatMessage(row.isExpanded
105
- ? messages['authz.user.table.view_all_permissions.link.text.close']
106
- : messages['authz.user.table.view_all_permissions.link.text.open']), onClick: handleToggleExpanded, iconSrc: ExpandMore }) }));
70
+ const toggleExpanded = useExclusiveRowExpansion(row);
71
+ return (_jsx(ExpandableButton, { label: formatMessage(row.isExpanded
72
+ ? messages['authz.user.table.view_all_permissions.link.text.close']
73
+ : messages['authz.user.table.view_all_permissions.link.text.open']), onClick: toggleExpanded, isExpanded: !!row.isExpanded }));
107
74
  };
108
75
  const ActionsCell = ({ row, onClickDeleteButton, isUserAuthenticatedPage, isCourseEnabled, }) => {
109
76
  const { formatMessage } = useIntl();
@@ -133,5 +100,5 @@ const ActionsCell = ({ row, onClickDeleteButton, isUserAuthenticatedPage, isCour
133
100
  const createActionsCell = (extraProps) => function customActionsCell(cellProps) {
134
101
  return _jsx(ActionsCell, Object.assign({}, cellProps, extraProps));
135
102
  };
136
- export { NameCell, ViewActionCell, RoleCell, OrgCell, ScopeCell, PermissionsCell, ViewAllPermissionsCell, createActionsCell, createViewActionCell, };
103
+ export { RoleCell, OrgCell, ScopeCell, PermissionsCell, ViewAllPermissionsCell, createActionsCell, };
137
104
  //# sourceMappingURL=TableCells.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TableCells.js","sourceRoot":"","sources":["../../../src/authz-module/components/TableCells.tsx"],"names":[],"mappings":"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","sourcesContent":["import { SiteContext, useIntl } from '@openedx/frontend-base';\nimport {\n RemoveRedEye,\n Delete, ExpandMore,\n Info,\n} from '@openedx/paragon/icons';\nimport { UserRoleWithPermissions, RoleToDelete } from '@src/types';\nimport { useNavigate } from 'react-router-dom';\nimport { useContext, useMemo, type ComponentProps } from 'react';\nimport {\n ADMIN_ROLES, DJANGO_MANAGED_ROLES, MAP_ROLE_KEY_TO_LABEL,\n} from '@src/authz-module/constants';\nimport {\n Icon, IconButton, OverlayTrigger, Tooltip, DataTableContext,\n type DataTableCellProps,\n} from '@openedx/paragon';\nimport { RESOURCE_ICONS } from './constants';\nimport messages from './messages';\nimport ViewMoreLink from './ViewMoreLink';\n\ninterface ViewActionCellExtraProps {\n isCourseEnabled: (scope: string) => boolean;\n}\n\ninterface DataTableInstance {\n state?: {\n expanded?: Record<string, boolean>;\n };\n toggleRowExpanded?: (rowId: string, expanded: boolean) => void;\n}\n\ntype CellProps = DataTableCellProps<UserRoleWithPermissions>;\ntype CellPropsWithValue = CellProps & {\n value: string;\n};\ntype ExtendedCellProps = CellPropsWithValue & {\n cell: {\n getCellProps: (props?: Record<string, string>) => Record<string, string>;\n };\n};\n\ninterface ActionsCellExtraProps {\n onClickDeleteButton: (role: RoleToDelete) => void;\n isUserAuthenticatedPage: boolean;\n isCourseEnabled?: (scope: string) => boolean;\n}\n\ntype ActionsCellProps = CellProps & ActionsCellExtraProps;\n\ntype DisabledCourseActionButtonProps = Pick<ComponentProps<typeof IconButton>, 'src' | 'alt' | 'size' | 'variant'>;\n\n// A disabled button can't trigger its own tooltip (Paragon sets pointer-events: none on it),\n// so the OverlayTrigger must live on a wrapper element that still receives hover events.\nconst DisabledCourseActionButton = ({\n src, alt, size, variant,\n}: DisabledCourseActionButtonProps) => {\n const { formatMessage } = useIntl();\n return (\n <OverlayTrigger\n placement=\"left\"\n overlay={(\n <Tooltip variant=\"light\" id=\"tooltip-left\">\n {formatMessage(messages['authz.table.actions.course.disabled.tooltip'])}\n </Tooltip>\n )}\n >\n <span className=\"d-inline-block\">\n <IconButton\n src={src}\n alt={alt}\n size={size}\n variant={variant}\n disabled\n />\n </span>\n </OverlayTrigger>\n );\n};\n\nconst NameCell = ({ row }: CellProps) => {\n const intl = useIntl();\n const { authenticatedUser } = useContext(SiteContext);\n const username = authenticatedUser?.username;\n\n if (row.original.username === username) {\n return (\n <span>\n {row.original.fullName || row.original.username}\n <span className=\"text-gray-500\">{intl.formatMessage(messages['authz.table.username.current'])}</span>\n </span>\n );\n }\n return <span>{row.original.fullName || row.original.username || ''}</span>;\n};\n\nconst ViewActionCell = ({ row, isCourseEnabled }: CellProps & Partial<ViewActionCellExtraProps>) => {\n const { formatMessage } = useIntl();\n const navigate = useNavigate();\n const viewPath = `/authz/user/${row.original.username}`;\n const isCourseScope = !row.original.role?.startsWith('lib') && !DJANGO_MANAGED_ROLES.includes(row.original.role);\n const isDisabled = isCourseEnabled !== undefined && isCourseScope && !isCourseEnabled(row.original.scope);\n\n if (isDisabled) {\n return (\n <DisabledCourseActionButton\n src={RemoveRedEye}\n alt={formatMessage(messages['authz.table.column.actions.view.title'])}\n size=\"sm\"\n />\n );\n }\n\n return (\n <IconButton\n src={RemoveRedEye}\n alt={formatMessage(messages['authz.table.column.actions.view.title'])}\n size=\"sm\"\n onClick={() => navigate(viewPath)}\n />\n );\n};\n\nconst createViewActionCell = (extraProps: ViewActionCellExtraProps) => function customViewActionCell(cellProps) {\n return <ViewActionCell {...cellProps} {...extraProps} />;\n};\n\nconst OrgCell = ({ value, row }: CellPropsWithValue) => {\n const { formatMessage } = useIntl();\n return (\n <span>\n {DJANGO_MANAGED_ROLES.includes(row.original.role) ? formatMessage(messages['authz.user.table.org.all.organizations.label']) : value}\n </span>\n );\n};\n\nconst ScopeCell = ({ row }: CellProps) => {\n const { formatMessage } = useIntl();\n\n const { scopeText, iconSrc } = useMemo(() => {\n if (DJANGO_MANAGED_ROLES.includes(row.original.role)) {\n return {\n scopeText: formatMessage(messages['authz.user.table.scope.global.label']),\n iconSrc: RESOURCE_ICONS.GLOBAL,\n };\n }\n const scopeIcon = row.original.role?.startsWith('lib') ? RESOURCE_ICONS.LIBRARY : RESOURCE_ICONS.COURSE;\n return {\n scopeText: row.original.scope,\n iconSrc: scopeIcon,\n };\n }, [row.original.role, row.original.scope, formatMessage]);\n\n return (\n <span className=\"d-flex align-items-center\">\n {iconSrc && <Icon color=\"primary\" src={iconSrc} className=\"mr-2\" size=\"xs\" />}\n {scopeText}\n </span>\n );\n};\n\nconst RoleCell = ({ value, cell }: ExtendedCellProps) => {\n const { key, ...cellProps } = cell.getCellProps({ 'data-role': MAP_ROLE_KEY_TO_LABEL[value] || '' });\n return (\n <span key={key} {...cellProps}>\n {MAP_ROLE_KEY_TO_LABEL[value] || ''}\n </span>\n );\n};\n\nconst PermissionsCell = ({ row }: CellProps) => {\n const { formatMessage } = useIntl();\n const { role, permissionCount: count } = row.original;\n const isDjangoRole = DJANGO_MANAGED_ROLES.includes(role);\n return (\n <span>\n { isDjangoRole\n ? formatMessage(\n messages['authz.user.table.permissions.access.label'],\n { accessType: role === 'django.superuser' ? 'total' : 'partial' },\n )\n : formatMessage(messages['authz.user.table.permissions.available.count'], { count })}\n </span>\n );\n};\n\nconst ViewAllPermissionsCell = ({ row }: CellProps) => {\n const { formatMessage } = useIntl();\n const instance = useContext(DataTableContext) as DataTableInstance;\n const handleToggleExpanded = () => {\n if (!row.isExpanded && instance) {\n // Close all other expanded rows first\n const expanded = instance.state?.expanded || {};\n Object.keys(expanded).forEach(rowId => {\n if (rowId !== row.id && expanded[rowId]) {\n instance.toggleRowExpanded?.(rowId, false);\n }\n });\n }\n // Toggle the current row\n row.toggleRowExpanded?.();\n };\n\n return (\n <div role=\"button\">\n <ViewMoreLink\n label={formatMessage(\n row.isExpanded\n ? messages['authz.user.table.view_all_permissions.link.text.close']\n : messages['authz.user.table.view_all_permissions.link.text.open'],\n )}\n onClick={handleToggleExpanded}\n iconSrc={ExpandMore}\n />\n </div>\n );\n};\n\nconst ActionsCell = ({\n row, onClickDeleteButton, isUserAuthenticatedPage, isCourseEnabled,\n}: ActionsCellProps) => {\n const { formatMessage } = useIntl();\n const { role, canManageScope } = row.original;\n\n const handleDelete = () => {\n const roleToDelete = {\n role,\n scope: row.original.scope,\n name: MAP_ROLE_KEY_TO_LABEL[role] || '',\n } as RoleToDelete;\n onClickDeleteButton(roleToDelete);\n };\n\n if (DJANGO_MANAGED_ROLES.includes(role)) {\n return (\n <OverlayTrigger\n placement=\"left\"\n overlay={(\n <Tooltip variant=\"light\" id=\"tooltip-left\">\n {formatMessage(messages['authz.user.table.delete.action.djangorole.tooltip'])}\n </Tooltip>\n )}\n >\n <Icon\n className=\"mx-2 pl-1\"\n src={Info}\n />\n </OverlayTrigger>\n );\n }\n\n if (ADMIN_ROLES.includes(role) && isUserAuthenticatedPage) {\n return (\n <OverlayTrigger\n placement=\"left\"\n overlay={(\n <Tooltip variant=\"light\" id=\"tooltip-left\">\n {formatMessage(messages['authz.user.table.delete.action.adminrole.tooltip'])}\n </Tooltip>\n )}\n >\n <Icon\n className=\"mx-2 pl-1 text-light-500\"\n src={Delete}\n />\n </OverlayTrigger>\n );\n }\n\n const isCourseScope = !role?.startsWith('lib');\n const isCourseAuthoringDisabled = isCourseEnabled !== undefined\n && isCourseScope && !isCourseEnabled(row.original.scope);\n\n if (isCourseAuthoringDisabled) {\n return (\n <DisabledCourseActionButton\n src={Delete}\n alt={formatMessage(messages['authz.user.table.delete.action.alt'])}\n variant=\"light\"\n />\n );\n }\n\n return (\n <IconButton\n disabled={!canManageScope}\n variant={canManageScope ? 'danger' : 'light'}\n onClick={handleDelete}\n alt={formatMessage(messages['authz.user.table.delete.action.alt'])}\n src={Delete}\n />\n );\n};\n\nconst createActionsCell = (extraProps: ActionsCellExtraProps) => function customActionsCell(cellProps) {\n return <ActionsCell {...cellProps} {...extraProps} />;\n};\n\nexport {\n NameCell,\n ViewActionCell,\n RoleCell,\n OrgCell,\n ScopeCell,\n PermissionsCell,\n ViewAllPermissionsCell,\n createActionsCell,\n createViewActionCell,\n};\n"]}
1
+ {"version":3,"file":"TableCells.js","sourceRoot":"","sources":["../../../src/authz-module/components/TableCells.tsx"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EACL,MAAM,EACN,IAAI,GACL,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,OAAO,EAAuB,MAAM,OAAO,CAAC;AACrD,OAAO,EACL,WAAW,EAAE,YAAY,EAAE,oBAAoB,EAAE,qBAAqB,EACtE,mBAAmB,EAAE,qBAAqB,GAC3C,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,OAAO,GAE1C,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,wBAAwB,EAAE,MAAM,kDAAkD,CAAC;AAC5F,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAsBlD,6FAA6F;AAC7F,yFAAyF;AACzF,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,EACzC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,GACS,EAAE,EAAE;IACpC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,OAAO,CACL,KAAC,cAAc,IACb,SAAS,EAAC,MAAM,EAChB,OAAO,EAAE,CACP,KAAC,OAAO,IAAC,OAAO,EAAC,OAAO,EAAC,EAAE,EAAC,cAAc,YACvC,aAAa,CAAC,QAAQ,CAAC,6CAA6C,CAAC,CAAC,GAC/D,CACX,YAED,eAAM,SAAS,EAAC,gBAAgB,YAC9B,KAAC,UAAU,IACT,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,QAAQ,SACR,GACG,GACQ,CAClB,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,OAAO,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,EAAsB,EAAE,EAAE;IACrD,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,0FAA0F;IAC1F,MAAM,SAAS,GAAG,oBAAoB,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,YAAY,CAAC;IAC7F,OAAO,CACL,yBACG,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,8CAA8C,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GACvF,CACR,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,EAAE,GAAG,EAAa,EAAE,EAAE;IACvC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IAEpC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE;QAC1C,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,QAAQ,CAAC;QAC1C,IAAI,oBAAoB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,OAAO;gBACL,SAAS,EAAE,aAAa,CAAC,QAAQ,CAAC,qCAAqC,CAAC,CAAC;gBACzE,OAAO,EAAE,cAAc,CAAC,MAAM;aAC/B,CAAC;QACJ,CAAC;QACD,MAAM,aAAa,GAAG,qBAAqB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACxD,OAAO;YACL,SAAS,EAAE,aAAa;gBACtB,CAAC,CAAC,aAAa,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;gBACnE,CAAC,CAAC,KAAK;YACT,OAAO,EAAE,oBAAoB,CAAC,KAAK,CAAC;SACrC,CAAC;IACJ,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC;IAElC,OAAO,CACL,gBAAM,SAAS,EAAC,2BAA2B,aACxC,OAAO,IAAI,KAAC,IAAI,IAAC,KAAK,EAAC,SAAS,EAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAC,MAAM,EAAC,IAAI,EAAC,IAAI,GAAG,EAC5E,SAAS,IACL,CACR,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAqB,EAAE,EAAE;IACtD,MAAM,KAAwB,IAAI,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,qBAAqB,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,EAA9F,EAAE,GAAG,OAAyF,EAApF,SAAS,cAAnB,OAAqB,CAAyE,CAAC;IACrG,OAAO,CACL,+BAAoB,SAAS,cAC1B,qBAAqB,CAAC,KAAK,CAAC,IAAI,EAAE,KAD1B,GAAG,CAEP,CACR,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,EAAE,GAAG,EAAa,EAAE,EAAE;IAC7C,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,QAAQ,CAAC;IACtD,MAAM,YAAY,GAAG,oBAAoB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACzD,OAAO,CACL,yBACI,YAAY;YACZ,CAAC,CAAC,aAAa,CACX,QAAQ,CAAC,2CAA2C,CAAC,EACrD,EAAE,UAAU,EAAE,IAAI,KAAK,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAClE;YACH,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,8CAA8C,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,GACjF,CACR,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,sBAAsB,GAAG,CAAC,EAAE,GAAG,EAAa,EAAE,EAAE;IACpD,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,cAAc,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;IAErD,OAAO,CACL,KAAC,gBAAgB,IACf,KAAK,EAAE,aAAa,CAClB,GAAG,CAAC,UAAU;YACZ,CAAC,CAAC,QAAQ,CAAC,uDAAuD,CAAC;YACnE,CAAC,CAAC,QAAQ,CAAC,sDAAsD,CAAC,CACrE,EACD,OAAO,EAAE,cAAc,EACvB,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,GAC5B,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,EACnB,GAAG,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,eAAe,GACjD,EAAE,EAAE;IACrB,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,GAAG,CAAC,QAAQ,CAAC;IAE9C,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,MAAM,YAAY,GAAG;YACnB,IAAI;YACJ,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK;YACzB,IAAI,EAAE,qBAAqB,CAAC,IAAI,CAAC,IAAI,EAAE;SACxB,CAAC;QAClB,mBAAmB,CAAC,YAAY,CAAC,CAAC;IACpC,CAAC,CAAC;IAEF,IAAI,oBAAoB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,OAAO,CACL,KAAC,cAAc,IACb,SAAS,EAAC,MAAM,EAChB,OAAO,EAAE,CACP,KAAC,OAAO,IAAC,OAAO,EAAC,OAAO,EAAC,EAAE,EAAC,cAAc,YACvC,aAAa,CAAC,QAAQ,CAAC,mDAAmD,CAAC,CAAC,GACrE,CACX,YAED,KAAC,IAAI,IACH,SAAS,EAAC,WAAW,EACrB,GAAG,EAAE,IAAI,GACT,GACa,CAClB,CAAC;IACJ,CAAC;IAED,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,uBAAuB,EAAE,CAAC;QAC1D,OAAO,CACL,KAAC,cAAc,IACb,SAAS,EAAC,MAAM,EAChB,OAAO,EAAE,CACP,KAAC,OAAO,IAAC,OAAO,EAAC,OAAO,EAAC,EAAE,EAAC,cAAc,YACvC,aAAa,CAAC,QAAQ,CAAC,kDAAkD,CAAC,CAAC,GACpE,CACX,YAED,KAAC,IAAI,IACH,SAAS,EAAC,0BAA0B,EACpC,GAAG,EAAE,MAAM,GACX,GACa,CAClB,CAAC;IACJ,CAAC;IAED,MAAM,aAAa,GAAG,CAAC,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,UAAU,CAAC,KAAK,CAAC,CAAA,CAAC;IAC/C,MAAM,yBAAyB,GAAG,eAAe,KAAK,SAAS;WAC1D,aAAa,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE3D,IAAI,yBAAyB,EAAE,CAAC;QAC9B,OAAO,CACL,KAAC,0BAA0B,IACzB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,aAAa,CAAC,QAAQ,CAAC,oCAAoC,CAAC,CAAC,EAClE,OAAO,EAAC,OAAO,GACf,CACH,CAAC;IACJ,CAAC;IAED,OAAO,CACL,KAAC,UAAU,IACT,QAAQ,EAAE,CAAC,cAAc,EACzB,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAC5C,OAAO,EAAE,YAAY,EACrB,GAAG,EAAE,aAAa,CAAC,QAAQ,CAAC,oCAAoC,CAAC,CAAC,EAClE,GAAG,EAAE,MAAM,GACX,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,UAAiC,EAAE,EAAE,CAAC,SAAS,iBAAiB,CAAC,SAAS;IACnG,OAAO,KAAC,WAAW,oBAAK,SAAS,EAAM,UAAU,EAAI,CAAC;AACxD,CAAC,CAAC;AAEF,OAAO,EACL,QAAQ,EACR,OAAO,EACP,SAAS,EACT,eAAe,EACf,sBAAsB,EACtB,iBAAiB,GAClB,CAAC","sourcesContent":["import { useIntl } from '@openedx/frontend-base';\nimport {\n Delete,\n Info,\n} from '@openedx/paragon/icons';\nimport { UserRoleWithPermissions, RoleToDelete } from '@src/types';\nimport { useMemo, type ComponentProps } from 'react';\nimport {\n ADMIN_ROLES, ALL_ORGS_KEY, DJANGO_MANAGED_ROLES, getAggregateScopeType,\n getScopeContextType, MAP_ROLE_KEY_TO_LABEL,\n} from '@src/authz-module/constants';\nimport {\n Icon, IconButton, OverlayTrigger, Tooltip,\n type DataTableCellProps,\n} from '@openedx/paragon';\nimport { useExclusiveRowExpansion } from '@src/authz-module/hooks/useExclusiveRowExpansion';\nimport { getScopeResourceIcon } from '@src/authz-module/utils';\nimport { AGGREGATE_SCOPE_LABELS } from '@src/authz-module/messages';\nimport { RESOURCE_ICONS } from './constants';\nimport messages from './messages';\nimport ExpandableButton from './ExpandableButton';\n\ntype CellProps = DataTableCellProps<UserRoleWithPermissions>;\ntype CellPropsWithValue = CellProps & {\n value: string;\n};\ntype ExtendedCellProps = CellPropsWithValue & {\n cell: {\n getCellProps: (props?: Record<string, string>) => Record<string, string>;\n };\n};\n\ninterface ActionsCellExtraProps {\n onClickDeleteButton: (role: RoleToDelete) => void;\n isUserAuthenticatedPage: boolean;\n isCourseEnabled?: (scope: string) => boolean;\n}\n\ntype ActionsCellProps = CellProps & ActionsCellExtraProps;\n\ntype DisabledCourseActionButtonProps = Pick<ComponentProps<typeof IconButton>, 'src' | 'alt' | 'size' | 'variant'>;\n\n// A disabled button can't trigger its own tooltip (Paragon sets pointer-events: none on it),\n// so the OverlayTrigger must live on a wrapper element that still receives hover events.\nexport const DisabledCourseActionButton = ({\n src, alt, size, variant,\n}: DisabledCourseActionButtonProps) => {\n const { formatMessage } = useIntl();\n return (\n <OverlayTrigger\n placement=\"left\"\n overlay={(\n <Tooltip variant=\"light\" id=\"tooltip-left\">\n {formatMessage(messages['authz.table.actions.course.disabled.tooltip'])}\n </Tooltip>\n )}\n >\n <span className=\"d-inline-block\">\n <IconButton\n src={src}\n alt={alt}\n size={size}\n variant={variant}\n disabled\n />\n </span>\n </OverlayTrigger>\n );\n};\n\nconst OrgCell = ({ value, row }: CellPropsWithValue) => {\n const { formatMessage } = useIntl();\n // The backend returns '*' as the org wildcard, meaning the role spans every organization.\n const isAllOrgs = DJANGO_MANAGED_ROLES.includes(row.original.role) || value === ALL_ORGS_KEY;\n return (\n <span>\n {isAllOrgs ? formatMessage(messages['authz.user.table.org.all.organizations.label']) : value}\n </span>\n );\n};\n\nconst ScopeCell = ({ row }: CellProps) => {\n const { formatMessage } = useIntl();\n\n const { scopeText, iconSrc } = useMemo(() => {\n const { role, scope, org } = row.original;\n if (DJANGO_MANAGED_ROLES.includes(role)) {\n return {\n scopeText: formatMessage(messages['authz.user.table.scope.global.label']),\n iconSrc: RESOURCE_ICONS.GLOBAL,\n };\n }\n const aggregateType = getAggregateScopeType(scope, org);\n return {\n scopeText: aggregateType\n ? formatMessage(AGGREGATE_SCOPE_LABELS[getScopeContextType(scope)])\n : scope,\n iconSrc: getScopeResourceIcon(scope),\n };\n }, [row.original, formatMessage]);\n\n return (\n <span className=\"d-flex align-items-center\">\n {iconSrc && <Icon color=\"primary\" src={iconSrc} className=\"mr-2\" size=\"xs\" />}\n {scopeText}\n </span>\n );\n};\n\nconst RoleCell = ({ value, cell }: ExtendedCellProps) => {\n const { key, ...cellProps } = cell.getCellProps({ 'data-role': MAP_ROLE_KEY_TO_LABEL[value] || '' });\n return (\n <span key={key} {...cellProps}>\n {MAP_ROLE_KEY_TO_LABEL[value] || ''}\n </span>\n );\n};\n\nconst PermissionsCell = ({ row }: CellProps) => {\n const { formatMessage } = useIntl();\n const { role, permissionCount: count } = row.original;\n const isDjangoRole = DJANGO_MANAGED_ROLES.includes(role);\n return (\n <span>\n { isDjangoRole\n ? formatMessage(\n messages['authz.user.table.permissions.access.label'],\n { accessType: role === 'django.superuser' ? 'total' : 'partial' },\n )\n : formatMessage(messages['authz.user.table.permissions.available.count'], { count })}\n </span>\n );\n};\n\nconst ViewAllPermissionsCell = ({ row }: CellProps) => {\n const { formatMessage } = useIntl();\n const toggleExpanded = useExclusiveRowExpansion(row);\n\n return (\n <ExpandableButton\n label={formatMessage(\n row.isExpanded\n ? messages['authz.user.table.view_all_permissions.link.text.close']\n : messages['authz.user.table.view_all_permissions.link.text.open'],\n )}\n onClick={toggleExpanded}\n isExpanded={!!row.isExpanded}\n />\n );\n};\n\nconst ActionsCell = ({\n row, onClickDeleteButton, isUserAuthenticatedPage, isCourseEnabled,\n}: ActionsCellProps) => {\n const { formatMessage } = useIntl();\n const { role, canManageScope } = row.original;\n\n const handleDelete = () => {\n const roleToDelete = {\n role,\n scope: row.original.scope,\n name: MAP_ROLE_KEY_TO_LABEL[role] || '',\n } as RoleToDelete;\n onClickDeleteButton(roleToDelete);\n };\n\n if (DJANGO_MANAGED_ROLES.includes(role)) {\n return (\n <OverlayTrigger\n placement=\"left\"\n overlay={(\n <Tooltip variant=\"light\" id=\"tooltip-left\">\n {formatMessage(messages['authz.user.table.delete.action.djangorole.tooltip'])}\n </Tooltip>\n )}\n >\n <Icon\n className=\"mx-2 pl-1\"\n src={Info}\n />\n </OverlayTrigger>\n );\n }\n\n if (ADMIN_ROLES.includes(role) && isUserAuthenticatedPage) {\n return (\n <OverlayTrigger\n placement=\"left\"\n overlay={(\n <Tooltip variant=\"light\" id=\"tooltip-left\">\n {formatMessage(messages['authz.user.table.delete.action.adminrole.tooltip'])}\n </Tooltip>\n )}\n >\n <Icon\n className=\"mx-2 pl-1 text-light-500\"\n src={Delete}\n />\n </OverlayTrigger>\n );\n }\n\n const isCourseScope = !role?.startsWith('lib');\n const isCourseAuthoringDisabled = isCourseEnabled !== undefined\n && isCourseScope && !isCourseEnabled(row.original.scope);\n\n if (isCourseAuthoringDisabled) {\n return (\n <DisabledCourseActionButton\n src={Delete}\n alt={formatMessage(messages['authz.user.table.delete.action.alt'])}\n variant=\"light\"\n />\n );\n }\n\n return (\n <IconButton\n disabled={!canManageScope}\n variant={canManageScope ? 'danger' : 'light'}\n onClick={handleDelete}\n alt={formatMessage(messages['authz.user.table.delete.action.alt'])}\n src={Delete}\n />\n );\n};\n\nconst createActionsCell = (extraProps: ActionsCellExtraProps) => function customActionsCell(cellProps) {\n return <ActionsCell {...cellProps} {...extraProps} />;\n};\n\nexport {\n RoleCell,\n OrgCell,\n ScopeCell,\n PermissionsCell,\n ViewAllPermissionsCell,\n createActionsCell,\n};\n"]}
@@ -1,3 +1,3 @@
1
1
  import { MultipleChoiceFilterProps } from './types';
2
- declare const MultipleChoiceFilter: ({ filterButtonText, filterChoices, filterValue, setFilter, isGrouped, isSearchable, onSearchChange, iconSrc, disabled, }: MultipleChoiceFilterProps) => import("react").JSX.Element;
2
+ declare const MultipleChoiceFilter: ({ filterButtonText, filterChoices, filterValue, setFilter, isGrouped, isSearchable, onSearchChange, iconSrc, disabled, size, }: MultipleChoiceFilterProps) => import("react").JSX.Element;
3
3
  export default MultipleChoiceFilter;
@@ -4,7 +4,8 @@ import { useIntl } from '@openedx/frontend-base';
4
4
  import { FilterList, Info, Search } from '@openedx/paragon/icons';
5
5
  import { useState } from 'react';
6
6
  import messages from '../messages';
7
- const MultipleChoiceFilter = ({ filterButtonText, filterChoices, filterValue, setFilter, isGrouped = false, isSearchable = false, onSearchChange, iconSrc, disabled = false, }) => {
7
+ import { validateSizeFormControl } from '../../utils';
8
+ const MultipleChoiceFilter = ({ filterButtonText, filterChoices, filterValue, setFilter, isGrouped = false, isSearchable = false, onSearchChange, iconSrc, disabled = false, size = 'sm', }) => {
8
9
  const [searchValue, setSearchValue] = useState(undefined);
9
10
  const { formatMessage } = useIntl();
10
11
  const checkedBoxes = filterValue || [];
@@ -37,10 +38,10 @@ const MultipleChoiceFilter = ({ filterButtonText, filterChoices, filterValue, se
37
38
  }, new Map());
38
39
  return Array.from(groupedFilterChoices.values());
39
40
  };
40
- return (_jsxs(Dropdown, { className: "no-caret-dropdown filters", children: [_jsx(Dropdown.Toggle, { variant: checkedBoxes.length > 0 ? 'primary' : 'outline-primary', children: _jsxs(Stack, { direction: "horizontal", gap: 2, children: [iconSrc && _jsx(Icon, { color: "primary", src: iconSrc }), filterButtonText, checkedBoxes.length > 0 && ` (${checkedBoxes.length})`, _jsx(Icon, { color: "primary", src: FilterList })] }) }), _jsxs(Dropdown.Menu, { children: [isSearchable && (_jsx(Form.Control, { className: "m-1", type: "text", trailingElement: _jsx(Icon, { src: Search }), placeholder: formatMessage(messages['authz.table.controlbar.search']), onChange: (e) => {
41
+ return (_jsxs(Dropdown, { className: "no-caret-dropdown filters", children: [_jsx(Dropdown.Toggle, { variant: checkedBoxes.length > 0 ? 'primary' : 'outline-primary', size: size, children: _jsxs(Stack, { direction: "horizontal", gap: 2, children: [iconSrc && _jsx(Icon, { color: "primary", src: iconSrc }), filterButtonText, checkedBoxes.length > 0 && ` (${checkedBoxes.length})`, _jsx(Icon, { color: "primary", src: FilterList })] }) }), _jsxs(Dropdown.Menu, { children: [isSearchable && (_jsx(Form.Control, { className: "m-1", type: "text", trailingElement: _jsx(Icon, { src: Search }), placeholder: formatMessage(messages['authz.table.controlbar.search']), onChange: (e) => {
41
42
  setSearchValue(e.target.value);
42
43
  onSearchChange === null || onSearchChange === void 0 ? void 0 : onSearchChange(e.target.value);
43
- }, value: searchValue })), _jsxs(Form.CheckboxSet, { className: "pgn__dropdown-filter-checkbox-group", name: filterButtonText, "aria-label": filterButtonText, value: checkedBoxes, children: [_jsx("span", { className: "small text-info-700 mt-2", children: formatMessage(messages['authz.table.controlbar.filters.items.showing'], { current: filterChoices.length, total: filterChoices.length }) }), !isGrouped ? filterChoices.map(({ displayName, value, description, }) => (_jsx(Form.Checkbox, { className: "m-2 w-100", checked: checkedBoxes.includes(value), value: value, onChange: () => handleClickCheckbox(value, displayName), "aria-label": displayName, disabled: checkedBoxes.includes(value) ? false : disabled, children: _jsxs("div", { className: "d-flex flex-column", children: [_jsx("span", { className: "small", children: displayName }), description && _jsx("span", { className: "small text-muted d-block", children: description })] }) }, displayName)))
44
+ }, value: searchValue, size: validateSizeFormControl(size) })), _jsxs(Form.CheckboxSet, { className: "pgn__dropdown-filter-checkbox-group", name: filterButtonText, "aria-label": filterButtonText, value: checkedBoxes, children: [_jsx("span", { className: "small text-info-700 mt-2", children: formatMessage(messages['authz.table.controlbar.filters.items.showing'], { current: filterChoices.length, total: filterChoices.length }) }), !isGrouped ? filterChoices.map(({ displayName, value, description, }) => (_jsx(Form.Checkbox, { className: "m-2 w-100", checked: checkedBoxes.includes(value), value: value, onChange: () => handleClickCheckbox(value, displayName), "aria-label": displayName, disabled: checkedBoxes.includes(value) ? false : disabled, children: _jsxs("div", { className: "d-flex flex-column", children: [_jsx("span", { className: "small", children: displayName }), description && _jsx("span", { className: "small text-muted d-block", children: description })] }) }, displayName)))
44
45
  : getGroupedChoices().map(({ groupName, icon, options }) => (_jsxs("div", { children: [_jsxs("div", { className: "pgn__dropdown-filter-group-name text-info-700 d-flex align-items-center small m-2 ml-0", children: [icon && _jsx(Icon, { color: "primary", src: icon, className: "mr-2", size: "xs" }), _jsx("span", { children: groupName })] }), options.map(({ displayName, value, description }) => (_jsx(Form.Checkbox, { className: "m-2 w-100", value: value, onChange: () => handleClickCheckbox(value, displayName), disabled: checkedBoxes.includes(value) ? false : disabled, "aria-label": displayName, children: _jsxs("div", { className: "d-flex flex-column", children: [_jsx("span", { className: "small", children: displayName }), description && _jsx("span", { className: "small text-muted d-block", children: description })] }) }, displayName)))] }, groupName))), isSearchable && (_jsxs("div", { className: "d-flex align-items-center justify-content-between p-2", children: [_jsx("span", { className: "text-muted small", children: formatMessage(messages['authz.table.controlbar.filters.more.results']) }), _jsx(Icon, { className: "text-gray-300 ml-1", src: Info, size: "xs" })] }))] })] })] }));
45
46
  };
46
47
  export default MultipleChoiceFilter;
@@ -1 +1 @@
1
- {"version":3,"file":"MultipleChoiceFilter.js","sourceRoot":"","sources":["../../../../src/authz-module/components/TableControlBar/MultipleChoiceFilter.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Dropdown, Form, Icon, Stack,\n} from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport { FilterList, Info, Search } from '@openedx/paragon/icons';\nimport { useState } from 'react';\nimport messages from '@src/authz-module/components/messages';\nimport { FilterChoice, MultipleChoiceFilterProps } from './types';\n\nconst MultipleChoiceFilter = ({\n filterButtonText,\n filterChoices,\n filterValue,\n setFilter,\n isGrouped = false,\n isSearchable = false,\n onSearchChange,\n iconSrc,\n disabled = false,\n}: MultipleChoiceFilterProps) => {\n const [searchValue, setSearchValue] = useState<string | undefined>(undefined);\n const { formatMessage } = useIntl();\n\n const checkedBoxes = filterValue || [];\n const handleClickCheckbox = (value, displayName) => {\n const newValue = {\n groupName: filterButtonText?.toLocaleLowerCase() || '',\n value,\n displayName,\n };\n if (checkedBoxes.includes(value)) {\n const newCheckedBoxes = checkedBoxes.filter((val) => val !== value);\n return setFilter(newCheckedBoxes, newValue);\n }\n const newCheckedBoxes = [...checkedBoxes, value];\n return setFilter(newCheckedBoxes, newValue);\n };\n\n const getGroupedChoices = () => {\n const groupedFilterChoices = filterChoices.reduce((groups, choice) => {\n const groupName = choice.groupName || 'Ungrouped';\n const icon = choice.groupIcon || undefined;\n if (!groups.has(groupName)) {\n groups.set(groupName, { groupName, options: [], icon });\n }\n groups.get(groupName)!.options.push({\n displayName: choice.displayName,\n value: choice.value,\n description: choice.description,\n });\n return groups;\n }, new Map<string, { groupName: string; options: FilterChoice[]; icon?: any }>());\n return Array.from(groupedFilterChoices.values());\n };\n\n return (\n <Dropdown className=\"no-caret-dropdown filters\">\n <Dropdown.Toggle variant={checkedBoxes.length > 0 ? 'primary' : 'outline-primary'}>\n <Stack direction=\"horizontal\" gap={2}>\n {iconSrc && <Icon color=\"primary\" src={iconSrc} />}\n {filterButtonText}\n {checkedBoxes.length > 0 && ` (${checkedBoxes.length})`}\n <Icon color=\"primary\" src={FilterList} />\n </Stack>\n </Dropdown.Toggle>\n\n <Dropdown.Menu>\n {isSearchable && (\n <Form.Control\n className=\"m-1\"\n type=\"text\"\n trailingElement={<Icon src={Search} />}\n placeholder={formatMessage(messages['authz.table.controlbar.search'])}\n onChange={(e) => {\n setSearchValue(e.target.value);\n onSearchChange?.(e.target.value);\n }}\n value={searchValue}\n />\n )}\n <Form.CheckboxSet\n className=\"pgn__dropdown-filter-checkbox-group\"\n name={filterButtonText}\n aria-label={filterButtonText}\n value={checkedBoxes}\n >\n <span className=\"small text-info-700 mt-2\">\n {formatMessage(messages['authz.table.controlbar.filters.items.showing'], { current: filterChoices.length, total: filterChoices.length })}\n </span>\n {!isGrouped ? filterChoices.map(({\n displayName, value, description,\n }) => (\n <Form.Checkbox\n className=\"m-2 w-100\"\n key={displayName}\n checked={checkedBoxes.includes(value)}\n value={value}\n onChange={() => handleClickCheckbox(value, displayName)}\n aria-label={displayName}\n disabled={checkedBoxes.includes(value) ? false : disabled}\n >\n <div className=\"d-flex flex-column\">\n <span className=\"small\">{displayName}</span>\n { description && <span className=\"small text-muted d-block\">{description}</span> }\n </div>\n </Form.Checkbox>\n ))\n : getGroupedChoices().map(({ groupName, icon, options }) => (\n <div key={groupName}>\n <div className=\"pgn__dropdown-filter-group-name text-info-700 d-flex align-items-center small m-2 ml-0\">\n {icon && <Icon color=\"primary\" src={icon} className=\"mr-2\" size=\"xs\" />}\n <span>{groupName}</span>\n </div>\n {options.map(({ displayName, value, description }) => (\n <Form.Checkbox\n className=\"m-2 w-100\"\n key={displayName}\n value={value}\n onChange={() => handleClickCheckbox(value, displayName)}\n disabled={checkedBoxes.includes(value) ? false : disabled}\n aria-label={displayName}\n >\n <div className=\"d-flex flex-column\">\n <span className=\"small\">{displayName}</span>\n { description && <span className=\"small text-muted d-block\">{description}</span> }\n </div>\n </Form.Checkbox>\n ))}\n </div>\n ))}\n { isSearchable && (\n <div className=\"d-flex align-items-center justify-content-between p-2\">\n <span className=\"text-muted small\">{formatMessage(messages['authz.table.controlbar.filters.more.results'])}</span>\n <Icon className=\"text-gray-300 ml-1\" src={Info} size=\"xs\" />\n </div>\n )}\n </Form.CheckboxSet>\n </Dropdown.Menu>\n\n </Dropdown>\n );\n};\n\nexport default MultipleChoiceFilter;\n"]}
1
+ {"version":3,"file":"MultipleChoiceFilter.js","sourceRoot":"","sources":["../../../../src/authz-module/components/TableControlBar/MultipleChoiceFilter.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,QAAQ,MAAM,uCAAuC,CAAC;AAE7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAElE,MAAM,oBAAoB,GAAG,CAAC,EAC5B,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,SAAS,EACT,SAAS,GAAG,KAAK,EACjB,YAAY,GAAG,KAAK,EACpB,cAAc,EACd,OAAO,EACP,QAAQ,GAAG,KAAK,EAChB,IAAI,GAAG,IAAI,GACe,EAAE,EAAE;IAC9B,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAqB,SAAS,CAAC,CAAC;IAC9E,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IAEpC,MAAM,YAAY,GAAG,WAAW,IAAI,EAAE,CAAC;IACvC,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE;QACjD,MAAM,QAAQ,GAAG;YACf,SAAS,EAAE,CAAA,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,CAAE,iBAAiB,EAAE,KAAI,EAAE;YACtD,KAAK;YACL,WAAW;SACZ,CAAC;QACF,IAAI,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,MAAM,eAAe,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC;YACpE,OAAO,SAAS,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;QAC9C,CAAC;QACD,MAAM,eAAe,GAAG,CAAC,GAAG,YAAY,EAAE,KAAK,CAAC,CAAC;QACjD,OAAO,SAAS,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC,CAAC;IAEF,MAAM,iBAAiB,GAAG,GAAG,EAAE;QAC7B,MAAM,oBAAoB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;YACnE,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,WAAW,CAAC;YAClD,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,IAAI,SAAS,CAAC;YAC3C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC3B,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1D,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,SAAS,CAAE,CAAC,OAAO,CAAC,IAAI,CAAC;gBAClC,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,WAAW,EAAE,MAAM,CAAC,WAAW;aAChC,CAAC,CAAC;YACH,OAAO,MAAM,CAAC;QAChB,CAAC,EAAE,IAAI,GAAG,EAAsE,CAAC,CAAC;QAClF,OAAO,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC;IAEF,OAAO,CACL,MAAC,QAAQ,IAAC,SAAS,EAAC,2BAA2B,aAC7C,KAAC,QAAQ,CAAC,MAAM,IAAC,OAAO,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,EAAE,IAAI,EAAE,IAAI,YAC3F,MAAC,KAAK,IAAC,SAAS,EAAC,YAAY,EAAC,GAAG,EAAE,CAAC,aACjC,OAAO,IAAI,KAAC,IAAI,IAAC,KAAK,EAAC,SAAS,EAAC,GAAG,EAAE,OAAO,GAAI,EACjD,gBAAgB,EAChB,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC,MAAM,GAAG,EACvD,KAAC,IAAI,IAAC,KAAK,EAAC,SAAS,EAAC,GAAG,EAAE,UAAU,GAAI,IACnC,GACQ,EAElB,MAAC,QAAQ,CAAC,IAAI,eACX,YAAY,IAAI,CACf,KAAC,IAAI,CAAC,OAAO,IACX,SAAS,EAAC,KAAK,EACf,IAAI,EAAC,MAAM,EACX,eAAe,EAAE,KAAC,IAAI,IAAC,GAAG,EAAE,MAAM,GAAI,EACtC,WAAW,EAAE,aAAa,CAAC,QAAQ,CAAC,+BAA+B,CAAC,CAAC,EACrE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;4BACd,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;4BAC/B,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;wBACnC,CAAC,EACD,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,uBAAuB,CAAC,IAAI,CAAC,GACnC,CACH,EACD,MAAC,IAAI,CAAC,WAAW,IACf,SAAS,EAAC,qCAAqC,EAC/C,IAAI,EAAE,gBAAgB,gBACV,gBAAgB,EAC5B,KAAK,EAAE,YAAY,aAEnB,eAAM,SAAS,EAAC,0BAA0B,YACvC,aAAa,CAAC,QAAQ,CAAC,8CAA8C,CAAC,EAAE,EAAE,OAAO,EAAE,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC,GACnI,EACN,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EAC/B,WAAW,EAAE,KAAK,EAAE,WAAW,GAChC,EAAE,EAAE,CAAC,CACJ,KAAC,IAAI,CAAC,QAAQ,IACZ,SAAS,EAAC,WAAW,EAErB,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,EACrC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,KAAK,EAAE,WAAW,CAAC,gBAC3C,WAAW,EACvB,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,YAEzD,eAAK,SAAS,EAAC,oBAAoB,aACjC,eAAM,SAAS,EAAC,OAAO,YAAE,WAAW,GAAQ,EAC1C,WAAW,IAAI,eAAM,SAAS,EAAC,0BAA0B,YAAE,WAAW,GAAQ,IAC5E,IAVD,WAAW,CAWF,CACjB,CAAC;gCACA,CAAC,CAAC,iBAAiB,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CACxD,0BACE,eAAK,SAAS,EAAC,wFAAwF,aACpG,IAAI,IAAI,KAAC,IAAI,IAAC,KAAK,EAAC,SAAS,EAAC,GAAG,EAAE,IAAI,EAAE,SAAS,EAAC,MAAM,EAAC,IAAI,EAAC,IAAI,GAAG,EACvE,yBAAO,SAAS,GAAQ,IACpB,EACL,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CACpD,KAAC,IAAI,CAAC,QAAQ,IACZ,SAAS,EAAC,WAAW,EAErB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,KAAK,EAAE,WAAW,CAAC,EACvD,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,gBAC7C,WAAW,YAEvB,eAAK,SAAS,EAAC,oBAAoB,aACjC,eAAM,SAAS,EAAC,OAAO,YAAE,WAAW,GAAQ,EAC1C,WAAW,IAAI,eAAM,SAAS,EAAC,0BAA0B,YAAE,WAAW,GAAQ,IAC5E,IATD,WAAW,CAUF,CACjB,CAAC,KAnBM,SAAS,CAoBb,CACP,CAAC,EACJ,YAAY,IAAI,CAChB,eAAK,SAAS,EAAC,uDAAuD,aACpE,eAAM,SAAS,EAAC,kBAAkB,YAAE,aAAa,CAAC,QAAQ,CAAC,6CAA6C,CAAC,CAAC,GAAQ,EAClH,KAAC,IAAI,IAAC,SAAS,EAAC,oBAAoB,EAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAC,IAAI,GAAG,IACxD,CACP,IACgB,IACL,IAEP,CACZ,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,oBAAoB,CAAC","sourcesContent":["import {\n Dropdown, Form, Icon, Stack,\n} from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport { FilterList, Info, Search } from '@openedx/paragon/icons';\nimport { useState } from 'react';\nimport messages from '@src/authz-module/components/messages';\nimport { FilterChoice, MultipleChoiceFilterProps } from './types';\nimport { validateSizeFormControl } from '@src/authz-module/utils';\n\nconst MultipleChoiceFilter = ({\n filterButtonText,\n filterChoices,\n filterValue,\n setFilter,\n isGrouped = false,\n isSearchable = false,\n onSearchChange,\n iconSrc,\n disabled = false,\n size = 'sm',\n}: MultipleChoiceFilterProps) => {\n const [searchValue, setSearchValue] = useState<string | undefined>(undefined);\n const { formatMessage } = useIntl();\n\n const checkedBoxes = filterValue || [];\n const handleClickCheckbox = (value, displayName) => {\n const newValue = {\n groupName: filterButtonText?.toLocaleLowerCase() || '',\n value,\n displayName,\n };\n if (checkedBoxes.includes(value)) {\n const newCheckedBoxes = checkedBoxes.filter((val) => val !== value);\n return setFilter(newCheckedBoxes, newValue);\n }\n const newCheckedBoxes = [...checkedBoxes, value];\n return setFilter(newCheckedBoxes, newValue);\n };\n\n const getGroupedChoices = () => {\n const groupedFilterChoices = filterChoices.reduce((groups, choice) => {\n const groupName = choice.groupName || 'Ungrouped';\n const icon = choice.groupIcon || undefined;\n if (!groups.has(groupName)) {\n groups.set(groupName, { groupName, options: [], icon });\n }\n groups.get(groupName)!.options.push({\n displayName: choice.displayName,\n value: choice.value,\n description: choice.description,\n });\n return groups;\n }, new Map<string, { groupName: string; options: FilterChoice[]; icon?: any }>());\n return Array.from(groupedFilterChoices.values());\n };\n\n return (\n <Dropdown className=\"no-caret-dropdown filters\">\n <Dropdown.Toggle variant={checkedBoxes.length > 0 ? 'primary' : 'outline-primary'} size={size}>\n <Stack direction=\"horizontal\" gap={2}>\n {iconSrc && <Icon color=\"primary\" src={iconSrc} />}\n {filterButtonText}\n {checkedBoxes.length > 0 && ` (${checkedBoxes.length})`}\n <Icon color=\"primary\" src={FilterList} />\n </Stack>\n </Dropdown.Toggle>\n\n <Dropdown.Menu>\n {isSearchable && (\n <Form.Control\n className=\"m-1\"\n type=\"text\"\n trailingElement={<Icon src={Search} />}\n placeholder={formatMessage(messages['authz.table.controlbar.search'])}\n onChange={(e) => {\n setSearchValue(e.target.value);\n onSearchChange?.(e.target.value);\n }}\n value={searchValue}\n size={validateSizeFormControl(size)}\n />\n )}\n <Form.CheckboxSet\n className=\"pgn__dropdown-filter-checkbox-group\"\n name={filterButtonText}\n aria-label={filterButtonText}\n value={checkedBoxes}\n >\n <span className=\"small text-info-700 mt-2\">\n {formatMessage(messages['authz.table.controlbar.filters.items.showing'], { current: filterChoices.length, total: filterChoices.length })}\n </span>\n {!isGrouped ? filterChoices.map(({\n displayName, value, description,\n }) => (\n <Form.Checkbox\n className=\"m-2 w-100\"\n key={displayName}\n checked={checkedBoxes.includes(value)}\n value={value}\n onChange={() => handleClickCheckbox(value, displayName)}\n aria-label={displayName}\n disabled={checkedBoxes.includes(value) ? false : disabled}\n >\n <div className=\"d-flex flex-column\">\n <span className=\"small\">{displayName}</span>\n { description && <span className=\"small text-muted d-block\">{description}</span> }\n </div>\n </Form.Checkbox>\n ))\n : getGroupedChoices().map(({ groupName, icon, options }) => (\n <div key={groupName}>\n <div className=\"pgn__dropdown-filter-group-name text-info-700 d-flex align-items-center small m-2 ml-0\">\n {icon && <Icon color=\"primary\" src={icon} className=\"mr-2\" size=\"xs\" />}\n <span>{groupName}</span>\n </div>\n {options.map(({ displayName, value, description }) => (\n <Form.Checkbox\n className=\"m-2 w-100\"\n key={displayName}\n value={value}\n onChange={() => handleClickCheckbox(value, displayName)}\n disabled={checkedBoxes.includes(value) ? false : disabled}\n aria-label={displayName}\n >\n <div className=\"d-flex flex-column\">\n <span className=\"small\">{displayName}</span>\n { description && <span className=\"small text-muted d-block\">{description}</span> }\n </div>\n </Form.Checkbox>\n ))}\n </div>\n ))}\n { isSearchable && (\n <div className=\"d-flex align-items-center justify-content-between p-2\">\n <span className=\"text-muted small\">{formatMessage(messages['authz.table.controlbar.filters.more.results'])}</span>\n <Icon className=\"text-gray-300 ml-1\" src={Info} size=\"xs\" />\n </div>\n )}\n </Form.CheckboxSet>\n </Dropdown.Menu>\n\n </Dropdown>\n );\n};\n\nexport default MultipleChoiceFilter;\n"]}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import React, { useMemo } from 'react';
3
- import { Business } from '@openedx/paragon/icons';
3
+ import { AccountBalance } from '@openedx/paragon/icons';
4
4
  import { useOrgs } from '../../data/hooks';
5
5
  import { useViewTeamPermissions } from '../../hooks/useViewTeamPermissions';
6
6
  import { useCourseAuthoringFlag } from '../../hooks/useCourseAuthoringFlag';
@@ -30,7 +30,7 @@ const OrgFilter = ({ filterButtonText, filterValue, setFilter, disabled, }) => {
30
30
  const handleSearchChange = (value) => {
31
31
  setSearchValue(value);
32
32
  };
33
- return (_jsx(MultipleChoiceFilter, { filterButtonText: filterButtonText, filterChoices: filterChoices, filterValue: filterValue, setFilter: setFilter, isSearchable: true, onSearchChange: handleSearchChange, iconSrc: Business, disabled: disabled }));
33
+ return (_jsx(MultipleChoiceFilter, { filterButtonText: filterButtonText, filterChoices: filterChoices, filterValue: filterValue, setFilter: setFilter, isSearchable: true, onSearchChange: handleSearchChange, iconSrc: AccountBalance, disabled: disabled }));
34
34
  };
35
35
  export default OrgFilter;
36
36
  //# sourceMappingURL=OrgFilter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"OrgFilter.js","sourceRoot":"","sources":["../../../../src/authz-module/components/TableControlBar/OrgFilter.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AACxF,OAAO,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AACxF,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAEvE,OAAO,oBAAoB,MAAM,wBAAwB,CAAC;AAI1D,MAAM,SAAS,GAAG,CAAC,EACjB,gBAAgB,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,GACnC,EAAE,EAAE;IACnB,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAqB,SAAS,CAAC,CAAC;IACpF,MAAM,EAAE,oBAAoB,EAAE,SAAS,EAAE,GAAG,sBAAsB,EAAE,CAAC;IACrE,MAAM,EAAE,qBAAqB,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,sBAAsB,EAAE,CAAC;IACrF,MAAM,EACJ,IAAI,EAAE,QAAQ,GAAG;QACf,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;KAClD,GACF,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,wBAAwB,CAAC,CAAC;IAEtD,sFAAsF;IACtF,iFAAiF;IACjF,kFAAkF;IAClF,sFAAsF;IACtF,MAAM,qBAAqB,GAAG,CAAC,SAAS,IAAI,CAAC,aAAa,IAAI,CAAC,oBAAoB,CAAC;IAEpF,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE;;QAAC,OAAA,CAAC,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,OAAO,mCAAI,EAAE,CAAC;aAC1D,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,qBAAqB,IAAI,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;aAC/E,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACb,WAAW,EAAE,GAAG,CAAC,IAAI;YACrB,KAAK,EAAE,GAAG,CAAC,SAAS;SACrB,CAAC,CAAC,CAAA;KAAA,EAAE,CAAC,QAAQ,EAAE,qBAAqB,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAEjE,MAAM,kBAAkB,GAAG,CAAC,KAAa,EAAE,EAAE;QAC3C,cAAc,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC,CAAC;IAEF,OAAO,CACL,KAAC,oBAAoB,IACnB,gBAAgB,EAAE,gBAAgB,EAClC,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS,EACpB,YAAY,QACZ,cAAc,EAAE,kBAAkB,EAClC,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,QAAQ,GAClB,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,SAAS,CAAC","sourcesContent":["import React, { useMemo } from 'react';\nimport { Business } from '@openedx/paragon/icons';\nimport { useOrgs } from '@src/authz-module/data/hooks';\nimport { useViewTeamPermissions } from '@src/authz-module/hooks/useViewTeamPermissions';\nimport { useCourseAuthoringFlag } from '@src/authz-module/hooks/useCourseAuthoringFlag';\nimport { DEFAULT_FILTER_PAGE_SIZE } from '@src/authz-module/constants';\nimport { MultipleChoiceFilterProps } from './types';\nimport MultipleChoiceFilter from './MultipleChoiceFilter';\n\ntype OrgFilterProps = Omit<MultipleChoiceFilterProps, 'filterChoices' | 'isSearchable' | 'onSearchChange'>;\n\nconst OrgFilter = ({\n filterButtonText, filterValue, setFilter, disabled,\n}: OrgFilterProps) => {\n const [searchValue, setSearchValue] = React.useState<string | undefined>(undefined);\n const { isLibraryViewAllowed, isLoading } = useViewTeamPermissions();\n const { isOrgAuthoringEnabled, isLoading: isFlagLoading } = useCourseAuthoringFlag();\n const {\n data: orgsData = {\n count: 0, next: null, previous: null, results: [],\n },\n } = useOrgs(searchValue, 1, DEFAULT_FILTER_PAGE_SIZE);\n\n // Users with library access (including those with both library and course roles) must\n // always see all orgs: library access is not gated by the course-authoring flag,\n // so the flag must never be used to filter orgs for them. Only filter orgs by the\n // flag for course-only users, and never while permissions or flag states are loading.\n const filterByAuthoringFlag = !isLoading && !isFlagLoading && !isLibraryViewAllowed;\n\n const filterChoices = useMemo(() => (orgsData?.results ?? [])\n .filter((org) => !filterByAuthoringFlag || isOrgAuthoringEnabled(org.shortName))\n .map((org) => ({\n displayName: org.name,\n value: org.shortName,\n })), [orgsData, filterByAuthoringFlag, isOrgAuthoringEnabled]);\n\n const handleSearchChange = (value: string) => {\n setSearchValue(value);\n };\n\n return (\n <MultipleChoiceFilter\n filterButtonText={filterButtonText}\n filterChoices={filterChoices}\n filterValue={filterValue}\n setFilter={setFilter}\n isSearchable\n onSearchChange={handleSearchChange}\n iconSrc={Business}\n disabled={disabled}\n />\n );\n};\n\nexport default OrgFilter;\n"]}
1
+ {"version":3,"file":"OrgFilter.js","sourceRoot":"","sources":["../../../../src/authz-module/components/TableControlBar/OrgFilter.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AACxF,OAAO,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AACxF,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAEvE,OAAO,oBAAoB,MAAM,wBAAwB,CAAC;AAI1D,MAAM,SAAS,GAAG,CAAC,EACjB,gBAAgB,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,GACnC,EAAE,EAAE;IACnB,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAqB,SAAS,CAAC,CAAC;IACpF,MAAM,EAAE,oBAAoB,EAAE,SAAS,EAAE,GAAG,sBAAsB,EAAE,CAAC;IACrE,MAAM,EAAE,qBAAqB,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,sBAAsB,EAAE,CAAC;IACrF,MAAM,EACJ,IAAI,EAAE,QAAQ,GAAG;QACf,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;KAClD,GACF,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,wBAAwB,CAAC,CAAC;IAEtD,sFAAsF;IACtF,iFAAiF;IACjF,kFAAkF;IAClF,sFAAsF;IACtF,MAAM,qBAAqB,GAAG,CAAC,SAAS,IAAI,CAAC,aAAa,IAAI,CAAC,oBAAoB,CAAC;IAEpF,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE;;QAAC,OAAA,CAAC,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,OAAO,mCAAI,EAAE,CAAC;aAC1D,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,qBAAqB,IAAI,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;aAC/E,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACb,WAAW,EAAE,GAAG,CAAC,IAAI;YACrB,KAAK,EAAE,GAAG,CAAC,SAAS;SACrB,CAAC,CAAC,CAAA;KAAA,EAAE,CAAC,QAAQ,EAAE,qBAAqB,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAEjE,MAAM,kBAAkB,GAAG,CAAC,KAAa,EAAE,EAAE;QAC3C,cAAc,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC,CAAC;IAEF,OAAO,CACL,KAAC,oBAAoB,IACnB,gBAAgB,EAAE,gBAAgB,EAClC,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS,EACpB,YAAY,QACZ,cAAc,EAAE,kBAAkB,EAClC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,QAAQ,GAClB,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,SAAS,CAAC","sourcesContent":["import React, { useMemo } from 'react';\nimport { AccountBalance } from '@openedx/paragon/icons';\nimport { useOrgs } from '@src/authz-module/data/hooks';\nimport { useViewTeamPermissions } from '@src/authz-module/hooks/useViewTeamPermissions';\nimport { useCourseAuthoringFlag } from '@src/authz-module/hooks/useCourseAuthoringFlag';\nimport { DEFAULT_FILTER_PAGE_SIZE } from '@src/authz-module/constants';\nimport { MultipleChoiceFilterProps } from './types';\nimport MultipleChoiceFilter from './MultipleChoiceFilter';\n\ntype OrgFilterProps = Omit<MultipleChoiceFilterProps, 'filterChoices' | 'isSearchable' | 'onSearchChange'>;\n\nconst OrgFilter = ({\n filterButtonText, filterValue, setFilter, disabled,\n}: OrgFilterProps) => {\n const [searchValue, setSearchValue] = React.useState<string | undefined>(undefined);\n const { isLibraryViewAllowed, isLoading } = useViewTeamPermissions();\n const { isOrgAuthoringEnabled, isLoading: isFlagLoading } = useCourseAuthoringFlag();\n const {\n data: orgsData = {\n count: 0, next: null, previous: null, results: [],\n },\n } = useOrgs(searchValue, 1, DEFAULT_FILTER_PAGE_SIZE);\n\n // Users with library access (including those with both library and course roles) must\n // always see all orgs: library access is not gated by the course-authoring flag,\n // so the flag must never be used to filter orgs for them. Only filter orgs by the\n // flag for course-only users, and never while permissions or flag states are loading.\n const filterByAuthoringFlag = !isLoading && !isFlagLoading && !isLibraryViewAllowed;\n\n const filterChoices = useMemo(() => (orgsData?.results ?? [])\n .filter((org) => !filterByAuthoringFlag || isOrgAuthoringEnabled(org.shortName))\n .map((org) => ({\n displayName: org.name,\n value: org.shortName,\n })), [orgsData, filterByAuthoringFlag, isOrgAuthoringEnabled]);\n\n const handleSearchChange = (value: string) => {\n setSearchValue(value);\n };\n\n return (\n <MultipleChoiceFilter\n filterButtonText={filterButtonText}\n filterChoices={filterChoices}\n filterValue={filterValue}\n setFilter={setFilter}\n isSearchable\n onSearchChange={handleSearchChange}\n iconSrc={AccountBalance}\n disabled={disabled}\n />\n );\n};\n\nexport default OrgFilter;\n"]}
@@ -2,6 +2,7 @@ interface SearchFilterProps {
2
2
  filterValue: string;
3
3
  setFilter: (value: string) => void;
4
4
  placeholder: string;
5
+ size?: 'sm' | 'md' | 'lg';
5
6
  }
6
- declare const SearchFilter: ({ filterValue, setFilter, placeholder, }: SearchFilterProps) => import("react").JSX.Element;
7
+ declare const SearchFilter: ({ filterValue, setFilter, placeholder, size }: SearchFilterProps) => import("react").JSX.Element;
7
8
  export default SearchFilter;
@@ -1,7 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Form, Icon, } from '@openedx/paragon';
3
3
  import { Search } from '@openedx/paragon/icons';
4
- const SearchFilter = ({ filterValue, setFilter, placeholder, }) => (_jsx(Form.Group, { className: "m-0", children: _jsx(Form.Control, { className: "mw-xs mr-0", trailingElement: _jsx(Icon, { src: Search }), value: filterValue || '', type: "text", onChange: e => {
4
+ import { validateSizeFormControl } from '../../utils';
5
+ const SearchFilter = ({ filterValue, setFilter, placeholder, size = 'sm' }) => (_jsx(Form.Group, { className: "m-0", size: validateSizeFormControl(size), children: _jsx(Form.Control, { className: "mw-xs mr-0", trailingElement: _jsx(Icon, { src: Search }), value: filterValue || '', type: "text", onChange: e => {
5
6
  setFilter(e.target.value || undefined); // Set undefined to remove the filter entirely
6
7
  }, placeholder: placeholder }) }));
7
8
  export default SearchFilter;
@@ -1 +1 @@
1
- {"version":3,"file":"SearchFilter.js","sourceRoot":"","sources":["../../../../src/authz-module/components/TableControlBar/SearchFilter.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,IAAI,EACJ,IAAI,GACL,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAQhD,MAAM,YAAY,GAAG,CAAC,EACpB,WAAW,EAAE,SAAS,EAAE,WAAW,GACjB,EAAE,EAAE,CAAC,CACvB,KAAC,IAAI,CAAC,KAAK,IAAC,SAAS,EAAC,KAAK,YACzB,KAAC,IAAI,CAAC,OAAO,IACX,SAAS,EAAC,YAAY,EACtB,eAAe,EAAE,KAAC,IAAI,IAAC,GAAG,EAAE,MAAM,GAAI,EACtC,KAAK,EAAE,WAAW,IAAI,EAAE,EACxB,IAAI,EAAC,MAAM,EACX,QAAQ,EAAE,CAAC,CAAC,EAAE;YACZ,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC,CAAC,8CAA8C;QACxF,CAAC,EACD,WAAW,EAAE,WAAW,GACxB,GACS,CACd,CAAC;AAEF,eAAe,YAAY,CAAC","sourcesContent":["import {\n Form,\n Icon,\n} from '@openedx/paragon';\nimport { Search } from '@openedx/paragon/icons';\n\ninterface SearchFilterProps {\n filterValue: string;\n setFilter: (value: string) => void;\n placeholder: string;\n}\n\nconst SearchFilter = ({\n filterValue, setFilter, placeholder,\n}: SearchFilterProps) => (\n <Form.Group className=\"m-0\">\n <Form.Control\n className=\"mw-xs mr-0\"\n trailingElement={<Icon src={Search} />}\n value={filterValue || ''}\n type=\"text\"\n onChange={e => {\n setFilter(e.target.value || undefined); // Set undefined to remove the filter entirely\n }}\n placeholder={placeholder}\n />\n </Form.Group>\n);\n\nexport default SearchFilter;\n"]}
1
+ {"version":3,"file":"SearchFilter.js","sourceRoot":"","sources":["../../../../src/authz-module/components/TableControlBar/SearchFilter.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,IAAI,EACJ,IAAI,GACL,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AASlE,MAAM,YAAY,GAAG,CAAC,EACpB,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,GAAG,IAAI,EAC9B,EAAE,EAAE,CAAC,CACvB,KAAC,IAAI,CAAC,KAAK,IAAC,SAAS,EAAC,KAAK,EAAC,IAAI,EAAE,uBAAuB,CAAC,IAAI,CAAC,YAC7D,KAAC,IAAI,CAAC,OAAO,IACX,SAAS,EAAC,YAAY,EACtB,eAAe,EAAE,KAAC,IAAI,IAAC,GAAG,EAAE,MAAM,GAAI,EACtC,KAAK,EAAE,WAAW,IAAI,EAAE,EACxB,IAAI,EAAC,MAAM,EACX,QAAQ,EAAE,CAAC,CAAC,EAAE;YACZ,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC,CAAC,8CAA8C;QACxF,CAAC,EACD,WAAW,EAAE,WAAW,GACxB,GACS,CACd,CAAC;AAEF,eAAe,YAAY,CAAC","sourcesContent":["import {\n Form,\n Icon,\n} from '@openedx/paragon';\nimport { Search } from '@openedx/paragon/icons';\nimport { validateSizeFormControl } from '@src/authz-module/utils';\n\ninterface SearchFilterProps {\n filterValue: string;\n setFilter: (value: string) => void;\n placeholder: string;\n size?: 'sm' | 'md' | 'lg';\n}\n\nconst SearchFilter = ({\n filterValue, setFilter, placeholder, size = 'sm'\n}: SearchFilterProps) => (\n <Form.Group className=\"m-0\" size={validateSizeFormControl(size)}>\n <Form.Control\n className=\"mw-xs mr-0\"\n trailingElement={<Icon src={Search} />}\n value={filterValue || ''}\n type=\"text\"\n onChange={e => {\n setFilter(e.target.value || undefined); // Set undefined to remove the filter entirely\n }}\n placeholder={placeholder}\n />\n </Form.Group>\n);\n\nexport default SearchFilter;\n"]}
@@ -1,5 +1,8 @@
1
+ import { type ReactNode } from 'react';
1
2
  interface TableControlBarProps {
2
3
  onFilterChange?: (filters: string[]) => void;
4
+ /** Optional count rendered right-aligned on the filter row, e.g. "Showing 10 users of 100." */
5
+ countLabel?: ReactNode;
3
6
  }
4
- declare const TableControlBar: ({ onFilterChange }: TableControlBarProps) => import("react").JSX.Element;
7
+ declare const TableControlBar: ({ onFilterChange, countLabel }: TableControlBarProps) => import("react").JSX.Element;
5
8
  export default TableControlBar;
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useContext, useEffect, useState } from 'react';
2
+ import { useContext, useEffect, useState, } from 'react';
3
3
  import { useIntl } from '@openedx/frontend-base';
4
4
  import { DataTableContext, Stack, TextFilter, Button, Chip, Alert, Icon, } from '@openedx/paragon';
5
- import { Business, Close, LocationOn, Person, Warning, } from '@openedx/paragon/icons';
5
+ import { AccountBalance, Close, LocationOn, Person, Warning, } from '@openedx/paragon/icons';
6
6
  import { MAX_TABLE_FILTERS_APPLIED } from '../../constants';
7
7
  import MultipleChoiceFilter from './MultipleChoiceFilter';
8
8
  import SearchFilter from './SearchFilter';
@@ -12,7 +12,7 @@ import OrgFilter from './OrgFilter';
12
12
  import ScopesFilter from './ScopesFilter';
13
13
  const FILTER_CHIPS_ICONS = {
14
14
  role: Person,
15
- organization: Business,
15
+ organization: AccountBalance,
16
16
  scope: LocationOn,
17
17
  };
18
18
  const FILTER_GROUP_TO_ID = {
@@ -20,7 +20,7 @@ const FILTER_GROUP_TO_ID = {
20
20
  organization: 'org',
21
21
  scope: 'scope',
22
22
  };
23
- const TableControlBar = ({ onFilterChange }) => {
23
+ const TableControlBar = ({ onFilterChange, countLabel }) => {
24
24
  const intl = useIntl();
25
25
  // applied filters in the order they were selected by the user, to display on the control bar as chips
26
26
  const [chronologicalFilters, setChronologicalFilters] = useState([]);
@@ -74,26 +74,26 @@ const TableControlBar = ({ onFilterChange }) => {
74
74
  setAllFilters([]);
75
75
  setChronologicalFilters([]);
76
76
  };
77
- return (_jsxs("div", { className: "authz-table-control-bar pgn__data-table-status-bar", children: [_jsx(Stack, { className: "mb-2 flex-wrap", gap: 2, direction: "horizontal", children: availableFilters.map((column) => {
78
- var _a;
79
- const { Filter } = column;
80
- if (Filter === RolesFilter) {
81
- return (_jsx(RolesFilter, Object.assign({}, column, { setFilter: handleSetFilters(column.setFilter), disabled: filtersLimitReached }), column.id || column.accessor));
82
- }
83
- if (Filter === OrgFilter) {
84
- return (_jsx(OrgFilter, Object.assign({}, column, { setFilter: handleSetFilters(column.setFilter), disabled: filtersLimitReached }), column.id || column.accessor));
85
- }
86
- if (Filter === MultipleChoiceFilter) {
87
- return (_jsx(MultipleChoiceFilter, Object.assign({}, column, { setFilter: handleSetFilters(column.setFilter), disabled: filtersLimitReached }), column.id || column.accessor));
88
- }
89
- if (Filter === ScopesFilter) {
90
- return (_jsx(ScopesFilter, Object.assign({}, column, { setFilter: handleSetFilters(column.setFilter), disabled: filtersLimitReached, filterValue: ((_a = state.filters.find(filter => filter.id === 'scope')) === null || _a === void 0 ? void 0 : _a.value) || null }), column.id || column.accessor));
91
- }
92
- if (Filter === TextFilter) {
93
- return (_jsx(SearchFilter, { filterValue: column.filterValue, setFilter: column.setFilter, placeholder: getSearchPlaceholder() }, column.id || column.accessor));
94
- }
95
- return null;
96
- }) }), chronologicalFilters.length > 0 && (_jsxs(Stack, { gap: 1, direction: "horizontal", className: "flex-wrap mb-2", children: [_jsx("span", { children: intl.formatMessage(messages['authz.table.controlbar.filterby.label']) }), chronologicalFilters.map((filter) => (_jsx(Chip, { iconBefore: FILTER_CHIPS_ICONS[filter.groupName || ''], iconAfter: Close, onIconAfterClick: () => handleCloseFilter(filter.groupName, filter.value), children: filter.displayName }, filter.value))), chronologicalFilters.length > 1 && (_jsx(Button, { className: "py-0", variant: "link", onClick: clearAllFilters, children: intl.formatMessage(messages['authz.table.controlbar.clearFilters']) }))] })), filtersLimitReached && (_jsx(Alert, { variant: "warning", className: "mb-2", children: _jsxs("span", { className: "d-flex flex-row", children: [_jsx(Icon, { src: Warning, className: "text-warning-400 mr-2" }), intl.formatMessage(messages['authz.table.controlbar.filters.limit.reached'])] }) }))] }));
77
+ return (_jsxs("div", { className: "authz-table-control-bar pgn__data-table-status-bar", children: [_jsxs(Stack, { className: "mb-2 flex-wrap", gap: 2, direction: "horizontal", children: [availableFilters.map((column) => {
78
+ var _a;
79
+ const { Filter } = column;
80
+ if (Filter === RolesFilter) {
81
+ return (_jsx(RolesFilter, Object.assign({}, column, { setFilter: handleSetFilters(column.setFilter), disabled: filtersLimitReached }), column.id || column.accessor));
82
+ }
83
+ if (Filter === OrgFilter) {
84
+ return (_jsx(OrgFilter, Object.assign({}, column, { setFilter: handleSetFilters(column.setFilter), disabled: filtersLimitReached }), column.id || column.accessor));
85
+ }
86
+ if (Filter === MultipleChoiceFilter) {
87
+ return (_jsx(MultipleChoiceFilter, Object.assign({}, column, { setFilter: handleSetFilters(column.setFilter), disabled: filtersLimitReached }), column.id || column.accessor));
88
+ }
89
+ if (Filter === ScopesFilter) {
90
+ return (_jsx(ScopesFilter, Object.assign({}, column, { setFilter: handleSetFilters(column.setFilter), disabled: filtersLimitReached, filterValue: ((_a = state.filters.find(filter => filter.id === 'scope')) === null || _a === void 0 ? void 0 : _a.value) || null }), column.id || column.accessor));
91
+ }
92
+ if (Filter === TextFilter) {
93
+ return (_jsx(SearchFilter, { filterValue: column.filterValue, setFilter: column.setFilter, placeholder: getSearchPlaceholder() }, column.id || column.accessor));
94
+ }
95
+ return null;
96
+ }), countLabel && _jsx("span", { className: "ml-auto small", children: countLabel })] }), chronologicalFilters.length > 0 && (_jsxs(Stack, { gap: 1, direction: "horizontal", className: "flex-wrap mb-2", children: [_jsx("span", { children: intl.formatMessage(messages['authz.table.controlbar.filterby.label']) }), chronologicalFilters.map((filter) => (_jsx(Chip, { iconBefore: FILTER_CHIPS_ICONS[filter.groupName || ''], iconAfter: Close, onIconAfterClick: () => handleCloseFilter(filter.groupName, filter.value), children: filter.displayName }, filter.value))), chronologicalFilters.length > 1 && (_jsx(Button, { className: "py-0", variant: "link", onClick: clearAllFilters, children: intl.formatMessage(messages['authz.table.controlbar.clearFilters']) }))] })), filtersLimitReached && (_jsx(Alert, { variant: "warning", className: "mb-2", children: _jsxs("span", { className: "d-flex flex-row", children: [_jsx(Icon, { src: Warning, className: "text-warning-400 mr-2" }), intl.formatMessage(messages['authz.table.controlbar.filters.limit.reached'])] }) }))] }));
97
97
  };
98
98
  export default TableControlBar;
99
99
  //# sourceMappingURL=TableControlBar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TableControlBar.js","sourceRoot":"","sources":["../../../../src/authz-module/components/TableControlBar/TableControlBar.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useContext, useEffect, useState } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport {\n DataTableContext,\n Stack,\n TextFilter,\n Button,\n Chip,\n Alert,\n Icon,\n} from '@openedx/paragon';\nimport {\n Business, Close, LocationOn, Person,\n Warning,\n} from '@openedx/paragon/icons';\n\nimport { MAX_TABLE_FILTERS_APPLIED } from '@src/authz-module/constants';\nimport MultipleChoiceFilter from './MultipleChoiceFilter';\nimport SearchFilter from './SearchFilter';\nimport messages from '@src/authz-module/components/messages';\nimport RolesFilter from './RolesFilter';\nimport OrgFilter from './OrgFilter';\nimport ScopesFilter from './ScopesFilter';\nimport { FilterChoice } from './types';\n\nconst FILTER_CHIPS_ICONS = {\n role: Person,\n organization: Business,\n scope: LocationOn,\n};\n\nconst FILTER_GROUP_TO_ID = {\n role: 'role',\n organization: 'org',\n scope: 'scope',\n};\n\ninterface TableControlBarProps {\n onFilterChange?: (filters: string[]) => void;\n}\n\nconst TableControlBar = ({ onFilterChange }: TableControlBarProps) => {\n const intl = useIntl();\n // applied filters in the order they were selected by the user, to display on the control bar as chips\n const [chronologicalFilters, setChronologicalFilters] = useState<FilterChoice[]>([]);\n const [filtersLimitReached, setFiltersLimitReached] = useState(false);\n const {\n columns,\n setAllFilters,\n state,\n // @ts-expect-error - Paragon's DataTableContext is not typed\n } = useContext<DataTableContext>(DataTableContext);\n\n useEffect(() => {\n if (state.filters.length > 0) {\n const formattedInitialFilters = state.filters.map((filter) => ({\n groupName: filter.id,\n value: filter.value[0] || '',\n displayName: filter.value[0] || '',\n }));\n setChronologicalFilters(formattedInitialFilters);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n setFiltersLimitReached(chronologicalFilters.length >= MAX_TABLE_FILTERS_APPLIED);\n if (onFilterChange) {\n onFilterChange(state.filters.map((filter) => filter.id) || []);\n }\n }, [chronologicalFilters, onFilterChange, state.filters]);\n\n const availableFilters = columns.filter((column) => column.canFilter)\n .sort((a, b) => (a.filterOrder || 0) - (b.filterOrder || 0));\n\n const columnTextFilterHeaders = columns\n .filter((column) => column.Filter === TextFilter)\n .map((column) => column.Header);\n\n const getSearchPlaceholder = () => intl.formatMessage(messages['authz.table.controlbar.search.by.fields'], {\n firstField: columnTextFilterHeaders[0] || '',\n secondField: columnTextFilterHeaders[1] || '',\n });\n\n const handleCloseFilter = (filterName, filterValue) => {\n const actualFilterId = FILTER_GROUP_TO_ID[filterName] || filterName;\n const filterGroup = state.filters.find((filter) => filter.id === actualFilterId);\n const newFilterValue = filterGroup?.value.filter(item => item !== filterValue) || [];\n setAllFilters(state.filters.map(item => (\n item.id !== actualFilterId ? item : { id: item.id, value: newFilterValue })));\n setChronologicalFilters((prevFilters) => prevFilters.filter((filter) => filter.value !== filterValue));\n };\n\n const handleSetFilters = (setFilter) => (allFilters: string[], newFilter: FilterChoice) => {\n setFilter(allFilters);\n setChronologicalFilters((prevFilters) => {\n if (!prevFilters.find((filter) => filter.value === newFilter.value)) {\n return [...prevFilters, newFilter];\n }\n return prevFilters.filter((filter) => filter.value !== newFilter.value);\n });\n };\n\n const clearAllFilters = () => {\n setAllFilters([]);\n setChronologicalFilters([]);\n };\n return (\n <div className=\"authz-table-control-bar pgn__data-table-status-bar\">\n <Stack className=\"mb-2 flex-wrap\" gap={2} direction=\"horizontal\">\n {availableFilters.map((column) => {\n const { Filter } = column;\n if (Filter === RolesFilter) {\n return (\n <RolesFilter\n key={column.id || column.accessor}\n {...column}\n setFilter={handleSetFilters(column.setFilter)}\n disabled={filtersLimitReached}\n />\n );\n }\n if (Filter === OrgFilter) {\n return (\n <OrgFilter\n key={column.id || column.accessor}\n {...column}\n setFilter={handleSetFilters(column.setFilter)}\n disabled={filtersLimitReached}\n />\n );\n }\n if (Filter === MultipleChoiceFilter) {\n return (\n <MultipleChoiceFilter\n key={column.id || column.accessor}\n {...column}\n setFilter={handleSetFilters(column.setFilter)}\n disabled={filtersLimitReached}\n />\n );\n }\n if (Filter === ScopesFilter) {\n return (\n <ScopesFilter\n key={column.id || column.accessor}\n {...column}\n setFilter={handleSetFilters(column.setFilter)}\n disabled={filtersLimitReached}\n filterValue={state.filters.find(filter => filter.id === 'scope')?.value || null}\n />\n );\n }\n\n if (Filter === TextFilter) {\n return (\n <SearchFilter\n key={column.id || column.accessor}\n filterValue={column.filterValue}\n setFilter={column.setFilter}\n placeholder={getSearchPlaceholder()}\n />\n );\n }\n return null;\n })}\n </Stack>\n\n {chronologicalFilters.length > 0 && (\n <Stack gap={1} direction=\"horizontal\" className=\"flex-wrap mb-2\">\n <span>{intl.formatMessage(messages['authz.table.controlbar.filterby.label'])}</span>\n {chronologicalFilters.map((filter) => (\n <Chip\n key={filter.value}\n iconBefore={FILTER_CHIPS_ICONS[filter.groupName || '']}\n iconAfter={Close}\n onIconAfterClick={() => handleCloseFilter(filter.groupName, filter.value)}\n >\n {filter.displayName}\n </Chip>\n ))}\n {chronologicalFilters.length > 1 && (\n <Button className=\"py-0\" variant=\"link\" onClick={clearAllFilters}>\n {intl.formatMessage(messages['authz.table.controlbar.clearFilters'])}\n </Button>\n )}\n </Stack>\n )}\n { filtersLimitReached && (\n <Alert variant=\"warning\" className=\"mb-2\">\n <span className=\"d-flex flex-row\">\n <Icon src={Warning} className=\"text-warning-400 mr-2\" />\n {intl.formatMessage(messages['authz.table.controlbar.filters.limit.reached'])}\n </span>\n </Alert>\n )}\n\n </div>\n );\n};\n\nexport default TableControlBar;\n"]}
1
+ {"version":3,"file":"TableControlBar.js","sourceRoot":"","sources":["../../../../src/authz-module/components/TableControlBar/TableControlBar.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useContext, useEffect, useState, type ReactNode,\n} from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport {\n DataTableContext,\n Stack,\n TextFilter,\n Button,\n Chip,\n Alert,\n Icon,\n} from '@openedx/paragon';\nimport {\n AccountBalance, Close, LocationOn, Person,\n Warning,\n} from '@openedx/paragon/icons';\n\nimport { MAX_TABLE_FILTERS_APPLIED } from '@src/authz-module/constants';\nimport MultipleChoiceFilter from './MultipleChoiceFilter';\nimport SearchFilter from './SearchFilter';\nimport messages from '@src/authz-module/components/messages';\nimport RolesFilter from './RolesFilter';\nimport OrgFilter from './OrgFilter';\nimport ScopesFilter from './ScopesFilter';\nimport { FilterChoice } from './types';\n\nconst FILTER_CHIPS_ICONS = {\n role: Person,\n organization: AccountBalance,\n scope: LocationOn,\n};\n\nconst FILTER_GROUP_TO_ID = {\n role: 'role',\n organization: 'org',\n scope: 'scope',\n};\n\ninterface TableControlBarProps {\n onFilterChange?: (filters: string[]) => void;\n /** Optional count rendered right-aligned on the filter row, e.g. \"Showing 10 users of 100.\" */\n countLabel?: ReactNode;\n}\n\nconst TableControlBar = ({ onFilterChange, countLabel }: TableControlBarProps) => {\n const intl = useIntl();\n // applied filters in the order they were selected by the user, to display on the control bar as chips\n const [chronologicalFilters, setChronologicalFilters] = useState<FilterChoice[]>([]);\n const [filtersLimitReached, setFiltersLimitReached] = useState(false);\n const {\n columns,\n setAllFilters,\n state,\n // @ts-expect-error - Paragon's DataTableContext is not typed\n } = useContext<DataTableContext>(DataTableContext);\n\n useEffect(() => {\n if (state.filters.length > 0) {\n const formattedInitialFilters = state.filters.map((filter) => ({\n groupName: filter.id,\n value: filter.value[0] || '',\n displayName: filter.value[0] || '',\n }));\n setChronologicalFilters(formattedInitialFilters);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n setFiltersLimitReached(chronologicalFilters.length >= MAX_TABLE_FILTERS_APPLIED);\n if (onFilterChange) {\n onFilterChange(state.filters.map((filter) => filter.id) || []);\n }\n }, [chronologicalFilters, onFilterChange, state.filters]);\n\n const availableFilters = columns.filter((column) => column.canFilter)\n .sort((a, b) => (a.filterOrder || 0) - (b.filterOrder || 0));\n\n const columnTextFilterHeaders = columns\n .filter((column) => column.Filter === TextFilter)\n .map((column) => column.Header);\n\n const getSearchPlaceholder = () => intl.formatMessage(messages['authz.table.controlbar.search.by.fields'], {\n firstField: columnTextFilterHeaders[0] || '',\n secondField: columnTextFilterHeaders[1] || '',\n });\n\n const handleCloseFilter = (filterName, filterValue) => {\n const actualFilterId = FILTER_GROUP_TO_ID[filterName] || filterName;\n const filterGroup = state.filters.find((filter) => filter.id === actualFilterId);\n const newFilterValue = filterGroup?.value.filter(item => item !== filterValue) || [];\n setAllFilters(state.filters.map(item => (\n item.id !== actualFilterId ? item : { id: item.id, value: newFilterValue })));\n setChronologicalFilters((prevFilters) => prevFilters.filter((filter) => filter.value !== filterValue));\n };\n\n const handleSetFilters = (setFilter) => (allFilters: string[], newFilter: FilterChoice) => {\n setFilter(allFilters);\n setChronologicalFilters((prevFilters) => {\n if (!prevFilters.find((filter) => filter.value === newFilter.value)) {\n return [...prevFilters, newFilter];\n }\n return prevFilters.filter((filter) => filter.value !== newFilter.value);\n });\n };\n\n const clearAllFilters = () => {\n setAllFilters([]);\n setChronologicalFilters([]);\n };\n return (\n <div className=\"authz-table-control-bar pgn__data-table-status-bar\">\n <Stack className=\"mb-2 flex-wrap\" gap={2} direction=\"horizontal\">\n {availableFilters.map((column) => {\n const { Filter } = column;\n if (Filter === RolesFilter) {\n return (\n <RolesFilter\n key={column.id || column.accessor}\n {...column}\n setFilter={handleSetFilters(column.setFilter)}\n disabled={filtersLimitReached}\n />\n );\n }\n if (Filter === OrgFilter) {\n return (\n <OrgFilter\n key={column.id || column.accessor}\n {...column}\n setFilter={handleSetFilters(column.setFilter)}\n disabled={filtersLimitReached}\n />\n );\n }\n if (Filter === MultipleChoiceFilter) {\n return (\n <MultipleChoiceFilter\n key={column.id || column.accessor}\n {...column}\n setFilter={handleSetFilters(column.setFilter)}\n disabled={filtersLimitReached}\n />\n );\n }\n if (Filter === ScopesFilter) {\n return (\n <ScopesFilter\n key={column.id || column.accessor}\n {...column}\n setFilter={handleSetFilters(column.setFilter)}\n disabled={filtersLimitReached}\n filterValue={state.filters.find(filter => filter.id === 'scope')?.value || null}\n />\n );\n }\n\n if (Filter === TextFilter) {\n return (\n <SearchFilter\n key={column.id || column.accessor}\n filterValue={column.filterValue}\n setFilter={column.setFilter}\n placeholder={getSearchPlaceholder()}\n />\n );\n }\n return null;\n })}\n {countLabel && <span className=\"ml-auto small\">{countLabel}</span>}\n </Stack>\n\n {chronologicalFilters.length > 0 && (\n <Stack gap={1} direction=\"horizontal\" className=\"flex-wrap mb-2\">\n <span>{intl.formatMessage(messages['authz.table.controlbar.filterby.label'])}</span>\n {chronologicalFilters.map((filter) => (\n <Chip\n key={filter.value}\n iconBefore={FILTER_CHIPS_ICONS[filter.groupName || '']}\n iconAfter={Close}\n onIconAfterClick={() => handleCloseFilter(filter.groupName, filter.value)}\n >\n {filter.displayName}\n </Chip>\n ))}\n {chronologicalFilters.length > 1 && (\n <Button className=\"py-0\" variant=\"link\" onClick={clearAllFilters}>\n {intl.formatMessage(messages['authz.table.controlbar.clearFilters'])}\n </Button>\n )}\n </Stack>\n )}\n { filtersLimitReached && (\n <Alert variant=\"warning\" className=\"mb-2\">\n <span className=\"d-flex flex-row\">\n <Icon src={Warning} className=\"text-warning-400 mr-2\" />\n {intl.formatMessage(messages['authz.table.controlbar.filters.limit.reached'])}\n </span>\n </Alert>\n )}\n\n </div>\n );\n};\n\nexport default TableControlBar;\n"]}
@@ -15,4 +15,5 @@ export interface MultipleChoiceFilterProps {
15
15
  onSearchChange?: (value: string) => void;
16
16
  iconSrc?: React.ComponentType | undefined;
17
17
  disabled?: boolean;
18
+ size?: 'sm' | 'md' | 'lg' | 'inline';
18
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/authz-module/components/TableControlBar/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface FilterChoice {\n groupName?: string;\n groupIcon?: React.ComponentType;\n displayName: string;\n value: string;\n description?: string;\n}\n\nexport interface MultipleChoiceFilterProps {\n filterButtonText: string;\n filterChoices: FilterChoice[];\n filterValue: string[] | undefined;\n setFilter: (value: string[], newItem: FilterChoice) => void;\n isGrouped?: boolean;\n isSearchable?: boolean;\n onSearchChange?: (value: string) => void;\n iconSrc?: React.ComponentType | undefined;\n disabled?: boolean;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/authz-module/components/TableControlBar/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface FilterChoice {\n groupName?: string;\n groupIcon?: React.ComponentType;\n displayName: string;\n value: string;\n description?: string;\n}\n\nexport interface MultipleChoiceFilterProps {\n filterButtonText: string;\n filterChoices: FilterChoice[];\n filterValue: string[] | undefined;\n setFilter: (value: string[], newItem: FilterChoice) => void;\n isGrouped?: boolean;\n isSearchable?: boolean;\n onSearchChange?: (value: string) => void;\n iconSrc?: React.ComponentType | undefined;\n disabled?: boolean;\n size?: 'sm' | 'md' | 'lg' | 'inline';\n}\n"]}
@@ -1,2 +1,15 @@
1
- declare const Footer: () => import("react").JSX.Element;
1
+ declare const defaultShowingMessage: {
2
+ id: string;
3
+ defaultMessage: string;
4
+ description: string;
5
+ };
6
+ interface FooterProps {
7
+ /**
8
+ * Overrides the "Showing X of Y." text — used by tables whose rows are not
9
+ * assignments (e.g. the team members table counts users). Receives `pageSize`
10
+ * and `itemCount`.
11
+ */
12
+ showingMessage?: typeof defaultShowingMessage;
13
+ }
14
+ declare const Footer: ({ showingMessage }: FooterProps) => import("react").JSX.Element;
2
15
  export default Footer;
@@ -3,13 +3,14 @@ import { useContext } from 'react';
3
3
  import { useIntl } from '@openedx/frontend-base';
4
4
  import { DataTableContext, Pagination, TableFooter } from '@openedx/paragon';
5
5
  import messages from '../messages';
6
- const Footer = () => {
6
+ const defaultShowingMessage = messages['authz.table.footer.items.showing.text'];
7
+ const Footer = ({ showingMessage }) => {
7
8
  const { formatMessage } = useIntl();
8
9
  const { pageCount, gotoPage, state, itemCount, rows,
9
10
  // @ts-expect-error - Paragon's DataTableContext is not typed
10
11
  } = useContext(DataTableContext);
11
12
  const { pageIndex } = state;
12
- return (_jsxs(TableFooter, { children: [_jsx("span", { children: formatMessage(messages['authz.table.footer.items.showing.text'], { pageSize: rows.length, itemCount }) }), _jsx(Pagination, { variant: "reduced", currentPage: pageIndex + 1, pageCount: pageCount, paginationLabel: formatMessage(messages['authz.table.footer.pagination.label']), onPageSelect: (pageNum) => gotoPage(pageNum - 1) })] }));
13
+ return (_jsxs(TableFooter, { children: [_jsx("span", { className: "small", children: formatMessage(showingMessage !== null && showingMessage !== void 0 ? showingMessage : defaultShowingMessage, { pageSize: rows.length, itemCount }) }), _jsx(Pagination, { variant: "reduced", currentPage: pageIndex + 1, pageCount: pageCount, paginationLabel: formatMessage(messages['authz.table.footer.pagination.label']), onPageSelect: (pageNum) => gotoPage(pageNum - 1) })] }));
13
14
  };
14
15
  export default Footer;
15
16
  //# sourceMappingURL=TableFooter.js.map