{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 3740ed0d..2ffd4677 100644
--- a/src/authz-module/role-assignation-wizard/hooks/useScopeListData.ts
+++ b/src/authz-module/role-assignation-wizard/hooks/useScopeListData.ts
@@ -1,15 +1,14 @@
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 { useCourseAuthoringFlag } from '@src/authz-module/hooks/useCourseAuthoringFlag';
import { getOrgAggregateScopeKey, getPlatformAggregateScopeKey } from '@src/authz-module/constants';
-import type { ContextType } 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 e79487bc..d1421ff4 100644
--- a/src/authz-module/role-assignation-wizard/hooks/useScopePermissions.ts
+++ b/src/authz-module/role-assignation-wizard/hooks/useScopePermissions.ts
@@ -1,11 +1,11 @@
import { useMemo } from 'react';
import { useValidateUserPermissions } from '@src/data/hooks';
import { getOrgAggregateScopeKey, getPlatformAggregateScopeKey } from '@src/authz-module/constants';
-import type { ContextType } 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/index.ts b/src/authz-module/roles-permissions/index.ts
index 2d46d3dd..5073799a 100644
--- a/src/authz-module/roles-permissions/index.ts
+++ b/src/authz-module/roles-permissions/index.ts
@@ -1,4 +1,5 @@
-import { CONTENT_COURSE_PERMISSIONS } from './course/constants';
+import type { RoleMetadata } from '@src/types';
+import { CONTENT_COURSE_PERMISSIONS, courseRolesMetadata as _courseRolesMetadata } from './course/constants';
import { CONTENT_LIBRARY_PERMISSIONS, libraryRolesMetadata as _libraryRolesMetadata } from './library/constants';
export {
@@ -28,4 +29,6 @@ export const VIEW_TEAM_PERMISSIONS: { action: string }[] = [
{ action: CONTENT_LIBRARY_PERMISSIONS.VIEW_LIBRARY_TEAM },
{ action: CONTENT_COURSE_PERMISSIONS.VIEW_COURSE_TEAM },
];
+export const allRolesMetadata: RoleMetadata[] = [..._courseRolesMetadata, ..._libraryRolesMetadata];
+
export { buildPermissionMatrixByResource, getPermissionMetadata } from './utils';
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