diff --git a/src/authz-module/constants.ts b/src/authz-module/constants.ts index a37f69d3..be3e6a6c 100644 --- a/src/authz-module/constants.ts +++ b/src/authz-module/constants.ts @@ -495,6 +495,7 @@ export const rolesObject = [ userCount: 1, name: 'Course Editor', description: 'building and maintaining course content and supporting assets, without operational controls or high impact actions that can affect a live course.', + disabled: true, }, { role: 'course_auditor', @@ -513,6 +514,7 @@ export const rolesObject = [ userCount: 1, name: 'Course Auditor', description: ' QA, compliance review, content review, and general oversight, no changes in Studio.', + disabled: true, }, ]; diff --git a/src/authz-module/utils.test.tsx b/src/authz-module/utils.test.tsx index 502f141b..e11a4dff 100644 --- a/src/authz-module/utils.test.tsx +++ b/src/authz-module/utils.test.tsx @@ -6,8 +6,12 @@ import { getCellHeader, getScopeManageAction, getScopeManageActionPermission } f import { CONTENT_COURSE_PERMISSIONS, CONTENT_LIBRARY_PERMISSIONS } from './constants'; const renderCellHeader = (columnId: string, columnTitle: string, filtersApplied: string[]) => { - const component = getCellHeader(columnId, columnTitle, filtersApplied); - return renderWrapper(
{component}
); + const result = getCellHeader(columnId, columnTitle, filtersApplied); + if (typeof result === 'function') { + const Component = result; + return renderWrapper(); + } + return renderWrapper(
{result}
); }; describe('utils', () => { diff --git a/src/authz-module/utils.tsx b/src/authz-module/utils.tsx index 6d7282ea..47c38e1e 100644 --- a/src/authz-module/utils.tsx +++ b/src/authz-module/utils.tsx @@ -2,14 +2,31 @@ import { Icon } from '@openedx/paragon'; import { FilterList } from '@openedx/paragon/icons'; import { CONTENT_COURSE_PERMISSIONS, CONTENT_LIBRARY_PERMISSIONS } from './constants'; +/** + * Returns a header value for a DataTable column that shows a filter icon + * when the column has an active filter. + * + * When a filter is active, returns a **component function** with a custom + * toString() override. This is necessary because Paragon's TableRow builds + * cell keys via: `${cell.column.Header}${row.id}` + * + * - A JSX element stringifies to "[object Object]", causing duplicate keys. + * - A function with a custom toString() produces a unique string per column. + * + * react-table's render('Header') calls the function as a component, so the + * JSX is still rendered correctly in the table header. + */ export const getCellHeader = (columnId: string, columnTitle: string, filtersApplied: string[]) => { if (filtersApplied.includes(columnId)) { - return ( + const FilteredHeader = () => ( {columnTitle} ); + FilteredHeader.displayName = `FilteredHeader_${columnId}`; + FilteredHeader.toString = () => `FilteredHeader_${columnId}`; + return FilteredHeader; } return columnTitle; };