{intl.formatMessage(messages['wizard.step1.docs.heading'])}
{intl.formatMessage(messages['wizard.step1.docs.body'])}{' '} - + {intl.formatMessage(messages['wizard.step1.docs.link'])}
diff --git a/src/authz-module/role-assignation-wizard/constants.ts b/src/authz-module/role-assignation-wizard/constants.ts index 8fc39484..61d53f93 100644 --- a/src/authz-module/role-assignation-wizard/constants.ts +++ b/src/authz-module/role-assignation-wizard/constants.ts @@ -1,3 +1,5 @@ +// Error codes returned by the role-assignment API. Each code has a matching +// `wizard.save.error.` message in ./messages.ts.
export const ROLE_ASSIGNMENT_ERRORS = {
USER_ALREADY_HAS_ROLE: 'user_already_has_role',
USER_NOT_FOUND: 'user_not_found',
diff --git a/src/authz-module/role-assignation-wizard/hooks/useScopeListData.ts b/src/authz-module/role-assignation-wizard/hooks/useScopeListData.ts
index 205a6976..33b3c2c2 100644
--- a/src/authz-module/role-assignation-wizard/hooks/useScopeListData.ts
+++ b/src/authz-module/role-assignation-wizard/hooks/useScopeListData.ts
@@ -1,13 +1,13 @@
import { useMemo } from 'react';
import { useIntl } from '@edx/frontend-platform/i18n';
-import { Scope } from '@src/types';
+import { ContextType, Scope } from '@src/types';
import { useOrgs, useScopes } from '@src/authz-module/data/hooks';
import { getOrgAggregateScopeKey } from '@src/authz-module/constants';
import messages from '../messages';
import useScopePermissions from './useScopePermissions';
interface UseScopeListDataParams {
- contextType: string | undefined;
+ contextType: ContextType | undefined;
search: string;
orgs: string[];
}
diff --git a/src/authz-module/role-assignation-wizard/hooks/useScopePermissions.ts b/src/authz-module/role-assignation-wizard/hooks/useScopePermissions.ts
index a92122ec..9a4d7eb2 100644
--- a/src/authz-module/role-assignation-wizard/hooks/useScopePermissions.ts
+++ b/src/authz-module/role-assignation-wizard/hooks/useScopePermissions.ts
@@ -2,9 +2,10 @@ import { useMemo } from 'react';
import { useValidateUserPermissions } from '@src/data/hooks';
import { getOrgAggregateScopeKey } from '@src/authz-module/constants';
import { CONTENT_COURSE_PERMISSIONS, CONTENT_LIBRARY_PERMISSIONS } from '@src/authz-module/roles-permissions';
+import type { ContextType } from '@src/types';
interface UseScopePermissionsParams {
- contextType: string | undefined;
+ contextType: ContextType | undefined;
orderedOrgs: string[];
}
diff --git a/src/authz-module/role-assignation-wizard/utils.ts b/src/authz-module/role-assignation-wizard/utils.ts
index 46a1573c..2f0254a8 100644
--- a/src/authz-module/role-assignation-wizard/utils.ts
+++ b/src/authz-module/role-assignation-wizard/utils.ts
@@ -5,19 +5,15 @@ import messages from './messages';
type RoleAssignmentError = PutAssignTeamMembersRoleResponse['errors'][number];
+const KNOWN_ERRORS: string[] = Object.values(ROLE_ASSIGNMENT_ERRORS);
+
export const formatRoleAssignmentError = (
intl: IntlShape,
e: RoleAssignmentError,
): string => {
const params = { userIdentifier: e.userIdentifier, scope: e.scope };
- if (e.error === ROLE_ASSIGNMENT_ERRORS.USER_ALREADY_HAS_ROLE) {
- return intl.formatMessage(messages['wizard.save.error.user_already_has_role'], params);
- }
- if (e.error === ROLE_ASSIGNMENT_ERRORS.USER_NOT_FOUND) {
- return intl.formatMessage(messages['wizard.save.error.user_not_found'], params);
- }
- if (e.error === ROLE_ASSIGNMENT_ERRORS.ROLE_ASSIGNMENT_ERROR) {
- return intl.formatMessage(messages['wizard.save.error.role_assignment_error'], params);
+ if (KNOWN_ERRORS.includes(e.error)) {
+ return intl.formatMessage(messages[`wizard.save.error.${e.error}`], params);
}
return intl.formatMessage(messages['wizard.save.error.default'], { ...params, error: e.error });
};
diff --git a/src/authz-module/roles-permissions/RolesPermissions.test.tsx b/src/authz-module/roles-permissions/RolesPermissions.test.tsx
index a29fa0ae..66d0a4ce 100644
--- a/src/authz-module/roles-permissions/RolesPermissions.test.tsx
+++ b/src/authz-module/roles-permissions/RolesPermissions.test.tsx
@@ -25,6 +25,7 @@ jest.mock('./course/constants', () => ({
],
coursePermissions: [],
courseResourceTypes: [],
+ courseRolesMetadata: [],
}));
jest.mock('./library/constants', () => ({
@@ -35,6 +36,7 @@ jest.mock('./library/constants', () => ({
],
libraryPermissions: [],
libraryResourceTypes: [],
+ libraryRolesMetadata: [],
}));
jest.mock('@openedx/paragon', () => ({
diff --git a/src/authz-module/roles-permissions/index.ts b/src/authz-module/roles-permissions/index.ts
index 690fa56a..e29da434 100644
--- a/src/authz-module/roles-permissions/index.ts
+++ b/src/authz-module/roles-permissions/index.ts
@@ -1,3 +1,7 @@
+import type { RoleMetadata } from '@src/types';
+import { libraryRolesMetadata } from './library/constants';
+import { courseRolesMetadata } from './course/constants';
+
export {
CONTENT_LIBRARY_PERMISSIONS,
libraryResourceTypes,
@@ -13,3 +17,5 @@ export {
rolesObject,
courseRolesMetadata,
} from './course/constants';
+
+export const allRolesMetadata: RoleMetadata[] = [...courseRolesMetadata, ...libraryRolesMetadata];
diff --git a/src/authz-module/roles-permissions/library/utils.test.ts b/src/authz-module/roles-permissions/library/utils.test.ts
index 0d4f0ff5..f5c9b2bb 100644
--- a/src/authz-module/roles-permissions/library/utils.test.ts
+++ b/src/authz-module/roles-permissions/library/utils.test.ts
@@ -1,4 +1,5 @@
import { createIntl } from '@edx/frontend-platform/i18n';
+import type { Role } from '@src/types';
import { buildPermissionMatrixByResource } from './utils';
const intl = createIntl({ locale: 'en', messages: {} });
@@ -14,15 +15,15 @@ const permissions = [
const resources = [
{ key: 'library', label: 'Library', description: '' },
];
-const roles = [
+const roles: Role[] = [
{
- name: 'admin', permissions: ['create_library', 'edit_library'], userCount: 2, role: 'admin', description: '', contextType: '', scope: '',
+ name: 'admin', permissions: ['create_library', 'edit_library'], userCount: 2, role: 'admin', description: '', contextType: 'library', scope: '',
},
{
- name: 'editor', permissions: ['edit_library'], userCount: 2, role: 'editor', description: '', contextType: '', scope: '',
+ name: 'editor', permissions: ['edit_library'], userCount: 2, role: 'editor', description: '', contextType: 'library', scope: '',
},
{
- name: 'guest', permissions: [], userCount: 2, role: 'guest', description: '', contextType: '', scope: '',
+ name: 'guest', permissions: [], userCount: 2, role: 'guest', description: '', contextType: 'library', scope: '',
},
];
diff --git a/src/authz-module/utils.tsx b/src/authz-module/utils.tsx
index fd2a422e..7ae0e429 100644
--- a/src/authz-module/utils.tsx
+++ b/src/authz-module/utils.tsx
@@ -1,6 +1,7 @@
import { Icon } from '@openedx/paragon';
import { FilterList } from '@openedx/paragon/icons';
import { CONTENT_COURSE_PERMISSIONS, CONTENT_LIBRARY_PERMISSIONS } from './roles-permissions';
+import { getScopeContextType } from './constants';
/**
* Returns a header value for a DataTable column that shows a filter icon
@@ -31,16 +32,11 @@ export const getCellHeader = (columnId: string, columnTitle: string, filtersAppl
return columnTitle;
};
-export const getScopeManageAction = (scope: string) => {
- if (scope.startsWith('lib')) {
- return CONTENT_LIBRARY_PERMISSIONS.MANAGE_LIBRARY_TEAM;
- }
- if (scope.startsWith('course')) {
- return CONTENT_COURSE_PERMISSIONS.MANAGE_COURSE_TEAM;
- }
- // Default fallback or throw error for unknown scopes
- return CONTENT_COURSE_PERMISSIONS.MANAGE_COURSE_TEAM;
-};
+export const getScopeManageAction = (scope: string) => (
+ getScopeContextType(scope) === 'library'
+ ? CONTENT_LIBRARY_PERMISSIONS.MANAGE_LIBRARY_TEAM
+ : CONTENT_COURSE_PERMISSIONS.MANAGE_COURSE_TEAM
+);
export const getScopeManageActionPermission = (scope: string) => {
const action = getScopeManageAction(scope);
diff --git a/src/constants.ts b/src/constants.ts
index fc01102d..bfebd972 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -15,6 +15,6 @@ export const STATUS_404 = 404;
export const ERROR_STATUS: ErrorStatusCode = {
[CustomErrors.NO_ACCESS]: [403, 401],
- [CustomErrors.NOT_FOUND]: [400, 404],
+ [CustomErrors.NOT_FOUND]: [STATUS_400, STATUS_404],
[CustomErrors.SERVER_ERROR]: [500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511],
};
diff --git a/src/types.ts b/src/types.ts
index e473331b..aff28d59 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -27,11 +27,13 @@ export interface LibraryMetadata {
allowPublicRead: boolean;
}
+export type ContextType = 'course' | 'library';
+
export interface RoleMetadata {
role: string;
name: string;
description: string;
- contextType: string;
+ contextType: ContextType;
disabled?: boolean;
}
// TODO: remove unnecessary fields when libraries gets removed