@openedx/frontend-app-instructor-dashboard 1.0.0-alpha.30 → 1.0.0-alpha.31

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.
@@ -29,6 +29,7 @@ export interface CourseInfoResponse {
29
29
  studioGradingUrl?: string;
30
30
  certificatesEnabled?: boolean;
31
31
  adminConsoleUrl: string | null;
32
+ username: string;
32
33
  }
33
34
  interface EnrollmentCounts extends Record<string, number> {
34
35
  total: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/courseInfo/types.ts"],"names":[],"mappings":"","sourcesContent":["import { TabProps } from '@src/instructorNav/InstructorNav';\n\nexport interface CourseInfoResponse {\n courseId: string,\n displayName: string,\n courseNumber: string,\n courseRun: string,\n enrollmentCounts: EnrollmentCounts,\n start: string | null,\n end: string | null,\n tabs?: TabProps[],\n totalEnrollment: number,\n studioUrl: string,\n pacing: string,\n org?: string,\n numSections: number,\n hasStarted: boolean,\n hasEnded: boolean,\n enrollmentEnd: string | null,\n enrollmentStart: string | null,\n gradeCutoffs: string | null,\n staffCount: number,\n learnerCount: number,\n permissions: {\n admin: boolean,\n dataResearcher: boolean,\n [key: string]: boolean,\n },\n gradebookUrl: string,\n studioGradingUrl?: string,\n certificatesEnabled?: boolean,\n adminConsoleUrl: string | null,\n}\n\ninterface EnrollmentCounts extends Record<string, number> {\n total: number,\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/courseInfo/types.ts"],"names":[],"mappings":"","sourcesContent":["import { TabProps } from '@src/instructorNav/InstructorNav';\n\nexport interface CourseInfoResponse {\n courseId: string,\n displayName: string,\n courseNumber: string,\n courseRun: string,\n enrollmentCounts: EnrollmentCounts,\n start: string | null,\n end: string | null,\n tabs?: TabProps[],\n totalEnrollment: number,\n studioUrl: string,\n pacing: string,\n org?: string,\n numSections: number,\n hasStarted: boolean,\n hasEnded: boolean,\n enrollmentEnd: string | null,\n enrollmentStart: string | null,\n gradeCutoffs: string | null,\n staffCount: number,\n learnerCount: number,\n permissions: {\n admin: boolean,\n dataResearcher: boolean,\n [key: string]: boolean,\n },\n gradebookUrl: string,\n studioGradingUrl?: string,\n certificatesEnabled?: boolean,\n adminConsoleUrl: string | null,\n username: string,\n}\n\ninterface EnrollmentCounts extends Record<string, number> {\n total: number,\n}\n"]}
@@ -2,11 +2,12 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useState } from 'react';
3
3
  import { useParams } from 'react-router-dom';
4
4
  import { useIntl } from '@openedx/frontend-base';
5
- import { ActionRow, Button, Form, FormControl, FormLabel, ModalDialog } from '@openedx/paragon';
5
+ import { ActionRow, Button, Form, FormControl, FormLabel, ModalDialog, OverlayTrigger, Tooltip } from '@openedx/paragon';
6
6
  import { useAddTeamMember, useRemoveTeamMember, useRoles } from '../../courseTeam/data/apiHook';
7
7
  import messages from '../../courseTeam/messages';
8
8
  import { useAlert } from '../../providers/AlertProvider';
9
9
  import { TEAM_MEMBER_ACTION } from '../constants';
10
+ import { useCourseInfo } from '../../data/apiHook';
10
11
  const EditTeamMemberModal = ({ isOpen, user, onClose }) => {
11
12
  const intl = useIntl();
12
13
  const { courseId = '' } = useParams();
@@ -15,7 +16,9 @@ const EditTeamMemberModal = ({ isOpen, user, onClose }) => {
15
16
  const { mutate: addTeamMember, isPending: isAdding } = useAddTeamMember(courseId);
16
17
  const { mutate: removeTeamMember, isPending: isRemoving } = useRemoveTeamMember(courseId);
17
18
  const { showModal } = useAlert();
18
- const { data: { results } = { results: [] } } = useRoles(courseId);
19
+ const { data: { results } = { results: [] } } = useRoles(courseId, true);
20
+ const { data } = useCourseInfo(courseId);
21
+ const { username: currentUser } = data || {};
19
22
  useEffect(() => {
20
23
  if (isOpen) {
21
24
  setKeepRoles(user.roles.map(role => role.role));
@@ -85,7 +88,15 @@ const EditTeamMemberModal = ({ isOpen, user, onClose }) => {
85
88
  }
86
89
  };
87
90
  return (_jsxs(ModalDialog, { isOpen: isOpen, title: intl.formatMessage(messages.editTeamTitle, { username: user.username }), onClose: onClose, isOverflowVisible: false, children: [_jsx(ModalDialog.Header, { className: "border-light-700 border-bottom", children: _jsx("h3", { className: "text-primary-500", children: intl.formatMessage(messages.editTeamTitle, { username: user.username }) }) }), _jsxs(ModalDialog.Body, { className: "position-relative overflow-auto", children: [_jsx("p", { children: intl.formatMessage(messages.editInstructions, { username: user.username }) }), _jsx(Form.CheckboxSet, { onChange: (e) => handleToggleRole(e.target.value), value: keepRoles, name: "keepRoles", children: (user.roles || [])
88
- .map((role) => (_jsx(Form.Checkbox, { className: "mt-2", value: role.role, children: role.displayName }, role.role))) }), _jsx(FormLabel, { className: "mt-4", children: intl.formatMessage(messages.addRole) }), _jsx(FormControl, { as: "select", disabled: roles.length === 1, onChange: (e) => setSelectedRole(e.target.value), value: selectedRole, children: roles.map((role) => (_jsx("option", { value: role.role, children: role.displayName }, role.role))) })] }), _jsx(ModalDialog.Footer, { className: "border-light-700 border-top", children: _jsxs(ActionRow, { children: [_jsx(Button, { variant: "tertiary", onClick: onClose, children: intl.formatMessage(messages.cancelButton) }), _jsx(Button, { variant: "primary", onClick: handleSave, disabled: isAdding || isRemoving || (keepRoles.length === user.roles.length && !selectedRole), children: intl.formatMessage(messages.saveButton) })] }) })] }));
91
+ .map((role) => {
92
+ // Disable roles that user is not available to edit based on his current role
93
+ // Also Admins cannot remove their own Admin role
94
+ // Discussion Admins cannot remove their own Discussion Admins role, unless they have Admin role as well
95
+ const isDiscussionAdminWithoutAdminRole = currentUser === user.username && role.role === 'Administrator' && !user.roles.some(r => r.role === 'instructor');
96
+ const isOwnAdminRole = currentUser === user.username && role.role === 'instructor';
97
+ const isEditAvailable = (results === null || results === void 0 ? void 0 : results.some(availableRole => availableRole.role === role.role)) && !isOwnAdminRole && !isDiscussionAdminWithoutAdminRole;
98
+ return (isEditAvailable ? (_jsx(Form.Checkbox, { className: "mt-2", value: role.role, children: role.displayName }, role.role)) : (_jsx(OverlayTrigger, { placement: "top", overlay: _jsx(Tooltip, { id: `tooltip-${role.role}`, className: "info-tooltip", children: isOwnAdminRole || isDiscussionAdminWithoutAdminRole ? intl.formatMessage(messages.cannotRemoveOwnRole) : intl.formatMessage(messages.roleNotEditable) }), children: _jsx(Form.Checkbox, { className: "mt-2", value: role.role, disabled: true, children: role.displayName }, role.role) })));
99
+ }) }), _jsx(FormLabel, { className: "mt-4", children: intl.formatMessage(messages.addRole) }), _jsx(FormControl, { as: "select", disabled: roles.length === 1, onChange: (e) => setSelectedRole(e.target.value), value: selectedRole, children: roles.map((role) => (_jsx("option", { value: role.role, children: role.displayName }, role.role))) })] }), _jsx(ModalDialog.Footer, { className: "border-light-700 border-top", children: _jsxs(ActionRow, { children: [_jsx(Button, { variant: "tertiary", onClick: onClose, children: intl.formatMessage(messages.cancelButton) }), _jsx(Button, { variant: "primary", onClick: handleSave, disabled: isAdding || isRemoving || (keepRoles.length === user.roles.length && !selectedRole), children: intl.formatMessage(messages.saveButton) })] }) })] }));
89
100
  };
90
101
  export default EditTeamMemberModal;
91
102
  //# sourceMappingURL=EditTeamMemberModal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EditTeamMemberModal.js","sourceRoot":"","sources":["../../../src/courseTeam/components/EditTeamMemberModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { ActionRow, Button, Form, FormControl, FormLabel, ModalDialog } from '@openedx/paragon';\nimport { useAddTeamMember, useRemoveTeamMember, useRoles } from '@src/courseTeam/data/apiHook';\nimport messages from '@src/courseTeam/messages';\nimport { CourseTeamMember, Role } from '@src/courseTeam/types';\nimport { useAlert } from '@src/providers/AlertProvider';\nimport { TEAM_MEMBER_ACTION } from '../constants';\n\ninterface EditTeamMemberModalProps {\n isOpen: boolean,\n user: CourseTeamMember,\n onClose: () => void,\n}\n\nconst EditTeamMemberModal = ({ isOpen, user, onClose }: EditTeamMemberModalProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [selectedRole, setSelectedRole] = useState('');\n const [keepRoles, setKeepRoles] = useState<string[]>([]);\n const { mutate: addTeamMember, isPending: isAdding } = useAddTeamMember(courseId);\n const { mutate: removeTeamMember, isPending: isRemoving } = useRemoveTeamMember(courseId);\n const { showModal } = useAlert();\n\n const { data: { results } = { results: [] } } = useRoles(courseId);\n\n useEffect(() => {\n if (isOpen) {\n setKeepRoles(user.roles.map(role => role.role));\n setSelectedRole('');\n }\n }, [isOpen, user]);\n\n const filteredRoles = results?.filter(role => !user.roles.some(userRole => userRole.role === role.role)) || [];\n\n const roles = [{ role: '', displayName: intl.formatMessage(messages.rolePlaceholder) }, ...filteredRoles];\n\n const handleToggleRole = (roleName: string) => {\n if (keepRoles.includes(roleName)) {\n setKeepRoles(keepRoles.filter(role => role !== roleName));\n } else {\n setKeepRoles([...keepRoles, roleName]);\n }\n };\n\n const handleSave = () => {\n const rolesToRemove = user.roles.filter(role => !keepRoles.includes(role.role)).map(role => role.role);\n const hasRolesToAdd = selectedRole;\n const hasRolesToRemove = rolesToRemove.length > 0;\n\n // Sequential approach: remove roles first, then add new role\n if (hasRolesToRemove) {\n removeTeamMember({ identifier: user.username, roles: rolesToRemove }, {\n onSuccess: () => {\n // After successful removal, add new role if needed\n if (hasRolesToAdd) {\n addTeamMember({ identifiers: [user.username], role: selectedRole, action: TEAM_MEMBER_ACTION.ALLOW }, {\n onSuccess: () => {\n onClose();\n },\n onError: () => {\n showModal({\n message: intl.formatMessage(messages.addRoleError),\n variant: 'danger',\n confirmText: intl.formatMessage(messages.closeButton),\n });\n }\n });\n } else {\n onClose();\n }\n },\n onError: () => {\n showModal({\n message: intl.formatMessage(messages.removeTeamMemberError, { username: user.username }),\n variant: 'danger',\n confirmText: intl.formatMessage(messages.closeButton),\n });\n }\n });\n } else if (hasRolesToAdd) {\n // Only add operation needed\n addTeamMember({ identifiers: [user.username], role: selectedRole, action: TEAM_MEMBER_ACTION.ALLOW }, {\n onSuccess: () => {\n onClose();\n },\n onError: () => {\n showModal({\n message: intl.formatMessage(messages.addRoleError),\n variant: 'danger',\n confirmText: intl.formatMessage(messages.closeButton),\n });\n }\n });\n }\n };\n\n return (\n <ModalDialog\n isOpen={isOpen}\n title={intl.formatMessage(messages.editTeamTitle, { username: user.username })}\n onClose={onClose}\n isOverflowVisible={false}\n >\n <ModalDialog.Header className=\"border-light-700 border-bottom\">\n <h3 className=\"text-primary-500\">{intl.formatMessage(messages.editTeamTitle, { username: user.username })}</h3>\n </ModalDialog.Header>\n <ModalDialog.Body className=\"position-relative overflow-auto\">\n <p>{intl.formatMessage(messages.editInstructions, { username: user.username })}</p>\n <Form.CheckboxSet onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleToggleRole(e.target.value)} value={keepRoles} name=\"keepRoles\">\n {\n (user.roles || [])\n .map((role: Role) => (\n <Form.Checkbox className=\"mt-2\" key={role.role} value={role.role}>\n {role.displayName}\n </Form.Checkbox>\n ))\n }\n </Form.CheckboxSet>\n <FormLabel className=\"mt-4\">{intl.formatMessage(messages.addRole)}</FormLabel>\n <FormControl\n as=\"select\"\n disabled={roles.length === 1}\n onChange={(e: React.ChangeEvent<HTMLSelectElement>) => setSelectedRole(e.target.value)}\n value={selectedRole}\n >\n {\n roles.map((role) => (\n <option key={role.role} value={role.role}>\n {role.displayName}\n </option>\n ))\n }\n </FormControl>\n </ModalDialog.Body>\n <ModalDialog.Footer className=\"border-light-700 border-top\">\n <ActionRow>\n <Button variant=\"tertiary\" onClick={onClose}>{intl.formatMessage(messages.cancelButton)}</Button>\n <Button variant=\"primary\" onClick={handleSave} disabled={isAdding || isRemoving || (keepRoles.length === user.roles.length && !selectedRole)}>\n {intl.formatMessage(messages.saveButton)}\n </Button>\n </ActionRow>\n </ModalDialog.Footer>\n </ModalDialog>\n );\n};\n\nexport default EditTeamMemberModal;\n"]}
1
+ {"version":3,"file":"EditTeamMemberModal.js","sourceRoot":"","sources":["../../../src/courseTeam/components/EditTeamMemberModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { ActionRow, Button, Form, FormControl, FormLabel, ModalDialog, OverlayTrigger, Tooltip } from '@openedx/paragon';\nimport { useAddTeamMember, useRemoveTeamMember, useRoles } from '@src/courseTeam/data/apiHook';\nimport messages from '@src/courseTeam/messages';\nimport { CourseTeamMember, Role } from '@src/courseTeam/types';\nimport { useAlert } from '@src/providers/AlertProvider';\nimport { TEAM_MEMBER_ACTION } from '../constants';\nimport { useCourseInfo } from '@src/data/apiHook';\n\ninterface EditTeamMemberModalProps {\n isOpen: boolean,\n user: CourseTeamMember,\n onClose: () => void,\n}\n\nconst EditTeamMemberModal = ({ isOpen, user, onClose }: EditTeamMemberModalProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [selectedRole, setSelectedRole] = useState('');\n const [keepRoles, setKeepRoles] = useState<string[]>([]);\n const { mutate: addTeamMember, isPending: isAdding } = useAddTeamMember(courseId);\n const { mutate: removeTeamMember, isPending: isRemoving } = useRemoveTeamMember(courseId);\n const { showModal } = useAlert();\n\n const { data: { results } = { results: [] } } = useRoles(courseId, true);\n\n const { data } = useCourseInfo(courseId);\n const { username: currentUser } = data || {};\n\n useEffect(() => {\n if (isOpen) {\n setKeepRoles(user.roles.map(role => role.role));\n setSelectedRole('');\n }\n }, [isOpen, user]);\n\n const filteredRoles = results?.filter(role => !user.roles.some(userRole => userRole.role === role.role)) || [];\n\n const roles = [{ role: '', displayName: intl.formatMessage(messages.rolePlaceholder) }, ...filteredRoles];\n\n const handleToggleRole = (roleName: string) => {\n if (keepRoles.includes(roleName)) {\n setKeepRoles(keepRoles.filter(role => role !== roleName));\n } else {\n setKeepRoles([...keepRoles, roleName]);\n }\n };\n\n const handleSave = () => {\n const rolesToRemove = user.roles.filter(role => !keepRoles.includes(role.role)).map(role => role.role);\n const hasRolesToAdd = selectedRole;\n const hasRolesToRemove = rolesToRemove.length > 0;\n\n // Sequential approach: remove roles first, then add new role\n if (hasRolesToRemove) {\n removeTeamMember({ identifier: user.username, roles: rolesToRemove }, {\n onSuccess: () => {\n // After successful removal, add new role if needed\n if (hasRolesToAdd) {\n addTeamMember({ identifiers: [user.username], role: selectedRole, action: TEAM_MEMBER_ACTION.ALLOW }, {\n onSuccess: () => {\n onClose();\n },\n onError: () => {\n showModal({\n message: intl.formatMessage(messages.addRoleError),\n variant: 'danger',\n confirmText: intl.formatMessage(messages.closeButton),\n });\n }\n });\n } else {\n onClose();\n }\n },\n onError: () => {\n showModal({\n message: intl.formatMessage(messages.removeTeamMemberError, { username: user.username }),\n variant: 'danger',\n confirmText: intl.formatMessage(messages.closeButton),\n });\n }\n });\n } else if (hasRolesToAdd) {\n // Only add operation needed\n addTeamMember({ identifiers: [user.username], role: selectedRole, action: TEAM_MEMBER_ACTION.ALLOW }, {\n onSuccess: () => {\n onClose();\n },\n onError: () => {\n showModal({\n message: intl.formatMessage(messages.addRoleError),\n variant: 'danger',\n confirmText: intl.formatMessage(messages.closeButton),\n });\n }\n });\n }\n };\n\n return (\n <ModalDialog\n isOpen={isOpen}\n title={intl.formatMessage(messages.editTeamTitle, { username: user.username })}\n onClose={onClose}\n isOverflowVisible={false}\n >\n <ModalDialog.Header className=\"border-light-700 border-bottom\">\n <h3 className=\"text-primary-500\">{intl.formatMessage(messages.editTeamTitle, { username: user.username })}</h3>\n </ModalDialog.Header>\n <ModalDialog.Body className=\"position-relative overflow-auto\">\n <p>{intl.formatMessage(messages.editInstructions, { username: user.username })}</p>\n <Form.CheckboxSet onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleToggleRole(e.target.value)} value={keepRoles} name=\"keepRoles\">\n {\n (user.roles || [])\n .map((role: Role) => {\n // Disable roles that user is not available to edit based on his current role\n // Also Admins cannot remove their own Admin role\n // Discussion Admins cannot remove their own Discussion Admins role, unless they have Admin role as well\n const isDiscussionAdminWithoutAdminRole = currentUser === user.username && role.role === 'Administrator' && !user.roles.some(r => r.role === 'instructor');\n const isOwnAdminRole = currentUser === user.username && role.role === 'instructor';\n const isEditAvailable = results?.some(availableRole => availableRole.role === role.role) && !isOwnAdminRole && !isDiscussionAdminWithoutAdminRole;\n return (\n isEditAvailable ? (\n <Form.Checkbox className=\"mt-2\" key={role.role} value={role.role}>\n {role.displayName}\n </Form.Checkbox>\n ) : (\n <OverlayTrigger\n placement=\"top\"\n overlay={\n <Tooltip id={`tooltip-${role.role}`} className=\"info-tooltip\">{isOwnAdminRole || isDiscussionAdminWithoutAdminRole ? intl.formatMessage(messages.cannotRemoveOwnRole) : intl.formatMessage(messages.roleNotEditable)}</Tooltip>\n }\n >\n <Form.Checkbox className=\"mt-2\" key={role.role} value={role.role} disabled>\n {role.displayName}\n </Form.Checkbox>\n </OverlayTrigger>\n )\n );\n })\n }\n </Form.CheckboxSet>\n <FormLabel className=\"mt-4\">{intl.formatMessage(messages.addRole)}</FormLabel>\n <FormControl\n as=\"select\"\n disabled={roles.length === 1}\n onChange={(e: React.ChangeEvent<HTMLSelectElement>) => setSelectedRole(e.target.value)}\n value={selectedRole}\n >\n {\n roles.map((role) => (\n <option key={role.role} value={role.role}>\n {role.displayName}\n </option>\n ))\n }\n </FormControl>\n </ModalDialog.Body>\n <ModalDialog.Footer className=\"border-light-700 border-top\">\n <ActionRow>\n <Button variant=\"tertiary\" onClick={onClose}>{intl.formatMessage(messages.cancelButton)}</Button>\n <Button variant=\"primary\" onClick={handleSave} disabled={isAdding || isRemoving || (keepRoles.length === user.roles.length && !selectedRole)}>\n {intl.formatMessage(messages.saveButton)}\n </Button>\n </ActionRow>\n </ModalDialog.Footer>\n </ModalDialog>\n );\n};\n\nexport default EditTeamMemberModal;\n"]}
@@ -1,6 +1,6 @@
1
1
  import { DataList } from '../../types';
2
2
  import { TeamMembersResponse, CourseTeamMember, CourseTeamMemberQueryParams, Role, AddTeamMemberParams } from '../../courseTeam/types';
3
3
  export declare const getTeamMembers: (courseId: string, params: CourseTeamMemberQueryParams) => Promise<DataList<CourseTeamMember>>;
4
- export declare const getRoles: (courseId: string) => Promise<Omit<DataList<Role>, "numPages" | "count">>;
4
+ export declare const getRoles: (courseId: string, editableRoles?: boolean) => Promise<Omit<DataList<Role>, "numPages" | "count">>;
5
5
  export declare const addTeamMember: (courseId: string, params: AddTeamMemberParams) => Promise<TeamMembersResponse>;
6
6
  export declare const removeTeamMember: (courseId: string, identifier: string, roles: string[]) => Promise<TeamMembersResponse>;
@@ -23,8 +23,8 @@ export const getTeamMembers = (courseId, params) => __awaiter(void 0, void 0, vo
23
23
  const { data } = yield getAuthenticatedHttpClient().get(`${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team?${queryParams.toString()}`);
24
24
  return camelCaseObject(data);
25
25
  });
26
- export const getRoles = (courseId) => __awaiter(void 0, void 0, void 0, function* () {
27
- const { data } = yield getAuthenticatedHttpClient().get(`${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team/roles`);
26
+ export const getRoles = (courseId_1, ...args_1) => __awaiter(void 0, [courseId_1, ...args_1], void 0, function* (courseId, editableRoles = false) {
27
+ const { data } = yield getAuthenticatedHttpClient().get(`${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team/roles${editableRoles ? '?editable=true' : ''}`);
28
28
  return camelCaseObject(data);
29
29
  });
30
30
  export const addTeamMember = (courseId, params) => __awaiter(void 0, void 0, void 0, function* () {
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/courseTeam/data/api.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAU9C,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,QAAgB,EAChB,MAAmC,EACE,EAAE;IACvC,MAAM,WAAW,GAAG,IAAI,eAAe,CAAC;QACtC,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE;QAClC,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE;KACtC,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3B,WAAW,CAAC,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CACrD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,SAAS,WAAW,CAAC,QAAQ,EAAE,EAAE,CAC1F,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAO,QAAgB,EAAuD,EAAE;IACtG,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CACrD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,aAAa,CACtE,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAO,QAAgB,EAAE,MAA2B,EAAgC,EAAE;IACjH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,IAAI,CACtD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,OAAO,EAC/D,MAAM,CACP,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAO,QAAgB,EAAE,UAAkB,EAAE,KAAe,EAAgC,EAAE;IAC5H,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,MAAM,CACxD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,SAAS,UAAU,EAAE,EAC7E,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,CACpB,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC","sourcesContent":["import { camelCaseObject, getAuthenticatedHttpClient } from '@openedx/frontend-base';\nimport { getApiBaseUrl } from '@src/data/api';\nimport { DataList } from '@src/types';\nimport {\n TeamMembersResponse,\n CourseTeamMember,\n CourseTeamMemberQueryParams,\n Role,\n AddTeamMemberParams,\n} from '@src/courseTeam/types';\n\nexport const getTeamMembers = async (\n courseId: string,\n params: CourseTeamMemberQueryParams\n): Promise<DataList<CourseTeamMember>> => {\n const queryParams = new URLSearchParams({\n page: (params.page + 1).toString(),\n page_size: params.pageSize.toString(),\n });\n\n if (params.emailOrUsername) {\n queryParams.append('email_or_username', params.emailOrUsername);\n }\n\n if (params.role) {\n queryParams.append('role', params.role);\n }\n\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team?${queryParams.toString()}`\n );\n return camelCaseObject(data);\n};\n\nexport const getRoles = async (courseId: string): Promise<Omit<DataList<Role>, 'numPages' | 'count'>> => {\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team/roles`\n );\n return camelCaseObject(data);\n};\n\nexport const addTeamMember = async (courseId: string, params: AddTeamMemberParams): Promise<TeamMembersResponse> => {\n const { data } = await getAuthenticatedHttpClient().post(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team`,\n params\n );\n return camelCaseObject(data);\n};\n\nexport const removeTeamMember = async (courseId: string, identifier: string, roles: string[]): Promise<TeamMembersResponse> => {\n const { data } = await getAuthenticatedHttpClient().delete(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team/${identifier}`,\n { data: { roles } }\n );\n return camelCaseObject(data);\n};\n"]}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/courseTeam/data/api.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAU9C,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,QAAgB,EAChB,MAAmC,EACE,EAAE;IACvC,MAAM,WAAW,GAAG,IAAI,eAAe,CAAC;QACtC,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE;QAClC,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE;KACtC,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3B,WAAW,CAAC,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CACrD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,SAAS,WAAW,CAAC,QAAQ,EAAE,EAAE,CAC1F,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,wBAAqG,EAAE,+DAAhG,QAAgB,EAAE,aAAa,GAAG,KAAK;IACpE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CACrD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,cAAc,aAAa,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9G,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAO,QAAgB,EAAE,MAA2B,EAAgC,EAAE;IACjH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,IAAI,CACtD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,OAAO,EAC/D,MAAM,CACP,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAO,QAAgB,EAAE,UAAkB,EAAE,KAAe,EAAgC,EAAE;IAC5H,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,MAAM,CACxD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,SAAS,UAAU,EAAE,EAC7E,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,CACpB,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC","sourcesContent":["import { camelCaseObject, getAuthenticatedHttpClient } from '@openedx/frontend-base';\nimport { getApiBaseUrl } from '@src/data/api';\nimport { DataList } from '@src/types';\nimport {\n TeamMembersResponse,\n CourseTeamMember,\n CourseTeamMemberQueryParams,\n Role,\n AddTeamMemberParams,\n} from '@src/courseTeam/types';\n\nexport const getTeamMembers = async (\n courseId: string,\n params: CourseTeamMemberQueryParams\n): Promise<DataList<CourseTeamMember>> => {\n const queryParams = new URLSearchParams({\n page: (params.page + 1).toString(),\n page_size: params.pageSize.toString(),\n });\n\n if (params.emailOrUsername) {\n queryParams.append('email_or_username', params.emailOrUsername);\n }\n\n if (params.role) {\n queryParams.append('role', params.role);\n }\n\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team?${queryParams.toString()}`\n );\n return camelCaseObject(data);\n};\n\nexport const getRoles = async (courseId: string, editableRoles = false): Promise<Omit<DataList<Role>, 'numPages' | 'count'>> => {\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team/roles${editableRoles ? '?editable=true' : ''}`\n );\n return camelCaseObject(data);\n};\n\nexport const addTeamMember = async (courseId: string, params: AddTeamMemberParams): Promise<TeamMembersResponse> => {\n const { data } = await getAuthenticatedHttpClient().post(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team`,\n params\n );\n return camelCaseObject(data);\n};\n\nexport const removeTeamMember = async (courseId: string, identifier: string, roles: string[]): Promise<TeamMembersResponse> => {\n const { data } = await getAuthenticatedHttpClient().delete(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team/${identifier}`,\n { data: { roles } }\n );\n return camelCaseObject(data);\n};\n"]}
@@ -1,6 +1,6 @@
1
1
  import { AddTeamMemberParams, CourseTeamMemberQueryParams } from '../../courseTeam/types';
2
2
  export declare const useTeamMembers: (courseId: string, params: CourseTeamMemberQueryParams) => import("@tanstack/react-query").UseQueryResult<import("../../types").DataList<import("../../courseTeam/types").CourseTeamMember>, Error>;
3
- export declare const useRoles: (courseId: string) => import("@tanstack/react-query").UseQueryResult<Omit<import("../../types").DataList<import("../../courseTeam/types").Role>, "count" | "numPages">, Error>;
3
+ export declare const useRoles: (courseId: string, editableRoles?: boolean) => import("@tanstack/react-query").UseQueryResult<Omit<import("../../types").DataList<import("../../courseTeam/types").Role>, "count" | "numPages">, Error>;
4
4
  export declare const useAddTeamMember: (courseId: string) => import("@tanstack/react-query").UseMutationResult<import("../../courseTeam/types").TeamMembersResponse, Error, AddTeamMemberParams, unknown>;
5
5
  export declare const useRemoveTeamMember: (courseId: string) => import("@tanstack/react-query").UseMutationResult<import("../../courseTeam/types").TeamMembersResponse, Error, {
6
6
  identifier: string;
@@ -6,9 +6,9 @@ export const useTeamMembers = (courseId, params) => (useQuery({
6
6
  queryFn: () => getTeamMembers(courseId, params),
7
7
  enabled: !!courseId,
8
8
  }));
9
- export const useRoles = (courseId) => (useQuery({
10
- queryKey: courseTeamQueryKeys.roles(courseId),
11
- queryFn: () => getRoles(courseId),
9
+ export const useRoles = (courseId, editableRoles = false) => (useQuery({
10
+ queryKey: courseTeamQueryKeys.roles(courseId, editableRoles),
11
+ queryFn: () => getRoles(courseId, editableRoles),
12
12
  enabled: !!courseId,
13
13
  }));
14
14
  export const useAddTeamMember = (courseId) => {
@@ -1 +1 @@
1
- {"version":3,"file":"apiHook.js","sourceRoot":"","sources":["../../../src/courseTeam/data/apiHook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACrG,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAGrE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,QAAgB,EAAE,MAAmC,EAAE,EAAE,CAAC,CACvF,QAAQ,CAAC;IACP,QAAQ,EAAE,mBAAmB,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC;IACjE,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC/C,OAAO,EAAE,CAAC,CAAC,QAAQ;CACpB,CAAC,CACH,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC,CAC5C,QAAQ,CAAC;IACP,QAAQ,EAAE,mBAAmB,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC7C,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;IACjC,OAAO,EAAE,CAAC,CAAC,QAAQ;CACpB,CAAC,CACH,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,QAAgB,EAAE,EAAE;IACnD,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,CAAC,WAAW,CAAC;QAClB,UAAU,EAAE,CAAC,MAA2B,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC5E,SAAS,EAAE,GAAG,EAAE;YACd,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACtF,CAAC;KACF,CAAC,CACD,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAgB,EAAE,EAAE;IACtD,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,CAAC,WAAW,CAAC;QAClB,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,KAAK,EAA2C,EAAE,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC;QAC7H,SAAS,EAAE,GAAG,EAAE;YACd,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACtF,CAAC;KACF,CAAC,CACD,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { addTeamMember, getRoles, getTeamMembers, removeTeamMember } from '@src/courseTeam/data/api';\nimport { courseTeamQueryKeys } from '@src/courseTeam/data/queryKeys';\nimport { AddTeamMemberParams, CourseTeamMemberQueryParams } from '@src/courseTeam/types';\n\nexport const useTeamMembers = (courseId: string, params: CourseTeamMemberQueryParams) => (\n useQuery({\n queryKey: courseTeamQueryKeys.byCoursePaginated(courseId, params),\n queryFn: () => getTeamMembers(courseId, params),\n enabled: !!courseId,\n })\n);\n\nexport const useRoles = (courseId: string) => (\n useQuery({\n queryKey: courseTeamQueryKeys.roles(courseId),\n queryFn: () => getRoles(courseId),\n enabled: !!courseId,\n })\n);\n\nexport const useAddTeamMember = (courseId: string) => {\n const queryClient = useQueryClient();\n return (useMutation({\n mutationFn: (params: AddTeamMemberParams) => addTeamMember(courseId, params),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: courseTeamQueryKeys.byCourse(courseId) });\n }\n })\n );\n};\n\nexport const useRemoveTeamMember = (courseId: string) => {\n const queryClient = useQueryClient();\n return (useMutation({\n mutationFn: ({ identifier, roles }: { identifier: string, roles: string[] }) => removeTeamMember(courseId, identifier, roles),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: courseTeamQueryKeys.byCourse(courseId) });\n }\n })\n );\n};\n"]}
1
+ {"version":3,"file":"apiHook.js","sourceRoot":"","sources":["../../../src/courseTeam/data/apiHook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACrG,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAGrE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,QAAgB,EAAE,MAAmC,EAAE,EAAE,CAAC,CACvF,QAAQ,CAAC;IACP,QAAQ,EAAE,mBAAmB,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC;IACjE,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC/C,OAAO,EAAE,CAAC,CAAC,QAAQ;CACpB,CAAC,CACH,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,QAAgB,EAAE,aAAa,GAAG,KAAK,EAAE,EAAE,CAAC,CACnE,QAAQ,CAAC;IACP,QAAQ,EAAE,mBAAmB,CAAC,KAAK,CAAC,QAAQ,EAAE,aAAa,CAAC;IAC5D,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IAChD,OAAO,EAAE,CAAC,CAAC,QAAQ;CACpB,CAAC,CACH,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,QAAgB,EAAE,EAAE;IACnD,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,CAAC,WAAW,CAAC;QAClB,UAAU,EAAE,CAAC,MAA2B,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC5E,SAAS,EAAE,GAAG,EAAE;YACd,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACtF,CAAC;KACF,CAAC,CACD,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAgB,EAAE,EAAE;IACtD,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,CAAC,WAAW,CAAC;QAClB,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,KAAK,EAA2C,EAAE,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC;QAC7H,SAAS,EAAE,GAAG,EAAE;YACd,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACtF,CAAC;KACF,CAAC,CACD,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { addTeamMember, getRoles, getTeamMembers, removeTeamMember } from '@src/courseTeam/data/api';\nimport { courseTeamQueryKeys } from '@src/courseTeam/data/queryKeys';\nimport { AddTeamMemberParams, CourseTeamMemberQueryParams } from '@src/courseTeam/types';\n\nexport const useTeamMembers = (courseId: string, params: CourseTeamMemberQueryParams) => (\n useQuery({\n queryKey: courseTeamQueryKeys.byCoursePaginated(courseId, params),\n queryFn: () => getTeamMembers(courseId, params),\n enabled: !!courseId,\n })\n);\n\nexport const useRoles = (courseId: string, editableRoles = false) => (\n useQuery({\n queryKey: courseTeamQueryKeys.roles(courseId, editableRoles),\n queryFn: () => getRoles(courseId, editableRoles),\n enabled: !!courseId,\n })\n);\n\nexport const useAddTeamMember = (courseId: string) => {\n const queryClient = useQueryClient();\n return (useMutation({\n mutationFn: (params: AddTeamMemberParams) => addTeamMember(courseId, params),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: courseTeamQueryKeys.byCourse(courseId) });\n }\n })\n );\n};\n\nexport const useRemoveTeamMember = (courseId: string) => {\n const queryClient = useQueryClient();\n return (useMutation({\n mutationFn: ({ identifier, roles }: { identifier: string, roles: string[] }) => removeTeamMember(courseId, identifier, roles),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: courseTeamQueryKeys.byCourse(courseId) });\n }\n })\n );\n};\n"]}
@@ -3,5 +3,5 @@ export declare const courseTeamQueryKeys: {
3
3
  all: readonly ["org.openedx.frontend.app.instructorDashboard", "courseTeam"];
4
4
  byCourse: (courseId: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "courseTeam", string];
5
5
  byCoursePaginated: (courseId: string, params: CourseTeamMemberQueryParams) => readonly ["org.openedx.frontend.app.instructorDashboard", "courseTeam", string, number, number, string, string];
6
- roles: (courseId: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "courseTeam", string, "roles"];
6
+ roles: (courseId: string, editableRoles: boolean) => readonly ["org.openedx.frontend.app.instructorDashboard", "courseTeam", string, "roles", boolean];
7
7
  };
@@ -9,6 +9,6 @@ export const courseTeamQueryKeys = {
9
9
  params.emailOrUsername || '',
10
10
  params.role || ''
11
11
  ],
12
- roles: (courseId) => [...courseTeamQueryKeys.byCourse(courseId), 'roles'],
12
+ roles: (courseId, editableRoles) => [...courseTeamQueryKeys.byCourse(courseId), 'roles', editableRoles],
13
13
  };
14
14
  //# sourceMappingURL=queryKeys.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"queryKeys.js","sourceRoot":"","sources":["../../../src/courseTeam/data/queryKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,GAAG,EAAE,CAAC,KAAK,EAAE,YAAY,CAAU;IACnC,QAAQ,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC,GAAG,mBAAmB,CAAC,GAAG,EAAE,QAAQ,CAAU;IAC/E,iBAAiB,EAAE,CACjB,QAAgB,EAChB,MAAmC,EACnC,EAAE,CAAC;QACH,GAAG,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACzC,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,QAAQ;QACf,MAAM,CAAC,eAAe,IAAI,EAAE;QAC5B,MAAM,CAAC,IAAI,IAAI,EAAE;KACT;IACV,KAAK,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC,GAAG,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAU;CAC3F,CAAC","sourcesContent":["import { appId } from '@src/constants';\nimport { CourseTeamMemberQueryParams } from '@src/courseTeam/types';\n\nexport const courseTeamQueryKeys = {\n all: [appId, 'courseTeam'] as const,\n byCourse: (courseId: string) => [...courseTeamQueryKeys.all, courseId] as const,\n byCoursePaginated: (\n courseId: string,\n params: CourseTeamMemberQueryParams\n ) => [\n ...courseTeamQueryKeys.byCourse(courseId),\n params.page,\n params.pageSize,\n params.emailOrUsername || '',\n params.role || ''\n ] as const,\n roles: (courseId: string) => [...courseTeamQueryKeys.byCourse(courseId), 'roles'] as const,\n};\n"]}
1
+ {"version":3,"file":"queryKeys.js","sourceRoot":"","sources":["../../../src/courseTeam/data/queryKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,GAAG,EAAE,CAAC,KAAK,EAAE,YAAY,CAAU;IACnC,QAAQ,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC,GAAG,mBAAmB,CAAC,GAAG,EAAE,QAAQ,CAAU;IAC/E,iBAAiB,EAAE,CACjB,QAAgB,EAChB,MAAmC,EACnC,EAAE,CAAC;QACH,GAAG,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACzC,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,QAAQ;QACf,MAAM,CAAC,eAAe,IAAI,EAAE;QAC5B,MAAM,CAAC,IAAI,IAAI,EAAE;KACT;IACV,KAAK,EAAE,CAAC,QAAgB,EAAE,aAAsB,EAAE,EAAE,CAAC,CAAC,GAAG,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,aAAa,CAAU;CAClI,CAAC","sourcesContent":["import { appId } from '@src/constants';\nimport { CourseTeamMemberQueryParams } from '@src/courseTeam/types';\n\nexport const courseTeamQueryKeys = {\n all: [appId, 'courseTeam'] as const,\n byCourse: (courseId: string) => [...courseTeamQueryKeys.all, courseId] as const,\n byCoursePaginated: (\n courseId: string,\n params: CourseTeamMemberQueryParams\n ) => [\n ...courseTeamQueryKeys.byCourse(courseId),\n params.page,\n params.pageSize,\n params.emailOrUsername || '',\n params.role || ''\n ] as const,\n roles: (courseId: string, editableRoles: boolean) => [...courseTeamQueryKeys.byCourse(courseId), 'roles', editableRoles] as const,\n};\n"]}
@@ -244,5 +244,15 @@ declare const messages: {
244
244
  defaultMessage: string;
245
245
  description: string;
246
246
  };
247
+ roleNotEditable: {
248
+ id: string;
249
+ defaultMessage: string;
250
+ description: string;
251
+ };
252
+ cannotRemoveOwnRole: {
253
+ id: string;
254
+ defaultMessage: string;
255
+ description: string;
256
+ };
247
257
  };
248
258
  export default messages;
@@ -244,6 +244,16 @@ const messages = defineMessages({
244
244
  id: 'instruct.courseTeam.viewStudioRoles',
245
245
  defaultMessage: 'View Studio Roles',
246
246
  description: 'Button label for viewing course team roles in Studio',
247
+ },
248
+ roleNotEditable: {
249
+ id: 'instruct.courseTeam.roleNotEditable',
250
+ defaultMessage: 'You do not have permission to change this role.',
251
+ description: 'Tooltip message displayed when a role cannot be edited by the user',
252
+ },
253
+ cannotRemoveOwnRole: {
254
+ id: 'instruct.courseTeam.cannotRemoveOwnRole',
255
+ defaultMessage: 'Admins cannot remove their own admin access.',
256
+ description: 'Tooltip message displayed when a user tries to remove their own admin role',
247
257
  }
248
258
  });
249
259
  export default messages;
@@ -1 +1 @@
1
- {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/courseTeam/messages.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n courseTeamTitle: {\n id: 'instruct.courseTeam.page.title',\n defaultMessage: 'Course Team Management',\n description: 'Title for the course team page',\n },\n addTeamMember: {\n id: 'instruct.courseTeam.addTeamMember',\n defaultMessage: 'Add Team Member',\n description: 'Button label for adding a team member',\n },\n membersTab: {\n id: 'instruct.courseTeam.membersTab',\n defaultMessage: 'Members',\n description: 'Tab title for course team members',\n },\n rolesTab: {\n id: 'instruct.courseTeam.rolesTab',\n defaultMessage: 'Roles',\n description: 'Tab title for course team roles',\n },\n username: {\n id: 'instruct.courseTeam.username',\n defaultMessage: 'Username',\n description: 'Column header for team member username',\n },\n email: {\n id: 'instruct.courseTeam.email',\n defaultMessage: 'Email',\n description: 'Column header for team member email',\n },\n role: {\n id: 'instruct.courseTeam.role',\n defaultMessage: 'Role',\n description: 'Column header for team member role',\n },\n actions: {\n id: 'instruct.courseTeam.actions',\n defaultMessage: 'Actions',\n description: 'Column header for team member actions',\n },\n edit: {\n id: 'instruct.courseTeam.edit',\n defaultMessage: 'Edit',\n description: 'Button label for editing a team member',\n },\n noTeamMembers: {\n id: 'instruct.courseTeam.noTeamMembers',\n defaultMessage: 'No team members found.',\n description: 'Message displayed when there are no team members',\n },\n allRoles: {\n id: 'instruct.courseTeam.allRoles',\n defaultMessage: 'All Roles',\n description: 'Option label for filtering by all roles',\n },\n staff: {\n id: 'instruct.courseTeam.roles.staff',\n defaultMessage: 'Staff',\n description: 'Role name for staff members',\n },\n staffDescription: {\n id: 'instruct.courseTeam.roles.staffDescription',\n defaultMessage: 'Course team members with the Staff role help you manage your course. Staff can enroll and unenroll learners, as well as modify their grades and access all course data. Staff also have access to your course in Studio and Insights. Any users not yet enrolled in the course will be automatically enrolled when added as Staff.',\n description: 'Description for staff role',\n },\n limitedStaff: {\n id: 'instruct.courseTeam.roles.limitedStaff',\n defaultMessage: 'Limited Staff',\n description: 'Role name for limited staff members',\n },\n limitedStaffDescription: {\n id: 'instruct.courseTeam.roles.limitedStaffDescription',\n defaultMessage: 'Course team members with the Limited Staff role help you manage your course. Limited Staff can enroll and unenroll learners, as well as modify their grades and access all course data. Limited Staff don\\'t have access to your course in Studio. Any users not yet enrolled in the course will be automatically enrolled when added as Limited Staff.',\n description: 'Description for limited staff role',\n },\n admin: {\n id: 'instruct.courseTeam.roles.admin',\n defaultMessage: 'Admin',\n description: 'Role name for admin members',\n },\n adminDescription: {\n id: 'instruct.courseTeam.roles.adminDescription',\n defaultMessage: 'Course team members with the Admin role help you manage your course. They can do all of the tasks that Staff can do, and can also add and remove the Staff and Admin roles, discussion moderation roles, and the beta tester role to manage course team membership. Any users not yet enrolled in the course will be automatically enrolled when added as Admin.',\n description: 'Description for admin role',\n },\n beta: {\n id: 'instruct.courseTeam.roles.beta',\n defaultMessage: 'Beta Testers',\n description: 'Role name for beta tester members',\n },\n betaDescription: {\n id: 'instruct.courseTeam.roles.betaDescription',\n defaultMessage: 'Beta Testers can see course content before other learners. They can make sure that the content works, but have no additional privileges. Any users not yet enrolled in the course will be automatically enrolled when added as Beta Tester.',\n description: 'Description for beta tester role',\n },\n courseDataResearchers: {\n id: 'instruct.courseTeam.roles.courseDataResearchers',\n defaultMessage: 'Course Data Researchers',\n description: 'Role name for course data researcher members',\n },\n courseDataResearchersDescription: {\n id: 'instruct.courseTeam.roles.courseDataResearchersDescription',\n defaultMessage: 'Course Data Researchers can access the data download tab. Any users not yet enrolled in the course will be automatically enrolled when added as Course Data Researcher.',\n description: 'Description for course data researcher role',\n },\n discussionAdmin: {\n id: 'instruct.courseTeam.roles.discussionAdmin',\n defaultMessage: 'Discussion Admin',\n description: 'Role name for discussion admin members',\n },\n discussionAdminDescription: {\n id: 'instruct.courseTeam.roles.discussionAdminDescription',\n defaultMessage: 'Discussion Admins can edit or delete any post, clear misuse flags, close and re-open threads, endorse responses, and see posts from all groups. Their posts are marked as \\'staff\\'. They can also add and remove the discussion moderation roles to manage course team membership. Any users not yet enrolled in the course will be automatically enrolled when added as Discussion Admin.',\n description: 'Description for discussion admin role',\n },\n discussionModerator: {\n id: 'instruct.courseTeam.roles.discussionModerator',\n defaultMessage: 'Discussion Moderator',\n description: 'Role name for discussion moderator members',\n },\n discussionModeratorDescription: {\n id: 'instruct.courseTeam.roles.discussionModeratorDescription',\n defaultMessage: 'Discussion Moderators can edit or delete any post, clear misuse flags, close and re-open threads, endorse responses, and see posts from all groups. Their posts are marked as \\'staff\\'. They cannot manage course team membership by adding or removing discussion moderation roles. Any users not yet enrolled in the course will be automatically enrolled when added as Discussion Moderator.',\n description: 'Description for discussion moderator role',\n },\n groupCommunityTA: {\n id: 'instruct.courseTeam.roles.groupCommunityTA',\n defaultMessage: 'Group Community TA',\n description: 'Role name for group community TA members',\n },\n groupCommunityTADescription: {\n id: 'instruct.courseTeam.roles.groupCommunityTADescription',\n defaultMessage: 'Group Community TAs are members of the community who help course teams moderate discussions. Group Community TAs see only posts by learners in their assigned group. They can edit or delete posts, clear flags, close and re-open threads, and endorse responses, but only for posts by learners in their group. Their posts are marked as \\'Community TA\\'. Any users not yet enrolled in the course will be automatically enrolled when added as Group Community TA.',\n description: 'Description for group community TA role',\n },\n communityTA: {\n id: 'instruct.courseTeam.roles.communityTA',\n defaultMessage: 'Community TA',\n description: 'Role name for community TA members',\n },\n communityTADescription: {\n id: 'instruct.courseTeam.roles.communityTADescription',\n defaultMessage: 'Community TAs are members of the community who help course teams moderate discussions. They can see posts by learners in their assigned cohort or enrollment track, and can edit or delete posts, clear flags, close or re-open threads, and endorse responses. Their posts are marked as \\'Community TA\\'. Any users not yet enrolled in the course will be automatically enrolled when added as Community TA.',\n description: 'Description for community TA role',\n },\n ccxCoach: {\n id: 'instruct.courseTeam.roles.ccxCoach',\n defaultMessage: 'CCX Coach',\n description: 'Role name for CCX coach members',\n },\n ccxCoachDescription: {\n id: 'instruct.courseTeam.roles.ccxCoachDescription',\n defaultMessage: 'CCX Coaches are able to create their own Custom Courses based on this course, which they can use to provide personalized instruction to their own students based in this course material.',\n description: 'Description for CCX coach role',\n },\n addNewTeamMember: {\n id: 'instruct.courseTeam.addNewTeamMember',\n defaultMessage: 'Add New Team Member',\n description: 'Title for add new team member form',\n },\n addNewTeamMemberDescription: {\n id: 'instruct.courseTeam.addNewTeamMemberDescription',\n defaultMessage: 'Add new members to {courseName}’s Course team and assign them a role to define their permissions.',\n description: 'Description for add new team member form',\n },\n addUsersLabel: {\n id: 'instruct.courseTeam.addUsersLabel',\n defaultMessage: 'Add users by username or email',\n description: 'Label for input to add users to course team',\n },\n usersPlaceholder: {\n id: 'instruct.courseTeam.usersPlaceholder',\n defaultMessage: 'Enter one or more email addresses or usernames',\n description: 'Placeholder for input to add users to course team',\n },\n roleLabel: {\n id: 'instruct.courseTeam.roleLabel',\n defaultMessage: 'Role',\n description: 'Label for role selection when adding users to course team',\n },\n rolePlaceholder: {\n id: 'instruct.courseTeam.rolePlaceholder',\n defaultMessage: 'Select Role',\n description: 'Placeholder for role selection when adding users to course team',\n },\n cancelButton: {\n id: 'instruct.courseTeam.cancelButton',\n defaultMessage: 'Cancel',\n description: 'Label for cancel button when adding users to course team',\n },\n saveButton: {\n id: 'instruct.courseTeam.saveButton',\n defaultMessage: 'Save',\n description: 'Label for save button when adding users to course team',\n },\n addTeamMemberError: {\n id: 'instruct.courseTeam.addTeamMemberError',\n defaultMessage: 'Could not find a user with username or email address “{username}”',\n description: 'Error message displayed when adding a team member fails',\n },\n closeButton: {\n id: 'instruct.courseTeam.closeButton',\n defaultMessage: 'Close',\n description: 'Label for close button in error modal when adding a team member fails',\n },\n failedToAddTeamMembers: {\n id: 'instruct.courseTeam.failedToAddTeamMembers',\n defaultMessage: 'The following usernames and/or email addresses are invalid. All other roles have been added to the team members.',\n description: 'Error message displayed when some team members could not be added',\n },\n unknownLearner: {\n id: 'instruct.courseTeam.unknownLearner',\n defaultMessage: 'Unknown learner: {learner}',\n description: 'Displayed when a learner does not have a full name or username available',\n },\n editTeamTitle: {\n id: 'instruct.courseTeam.editTeamTitle',\n defaultMessage: 'Edit {username} Roles',\n description: 'Title for edit team member modal',\n },\n editInstructions: {\n id: 'instruct.courseTeam.editInstructions',\n defaultMessage: 'Uncheck to remove role from {username}',\n description: 'Instructions for editing a team member',\n },\n addRole: {\n id: 'instruct.courseTeam.addRole',\n defaultMessage: 'Add role',\n description: 'Label for adding a role to a team member',\n },\n removeTeamMemberError: {\n id: 'instruct.courseTeam.removeTeamMemberError',\n defaultMessage: 'Failed to remove one or more roles from {username}.',\n description: 'Error message displayed when removing a team member fails',\n },\n addRoleError: {\n id: 'instruct.courseTeam.addRoleError',\n defaultMessage: 'Failed to add role to {username}.',\n description: 'Error message displayed when adding a role to a team member fails',\n },\n viewStudioRoles: {\n id: 'instruct.courseTeam.viewStudioRoles',\n defaultMessage: 'View Studio Roles',\n description: 'Button label for viewing course team roles in Studio',\n }\n});\n\nexport default messages;\n"]}
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/courseTeam/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,eAAe,EAAE;QACf,EAAE,EAAE,gCAAgC;QACpC,cAAc,EAAE,wBAAwB;QACxC,WAAW,EAAE,gCAAgC;KAC9C;IACD,aAAa,EAAE;QACb,EAAE,EAAE,mCAAmC;QACvC,cAAc,EAAE,iBAAiB;QACjC,WAAW,EAAE,uCAAuC;KACrD;IACD,UAAU,EAAE;QACV,EAAE,EAAE,gCAAgC;QACpC,cAAc,EAAE,SAAS;QACzB,WAAW,EAAE,mCAAmC;KACjD;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,8BAA8B;QAClC,cAAc,EAAE,OAAO;QACvB,WAAW,EAAE,iCAAiC;KAC/C;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,8BAA8B;QAClC,cAAc,EAAE,UAAU;QAC1B,WAAW,EAAE,wCAAwC;KACtD;IACD,KAAK,EAAE;QACL,EAAE,EAAE,2BAA2B;QAC/B,cAAc,EAAE,OAAO;QACvB,WAAW,EAAE,qCAAqC;KACnD;IACD,IAAI,EAAE;QACJ,EAAE,EAAE,0BAA0B;QAC9B,cAAc,EAAE,MAAM;QACtB,WAAW,EAAE,oCAAoC;KAClD;IACD,OAAO,EAAE;QACP,EAAE,EAAE,6BAA6B;QACjC,cAAc,EAAE,SAAS;QACzB,WAAW,EAAE,uCAAuC;KACrD;IACD,IAAI,EAAE;QACJ,EAAE,EAAE,0BAA0B;QAC9B,cAAc,EAAE,MAAM;QACtB,WAAW,EAAE,wCAAwC;KACtD;IACD,aAAa,EAAE;QACb,EAAE,EAAE,mCAAmC;QACvC,cAAc,EAAE,wBAAwB;QACxC,WAAW,EAAE,kDAAkD;KAChE;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,8BAA8B;QAClC,cAAc,EAAE,WAAW;QAC3B,WAAW,EAAE,yCAAyC;KACvD;IACD,KAAK,EAAE;QACL,EAAE,EAAE,iCAAiC;QACrC,cAAc,EAAE,OAAO;QACvB,WAAW,EAAE,6BAA6B;KAC3C;IACD,gBAAgB,EAAE;QAChB,EAAE,EAAE,4CAA4C;QAChD,cAAc,EAAE,oUAAoU;QACpV,WAAW,EAAE,4BAA4B;KAC1C;IACD,YAAY,EAAE;QACZ,EAAE,EAAE,wCAAwC;QAC5C,cAAc,EAAE,eAAe;QAC/B,WAAW,EAAE,qCAAqC;KACnD;IACD,uBAAuB,EAAE;QACvB,EAAE,EAAE,mDAAmD;QACvD,cAAc,EAAE,yVAAyV;QACzW,WAAW,EAAE,oCAAoC;KAClD;IACD,KAAK,EAAE;QACL,EAAE,EAAE,iCAAiC;QACrC,cAAc,EAAE,OAAO;QACvB,WAAW,EAAE,6BAA6B;KAC3C;IACD,gBAAgB,EAAE;QAChB,EAAE,EAAE,4CAA4C;QAChD,cAAc,EAAE,kWAAkW;QAClX,WAAW,EAAE,4BAA4B;KAC1C;IACD,IAAI,EAAE;QACJ,EAAE,EAAE,gCAAgC;QACpC,cAAc,EAAE,cAAc;QAC9B,WAAW,EAAE,mCAAmC;KACjD;IACD,eAAe,EAAE;QACf,EAAE,EAAE,2CAA2C;QAC/C,cAAc,EAAE,6OAA6O;QAC7P,WAAW,EAAE,kCAAkC;KAChD;IACD,qBAAqB,EAAE;QACrB,EAAE,EAAE,iDAAiD;QACrD,cAAc,EAAE,yBAAyB;QACzC,WAAW,EAAE,8CAA8C;KAC5D;IACD,gCAAgC,EAAE;QAChC,EAAE,EAAE,4DAA4D;QAChE,cAAc,EAAE,yKAAyK;QACzL,WAAW,EAAE,6CAA6C;KAC3D;IACD,eAAe,EAAE;QACf,EAAE,EAAE,2CAA2C;QAC/C,cAAc,EAAE,kBAAkB;QAClC,WAAW,EAAE,wCAAwC;KACtD;IACD,0BAA0B,EAAE;QAC1B,EAAE,EAAE,sDAAsD;QAC1D,cAAc,EAAE,6XAA6X;QAC7Y,WAAW,EAAE,uCAAuC;KACrD;IACD,mBAAmB,EAAE;QACnB,EAAE,EAAE,+CAA+C;QACnD,cAAc,EAAE,sBAAsB;QACtC,WAAW,EAAE,4CAA4C;KAC1D;IACD,8BAA8B,EAAE;QAC9B,EAAE,EAAE,0DAA0D;QAC9D,cAAc,EAAE,mYAAmY;QACnZ,WAAW,EAAE,2CAA2C;KACzD;IACD,gBAAgB,EAAE;QAChB,EAAE,EAAE,4CAA4C;QAChD,cAAc,EAAE,oBAAoB;QACpC,WAAW,EAAE,0CAA0C;KACxD;IACD,2BAA2B,EAAE;QAC3B,EAAE,EAAE,uDAAuD;QAC3D,cAAc,EAAE,ycAAyc;QACzd,WAAW,EAAE,yCAAyC;KACvD;IACD,WAAW,EAAE;QACX,EAAE,EAAE,uCAAuC;QAC3C,cAAc,EAAE,cAAc;QAC9B,WAAW,EAAE,oCAAoC;KAClD;IACD,sBAAsB,EAAE;QACtB,EAAE,EAAE,kDAAkD;QACtD,cAAc,EAAE,iZAAiZ;QACja,WAAW,EAAE,mCAAmC;KACjD;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,oCAAoC;QACxC,cAAc,EAAE,WAAW;QAC3B,WAAW,EAAE,iCAAiC;KAC/C;IACD,mBAAmB,EAAE;QACnB,EAAE,EAAE,+CAA+C;QACnD,cAAc,EAAE,2LAA2L;QAC3M,WAAW,EAAE,gCAAgC;KAC9C;IACD,gBAAgB,EAAE;QAChB,EAAE,EAAE,sCAAsC;QAC1C,cAAc,EAAE,qBAAqB;QACrC,WAAW,EAAE,oCAAoC;KAClD;IACD,2BAA2B,EAAE;QAC3B,EAAE,EAAE,iDAAiD;QACrD,cAAc,EAAE,mGAAmG;QACnH,WAAW,EAAE,0CAA0C;KACxD;IACD,aAAa,EAAE;QACb,EAAE,EAAE,mCAAmC;QACvC,cAAc,EAAE,gCAAgC;QAChD,WAAW,EAAE,6CAA6C;KAC3D;IACD,gBAAgB,EAAE;QAChB,EAAE,EAAE,sCAAsC;QAC1C,cAAc,EAAE,gDAAgD;QAChE,WAAW,EAAE,mDAAmD;KACjE;IACD,SAAS,EAAE;QACT,EAAE,EAAE,+BAA+B;QACnC,cAAc,EAAE,MAAM;QACtB,WAAW,EAAE,2DAA2D;KACzE;IACD,eAAe,EAAE;QACf,EAAE,EAAE,qCAAqC;QACzC,cAAc,EAAE,aAAa;QAC7B,WAAW,EAAE,iEAAiE;KAC/E;IACD,YAAY,EAAE;QACZ,EAAE,EAAE,kCAAkC;QACtC,cAAc,EAAE,QAAQ;QACxB,WAAW,EAAE,0DAA0D;KACxE;IACD,UAAU,EAAE;QACV,EAAE,EAAE,gCAAgC;QACpC,cAAc,EAAE,MAAM;QACtB,WAAW,EAAE,wDAAwD;KACtE;IACD,kBAAkB,EAAE;QAClB,EAAE,EAAE,wCAAwC;QAC5C,cAAc,EAAE,mEAAmE;QACnF,WAAW,EAAE,yDAAyD;KACvE;IACD,WAAW,EAAE;QACX,EAAE,EAAE,iCAAiC;QACrC,cAAc,EAAE,OAAO;QACvB,WAAW,EAAE,uEAAuE;KACrF;IACD,sBAAsB,EAAE;QACtB,EAAE,EAAE,4CAA4C;QAChD,cAAc,EAAE,kHAAkH;QAClI,WAAW,EAAE,mEAAmE;KACjF;IACD,cAAc,EAAE;QACd,EAAE,EAAE,oCAAoC;QACxC,cAAc,EAAE,4BAA4B;QAC5C,WAAW,EAAE,0EAA0E;KACxF;IACD,aAAa,EAAE;QACb,EAAE,EAAE,mCAAmC;QACvC,cAAc,EAAE,uBAAuB;QACvC,WAAW,EAAE,kCAAkC;KAChD;IACD,gBAAgB,EAAE;QAChB,EAAE,EAAE,sCAAsC;QAC1C,cAAc,EAAE,wCAAwC;QACxD,WAAW,EAAE,wCAAwC;KACtD;IACD,OAAO,EAAE;QACP,EAAE,EAAE,6BAA6B;QACjC,cAAc,EAAE,UAAU;QAC1B,WAAW,EAAE,0CAA0C;KACxD;IACD,qBAAqB,EAAE;QACrB,EAAE,EAAE,2CAA2C;QAC/C,cAAc,EAAE,qDAAqD;QACrE,WAAW,EAAE,2DAA2D;KACzE;IACD,YAAY,EAAE;QACZ,EAAE,EAAE,kCAAkC;QACtC,cAAc,EAAE,mCAAmC;QACnD,WAAW,EAAE,mEAAmE;KACjF;IACD,eAAe,EAAE;QACf,EAAE,EAAE,qCAAqC;QACzC,cAAc,EAAE,mBAAmB;QACnC,WAAW,EAAE,sDAAsD;KACpE;IACD,eAAe,EAAE;QACf,EAAE,EAAE,qCAAqC;QACzC,cAAc,EAAE,iDAAiD;QACjE,WAAW,EAAE,oEAAoE;KAClF;IACD,mBAAmB,EAAE;QACnB,EAAE,EAAE,yCAAyC;QAC7C,cAAc,EAAE,8CAA8C;QAC9D,WAAW,EAAE,4EAA4E;KAC1F;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n courseTeamTitle: {\n id: 'instruct.courseTeam.page.title',\n defaultMessage: 'Course Team Management',\n description: 'Title for the course team page',\n },\n addTeamMember: {\n id: 'instruct.courseTeam.addTeamMember',\n defaultMessage: 'Add Team Member',\n description: 'Button label for adding a team member',\n },\n membersTab: {\n id: 'instruct.courseTeam.membersTab',\n defaultMessage: 'Members',\n description: 'Tab title for course team members',\n },\n rolesTab: {\n id: 'instruct.courseTeam.rolesTab',\n defaultMessage: 'Roles',\n description: 'Tab title for course team roles',\n },\n username: {\n id: 'instruct.courseTeam.username',\n defaultMessage: 'Username',\n description: 'Column header for team member username',\n },\n email: {\n id: 'instruct.courseTeam.email',\n defaultMessage: 'Email',\n description: 'Column header for team member email',\n },\n role: {\n id: 'instruct.courseTeam.role',\n defaultMessage: 'Role',\n description: 'Column header for team member role',\n },\n actions: {\n id: 'instruct.courseTeam.actions',\n defaultMessage: 'Actions',\n description: 'Column header for team member actions',\n },\n edit: {\n id: 'instruct.courseTeam.edit',\n defaultMessage: 'Edit',\n description: 'Button label for editing a team member',\n },\n noTeamMembers: {\n id: 'instruct.courseTeam.noTeamMembers',\n defaultMessage: 'No team members found.',\n description: 'Message displayed when there are no team members',\n },\n allRoles: {\n id: 'instruct.courseTeam.allRoles',\n defaultMessage: 'All Roles',\n description: 'Option label for filtering by all roles',\n },\n staff: {\n id: 'instruct.courseTeam.roles.staff',\n defaultMessage: 'Staff',\n description: 'Role name for staff members',\n },\n staffDescription: {\n id: 'instruct.courseTeam.roles.staffDescription',\n defaultMessage: 'Course team members with the Staff role help you manage your course. Staff can enroll and unenroll learners, as well as modify their grades and access all course data. Staff also have access to your course in Studio and Insights. Any users not yet enrolled in the course will be automatically enrolled when added as Staff.',\n description: 'Description for staff role',\n },\n limitedStaff: {\n id: 'instruct.courseTeam.roles.limitedStaff',\n defaultMessage: 'Limited Staff',\n description: 'Role name for limited staff members',\n },\n limitedStaffDescription: {\n id: 'instruct.courseTeam.roles.limitedStaffDescription',\n defaultMessage: 'Course team members with the Limited Staff role help you manage your course. Limited Staff can enroll and unenroll learners, as well as modify their grades and access all course data. Limited Staff don\\'t have access to your course in Studio. Any users not yet enrolled in the course will be automatically enrolled when added as Limited Staff.',\n description: 'Description for limited staff role',\n },\n admin: {\n id: 'instruct.courseTeam.roles.admin',\n defaultMessage: 'Admin',\n description: 'Role name for admin members',\n },\n adminDescription: {\n id: 'instruct.courseTeam.roles.adminDescription',\n defaultMessage: 'Course team members with the Admin role help you manage your course. They can do all of the tasks that Staff can do, and can also add and remove the Staff and Admin roles, discussion moderation roles, and the beta tester role to manage course team membership. Any users not yet enrolled in the course will be automatically enrolled when added as Admin.',\n description: 'Description for admin role',\n },\n beta: {\n id: 'instruct.courseTeam.roles.beta',\n defaultMessage: 'Beta Testers',\n description: 'Role name for beta tester members',\n },\n betaDescription: {\n id: 'instruct.courseTeam.roles.betaDescription',\n defaultMessage: 'Beta Testers can see course content before other learners. They can make sure that the content works, but have no additional privileges. Any users not yet enrolled in the course will be automatically enrolled when added as Beta Tester.',\n description: 'Description for beta tester role',\n },\n courseDataResearchers: {\n id: 'instruct.courseTeam.roles.courseDataResearchers',\n defaultMessage: 'Course Data Researchers',\n description: 'Role name for course data researcher members',\n },\n courseDataResearchersDescription: {\n id: 'instruct.courseTeam.roles.courseDataResearchersDescription',\n defaultMessage: 'Course Data Researchers can access the data download tab. Any users not yet enrolled in the course will be automatically enrolled when added as Course Data Researcher.',\n description: 'Description for course data researcher role',\n },\n discussionAdmin: {\n id: 'instruct.courseTeam.roles.discussionAdmin',\n defaultMessage: 'Discussion Admin',\n description: 'Role name for discussion admin members',\n },\n discussionAdminDescription: {\n id: 'instruct.courseTeam.roles.discussionAdminDescription',\n defaultMessage: 'Discussion Admins can edit or delete any post, clear misuse flags, close and re-open threads, endorse responses, and see posts from all groups. Their posts are marked as \\'staff\\'. They can also add and remove the discussion moderation roles to manage course team membership. Any users not yet enrolled in the course will be automatically enrolled when added as Discussion Admin.',\n description: 'Description for discussion admin role',\n },\n discussionModerator: {\n id: 'instruct.courseTeam.roles.discussionModerator',\n defaultMessage: 'Discussion Moderator',\n description: 'Role name for discussion moderator members',\n },\n discussionModeratorDescription: {\n id: 'instruct.courseTeam.roles.discussionModeratorDescription',\n defaultMessage: 'Discussion Moderators can edit or delete any post, clear misuse flags, close and re-open threads, endorse responses, and see posts from all groups. Their posts are marked as \\'staff\\'. They cannot manage course team membership by adding or removing discussion moderation roles. Any users not yet enrolled in the course will be automatically enrolled when added as Discussion Moderator.',\n description: 'Description for discussion moderator role',\n },\n groupCommunityTA: {\n id: 'instruct.courseTeam.roles.groupCommunityTA',\n defaultMessage: 'Group Community TA',\n description: 'Role name for group community TA members',\n },\n groupCommunityTADescription: {\n id: 'instruct.courseTeam.roles.groupCommunityTADescription',\n defaultMessage: 'Group Community TAs are members of the community who help course teams moderate discussions. Group Community TAs see only posts by learners in their assigned group. They can edit or delete posts, clear flags, close and re-open threads, and endorse responses, but only for posts by learners in their group. Their posts are marked as \\'Community TA\\'. Any users not yet enrolled in the course will be automatically enrolled when added as Group Community TA.',\n description: 'Description for group community TA role',\n },\n communityTA: {\n id: 'instruct.courseTeam.roles.communityTA',\n defaultMessage: 'Community TA',\n description: 'Role name for community TA members',\n },\n communityTADescription: {\n id: 'instruct.courseTeam.roles.communityTADescription',\n defaultMessage: 'Community TAs are members of the community who help course teams moderate discussions. They can see posts by learners in their assigned cohort or enrollment track, and can edit or delete posts, clear flags, close or re-open threads, and endorse responses. Their posts are marked as \\'Community TA\\'. Any users not yet enrolled in the course will be automatically enrolled when added as Community TA.',\n description: 'Description for community TA role',\n },\n ccxCoach: {\n id: 'instruct.courseTeam.roles.ccxCoach',\n defaultMessage: 'CCX Coach',\n description: 'Role name for CCX coach members',\n },\n ccxCoachDescription: {\n id: 'instruct.courseTeam.roles.ccxCoachDescription',\n defaultMessage: 'CCX Coaches are able to create their own Custom Courses based on this course, which they can use to provide personalized instruction to their own students based in this course material.',\n description: 'Description for CCX coach role',\n },\n addNewTeamMember: {\n id: 'instruct.courseTeam.addNewTeamMember',\n defaultMessage: 'Add New Team Member',\n description: 'Title for add new team member form',\n },\n addNewTeamMemberDescription: {\n id: 'instruct.courseTeam.addNewTeamMemberDescription',\n defaultMessage: 'Add new members to {courseName}’s Course team and assign them a role to define their permissions.',\n description: 'Description for add new team member form',\n },\n addUsersLabel: {\n id: 'instruct.courseTeam.addUsersLabel',\n defaultMessage: 'Add users by username or email',\n description: 'Label for input to add users to course team',\n },\n usersPlaceholder: {\n id: 'instruct.courseTeam.usersPlaceholder',\n defaultMessage: 'Enter one or more email addresses or usernames',\n description: 'Placeholder for input to add users to course team',\n },\n roleLabel: {\n id: 'instruct.courseTeam.roleLabel',\n defaultMessage: 'Role',\n description: 'Label for role selection when adding users to course team',\n },\n rolePlaceholder: {\n id: 'instruct.courseTeam.rolePlaceholder',\n defaultMessage: 'Select Role',\n description: 'Placeholder for role selection when adding users to course team',\n },\n cancelButton: {\n id: 'instruct.courseTeam.cancelButton',\n defaultMessage: 'Cancel',\n description: 'Label for cancel button when adding users to course team',\n },\n saveButton: {\n id: 'instruct.courseTeam.saveButton',\n defaultMessage: 'Save',\n description: 'Label for save button when adding users to course team',\n },\n addTeamMemberError: {\n id: 'instruct.courseTeam.addTeamMemberError',\n defaultMessage: 'Could not find a user with username or email address “{username}”',\n description: 'Error message displayed when adding a team member fails',\n },\n closeButton: {\n id: 'instruct.courseTeam.closeButton',\n defaultMessage: 'Close',\n description: 'Label for close button in error modal when adding a team member fails',\n },\n failedToAddTeamMembers: {\n id: 'instruct.courseTeam.failedToAddTeamMembers',\n defaultMessage: 'The following usernames and/or email addresses are invalid. All other roles have been added to the team members.',\n description: 'Error message displayed when some team members could not be added',\n },\n unknownLearner: {\n id: 'instruct.courseTeam.unknownLearner',\n defaultMessage: 'Unknown learner: {learner}',\n description: 'Displayed when a learner does not have a full name or username available',\n },\n editTeamTitle: {\n id: 'instruct.courseTeam.editTeamTitle',\n defaultMessage: 'Edit {username} Roles',\n description: 'Title for edit team member modal',\n },\n editInstructions: {\n id: 'instruct.courseTeam.editInstructions',\n defaultMessage: 'Uncheck to remove role from {username}',\n description: 'Instructions for editing a team member',\n },\n addRole: {\n id: 'instruct.courseTeam.addRole',\n defaultMessage: 'Add role',\n description: 'Label for adding a role to a team member',\n },\n removeTeamMemberError: {\n id: 'instruct.courseTeam.removeTeamMemberError',\n defaultMessage: 'Failed to remove one or more roles from {username}.',\n description: 'Error message displayed when removing a team member fails',\n },\n addRoleError: {\n id: 'instruct.courseTeam.addRoleError',\n defaultMessage: 'Failed to add role to {username}.',\n description: 'Error message displayed when adding a role to a team member fails',\n },\n viewStudioRoles: {\n id: 'instruct.courseTeam.viewStudioRoles',\n defaultMessage: 'View Studio Roles',\n description: 'Button label for viewing course team roles in Studio',\n },\n roleNotEditable: {\n id: 'instruct.courseTeam.roleNotEditable',\n defaultMessage: 'You do not have permission to change this role.',\n description: 'Tooltip message displayed when a role cannot be edited by the user',\n },\n cannotRemoveOwnRole: {\n id: 'instruct.courseTeam.cannotRemoveOwnRole',\n defaultMessage: 'Admins cannot remove their own admin access.',\n description: 'Tooltip message displayed when a user tries to remove their own admin role',\n }\n});\n\nexport default messages;\n"]}
@@ -27,8 +27,9 @@ const AddBetaTestersModal = ({ isOpen, onClose }) => {
27
27
  const identifier = inputValue.split(',').map(email => email.trim()).filter(email => email);
28
28
  addBetaTesters({ identifier, action: 'add', autoEnroll, emailStudents }, {
29
29
  onSuccess: (data) => {
30
- var _a;
30
+ var _a, _b;
31
31
  const failedUsernames = ((_a = data.results) === null || _a === void 0 ? void 0 : _a.filter(user => user.userDoesNotExist).map(user => user.identifier)) || [];
32
+ const inactiveUsernames = ((_b = data.results) === null || _b === void 0 ? void 0 : _b.filter(user => !user.isActive && user.isActive !== null && !user.userDoesNotExist).map(user => user.identifier)) || [];
32
33
  if (failedUsernames.length > 0) {
33
34
  addAlert({
34
35
  type: 'danger',
@@ -36,6 +37,13 @@ const AddBetaTestersModal = ({ isOpen, onClose }) => {
36
37
  extraContent: (failedUsernames.map((learner) => (_jsxs("p", { className: "mb-0", children: ["\u2022 ", intl.formatMessage(messages.unknownLearner, { learner })] }, learner))))
37
38
  });
38
39
  }
40
+ if (inactiveUsernames.length > 0) {
41
+ addAlert({
42
+ type: 'warning',
43
+ message: intl.formatMessage(messages.inactiveUsers),
44
+ extraContent: (inactiveUsernames.map((learner) => (_jsxs("p", { className: "mb-0", children: ["\u2022 ", intl.formatMessage(messages.inactiveLearner, { learner })] }, learner))))
45
+ });
46
+ }
39
47
  handleChange('');
40
48
  setAutoEnroll(true);
41
49
  setEmailStudents(true);
@@ -1 +1 @@
1
- {"version":3,"file":"AddBetaTestersModal.js","sourceRoot":"","sources":["../../../src/enrollments/components/AddBetaTestersModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { isAxiosError } from 'axios';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, FormControl, ModalDialog, Form } from '@openedx/paragon';\nimport { useUpdateBetaTesters } from '@src/enrollments/data/apiHook';\nimport messages from '@src/enrollments/messages';\nimport { useAlert } from '@src/providers/AlertProvider';\nimport { useDebouncedFilter } from '@src/hooks/useDebouncedFilter';\n\nexport interface AddBetaTestersModalProps {\n isOpen: boolean,\n onClose: () => void,\n}\n\nconst AddBetaTestersModal = ({\n isOpen,\n onClose\n}: AddBetaTestersModalProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [emails, setEmails] = useState('');\n const [autoEnroll, setAutoEnroll] = useState(true);\n const [emailStudents, setEmailStudents] = useState(true);\n const { mutate: addBetaTesters } = useUpdateBetaTesters(courseId);\n const { showModal, addAlert } = useAlert();\n const { inputValue, handleChange } = useDebouncedFilter({\n filterValue: emails,\n setFilter: setEmails,\n });\n\n const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n handleChange(e.target.value);\n };\n\n const handleSave = () => {\n const identifier = inputValue.split(',').map(email => email.trim()).filter(email => email);\n addBetaTesters({ identifier, action: 'add', autoEnroll, emailStudents }, {\n onSuccess: (data) => {\n const failedUsernames = data.results?.filter(user => user.userDoesNotExist).map(user => user.identifier) || [];\n if (failedUsernames.length > 0) {\n addAlert({\n type: 'danger',\n message: intl.formatMessage(messages.failedBetaTesters),\n extraContent: (\n failedUsernames.map((learner: string) => (\n <p key={learner} className=\"mb-0\">• {intl.formatMessage(messages.unknownLearner, { learner })}</p>\n ))\n )\n });\n }\n handleChange('');\n setAutoEnroll(true);\n setEmailStudents(true);\n onClose();\n },\n onError: (error) => {\n const notFound = isAxiosError(error) && error.response?.status === 404;\n const errorMessage = notFound\n ? intl.formatMessage(messages.enrollLearnerNotFoundError)\n : intl.formatMessage(messages.enrollLearnerError);\n showModal({\n message: errorMessage,\n variant: 'danger',\n confirmText: intl.formatMessage(messages.closeButton),\n });\n }\n });\n };\n\n return (\n <ModalDialog isOpen={isOpen} onClose={onClose} isOverflowVisible={false} title={intl.formatMessage(messages.addBetaTesters)}>\n <ModalDialog.Header className=\"border-light-700 border-bottom\">\n <h3 className=\"text-primary-500\">{intl.formatMessage(messages.addBetaTesters)}</h3>\n </ModalDialog.Header>\n <div className=\"position-relative overflow-auto\">\n <ModalDialog.Body className=\"py-4\">\n <p className=\"text-gray-700 x-small mb-2\">{intl.formatMessage(messages.addBetaTestersInstructions)}</p>\n <FormControl\n name=\"identifier\"\n as=\"textarea\"\n rows={4}\n placeholder={intl.formatMessage(messages.userIdentifierPlaceholder)}\n onChange={handleInputChange}\n value={inputValue}\n />\n <div className=\"d-flex mt-3 text-primary-500\">\n <Form.Checkbox\n controlClassName=\"border-primary-500\"\n checked={autoEnroll}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setAutoEnroll(e.target.checked)}\n >{intl.formatMessage(messages.autoEnrollCheckbox)}\n </Form.Checkbox>\n <Form.Checkbox\n controlClassName=\"border-primary-500\"\n className=\"ml-4\"\n checked={emailStudents}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setEmailStudents(e.target.checked)}\n >{intl.formatMessage(messages.notifyUsersCheckbox)}\n </Form.Checkbox>\n </div>\n </ModalDialog.Body>\n </div>\n <ModalDialog.Footer className=\"border-light-700 border-top\">\n <Button variant=\"tertiary\" onClick={onClose}>\n {intl.formatMessage(messages.cancelButton)}\n </Button>\n <Button className=\"ml-2\" variant=\"primary\" onClick={handleSave} disabled={inputValue.trim().length === 0}>\n {intl.formatMessage(messages.saveButton)}\n </Button>\n </ModalDialog.Footer>\n </ModalDialog>\n );\n};\n\nexport default AddBetaTestersModal;\n"]}
1
+ {"version":3,"file":"AddBetaTestersModal.js","sourceRoot":"","sources":["../../../src/enrollments/components/AddBetaTestersModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { isAxiosError } from 'axios';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, FormControl, ModalDialog, Form } from '@openedx/paragon';\nimport { useUpdateBetaTesters } from '@src/enrollments/data/apiHook';\nimport messages from '@src/enrollments/messages';\nimport { useAlert } from '@src/providers/AlertProvider';\nimport { useDebouncedFilter } from '@src/hooks/useDebouncedFilter';\n\nexport interface AddBetaTestersModalProps {\n isOpen: boolean,\n onClose: () => void,\n}\n\nconst AddBetaTestersModal = ({\n isOpen,\n onClose\n}: AddBetaTestersModalProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [emails, setEmails] = useState('');\n const [autoEnroll, setAutoEnroll] = useState(true);\n const [emailStudents, setEmailStudents] = useState(true);\n const { mutate: addBetaTesters } = useUpdateBetaTesters(courseId);\n const { showModal, addAlert } = useAlert();\n const { inputValue, handleChange } = useDebouncedFilter({\n filterValue: emails,\n setFilter: setEmails,\n });\n\n const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n handleChange(e.target.value);\n };\n\n const handleSave = () => {\n const identifier = inputValue.split(',').map(email => email.trim()).filter(email => email);\n addBetaTesters({ identifier, action: 'add', autoEnroll, emailStudents }, {\n onSuccess: (data) => {\n const failedUsernames = data.results?.filter(user => user.userDoesNotExist).map(user => user.identifier) || [];\n const inactiveUsernames = data.results?.filter(user => !user.isActive && user.isActive !== null && !user.userDoesNotExist).map(user => user.identifier) || [];\n if (failedUsernames.length > 0) {\n addAlert({\n type: 'danger',\n message: intl.formatMessage(messages.failedBetaTesters),\n extraContent: (\n failedUsernames.map((learner: string) => (\n <p key={learner} className=\"mb-0\">• {intl.formatMessage(messages.unknownLearner, { learner })}</p>\n ))\n )\n });\n }\n if (inactiveUsernames.length > 0) {\n addAlert({\n type: 'warning',\n message: intl.formatMessage(messages.inactiveUsers),\n extraContent: (\n inactiveUsernames.map((learner: string) => (\n <p key={learner} className=\"mb-0\">• {intl.formatMessage(messages.inactiveLearner, { learner })}</p>\n ))\n )\n });\n }\n handleChange('');\n setAutoEnroll(true);\n setEmailStudents(true);\n onClose();\n },\n onError: (error) => {\n const notFound = isAxiosError(error) && error.response?.status === 404;\n const errorMessage = notFound\n ? intl.formatMessage(messages.enrollLearnerNotFoundError)\n : intl.formatMessage(messages.enrollLearnerError);\n showModal({\n message: errorMessage,\n variant: 'danger',\n confirmText: intl.formatMessage(messages.closeButton),\n });\n }\n });\n };\n\n return (\n <ModalDialog isOpen={isOpen} onClose={onClose} isOverflowVisible={false} title={intl.formatMessage(messages.addBetaTesters)}>\n <ModalDialog.Header className=\"border-light-700 border-bottom\">\n <h3 className=\"text-primary-500\">{intl.formatMessage(messages.addBetaTesters)}</h3>\n </ModalDialog.Header>\n <div className=\"position-relative overflow-auto\">\n <ModalDialog.Body className=\"py-4\">\n <p className=\"text-gray-700 x-small mb-2\">{intl.formatMessage(messages.addBetaTestersInstructions)}</p>\n <FormControl\n name=\"identifier\"\n as=\"textarea\"\n rows={4}\n placeholder={intl.formatMessage(messages.userIdentifierPlaceholder)}\n onChange={handleInputChange}\n value={inputValue}\n />\n <div className=\"d-flex mt-3 text-primary-500\">\n <Form.Checkbox\n controlClassName=\"border-primary-500\"\n checked={autoEnroll}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setAutoEnroll(e.target.checked)}\n >{intl.formatMessage(messages.autoEnrollCheckbox)}\n </Form.Checkbox>\n <Form.Checkbox\n controlClassName=\"border-primary-500\"\n className=\"ml-4\"\n checked={emailStudents}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setEmailStudents(e.target.checked)}\n >{intl.formatMessage(messages.notifyUsersCheckbox)}\n </Form.Checkbox>\n </div>\n </ModalDialog.Body>\n </div>\n <ModalDialog.Footer className=\"border-light-700 border-top\">\n <Button variant=\"tertiary\" onClick={onClose}>\n {intl.formatMessage(messages.cancelButton)}\n </Button>\n <Button className=\"ml-2\" variant=\"primary\" onClick={handleSave} disabled={inputValue.trim().length === 0}>\n {intl.formatMessage(messages.saveButton)}\n </Button>\n </ModalDialog.Footer>\n </ModalDialog>\n );\n};\n\nexport default AddBetaTestersModal;\n"]}
@@ -204,6 +204,16 @@ declare const messages: {
204
204
  defaultMessage: string;
205
205
  description: string;
206
206
  };
207
+ inactiveUsers: {
208
+ id: string;
209
+ defaultMessage: string;
210
+ description: string;
211
+ };
212
+ inactiveLearner: {
213
+ id: string;
214
+ defaultMessage: string;
215
+ description: string;
216
+ };
207
217
  addBetaTesterError: {
208
218
  id: string;
209
219
  defaultMessage: string;
@@ -205,6 +205,16 @@ const messages = defineMessages({
205
205
  defaultMessage: 'The following usernames and/or email addresses are invalid. All other beta testers have been added.',
206
206
  description: 'Message displaying the learners that could not be added as beta testers',
207
207
  },
208
+ inactiveUsers: {
209
+ id: 'instruct.enrollments.modals.addBetaTesters.inactiveUsers',
210
+ defaultMessage: 'The following users are inactive. They have been added as beta testers, but may not have access to the course until their accounts are active.',
211
+ description: 'Message displaying the learners that are inactive when adding beta testers',
212
+ },
213
+ inactiveLearner: {
214
+ id: 'instruct.enrollments.inactiveLearner',
215
+ defaultMessage: 'Inactive learner: {learner}',
216
+ description: 'Displayed when a learner is inactive',
217
+ },
208
218
  addBetaTesterError: {
209
219
  id: 'instruct.enrollments.modals.addBetaTesters.addBetaTesterError',
210
220
  defaultMessage: 'Error adding users as beta testers.',
@@ -1 +1 @@
1
- {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/enrollments/messages.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n enrollmentsPageTitle: {\n id: 'instruct.enrollments.page.title',\n defaultMessage: 'Enrollment Management',\n description: 'Title for the enrollments page',\n },\n addBetaTesters: {\n id: 'instruct.enrollments.addBetaTesters',\n defaultMessage: 'Add Beta Testers',\n description: 'Button label for adding beta testers',\n },\n enrollLearners: {\n id: 'instruct.enrollments.enrollLearners',\n defaultMessage: 'Enroll Learners',\n description: 'Button label and modal title for enrolling learners',\n },\n checkEnrollmentStatus: {\n id: 'instruct.enrollments.checkEnrollmentStatus',\n defaultMessage: 'Check Enrollment Status',\n description: 'Check enrollment status modal title and alt for icon button',\n },\n username: {\n id: 'instruct.enrollments.username',\n defaultMessage: 'Username',\n description: 'Column header for username in enrollments list',\n },\n fullName: {\n id: 'instruct.enrollments.fullName',\n defaultMessage: 'Name',\n description: 'Column header for full name in enrollments list',\n },\n email: {\n id: 'instruct.enrollments.email',\n defaultMessage: 'Email',\n description: 'Column header for email in enrollments list',\n },\n track: {\n id: 'instruct.enrollments.track',\n defaultMessage: 'Track',\n description: 'Column header for track in enrollments list',\n },\n betaTester: {\n id: 'instruct.enrollments.betaTester',\n defaultMessage: 'Beta Tester',\n description: 'Column header for beta tester status in enrollments list',\n },\n actions: {\n id: 'instruct.enrollments.actions',\n defaultMessage: 'Actions',\n description: 'Column header for actions in enrollments list',\n },\n unenrollButton: {\n id: 'instruct.enrollments.unenrollButton',\n defaultMessage: 'Unenroll',\n description: 'Button label for unenrolling a learner',\n },\n trueLabel: {\n id: 'instruct.enrollments.trueLabel',\n defaultMessage: 'True',\n description: 'Label for true boolean value',\n },\n addLearnerInstructions: {\n id: 'instruct.enrollments.modals.checkEnrollmentStatus.addLearnerInstructions',\n defaultMessage: 'Enter email addresses and/or usernames separated by new lines or commas. You will not get notification for emails that bounce, so please double-check spelling.',\n description: 'Instructions for enroll learners to the course',\n },\n enrollmentStatusPlaceholder: {\n id: 'instruct.enrollments.modals.checkEnrollmentStatus.enrollmentStatusPlaceholder',\n defaultMessage: 'Learner email address or username',\n description: 'Placeholder text for enrolling learners textarea',\n },\n closeButton: {\n id: 'instruct.enrollments.modals.closeButton',\n defaultMessage: 'Close',\n description: 'Label for close button in modals',\n },\n searchPlaceholder: {\n id: 'instruct.enrollments.searchPlaceholder',\n defaultMessage: 'Search enrollments',\n description: 'Placeholder for the search input in enrollments list',\n },\n noEnrollments: {\n id: 'instruct.enrollments.noEnrollments',\n defaultMessage: 'No enrollments found',\n description: 'Message displayed when there are no enrollments to show',\n },\n changeBetaTesterStatus: {\n id: 'instruct.enrollments.changeBetaTesterStatus',\n defaultMessage: 'Change Beta Tester Status',\n description: 'Alt text for change beta tester status icon button',\n },\n grantBetaTester: {\n id: 'instruct.enrollments.grantBetaTester',\n defaultMessage: 'Grant Beta Tester Role',\n description: 'Menu option to grant beta tester status',\n },\n revokeBetaTester: {\n id: 'instruct.enrollments.revokeBetaTester',\n defaultMessage: 'Remove Beta Tester Role',\n description: 'Menu option to revoke beta tester status',\n },\n allEnrollees: {\n id: 'instruct.enrollments.allEnrollees',\n defaultMessage: 'All Enrollees',\n description: 'Option for showing all enrollees in beta tester filter',\n },\n betaTesters: {\n id: 'instruct.enrollments.betaTesters',\n defaultMessage: 'Beta Testers',\n description: 'Option for showing only beta testers in beta tester filter',\n },\n nonBetaTesters: {\n id: 'instruct.enrollments.nonBetaTesters',\n defaultMessage: 'Non-Beta Testers',\n description: 'Option for showing only non-beta testers in beta tester filter',\n },\n statusResponseMessage: {\n id: 'instruct.enrollments.modals.checkEnrollmentStatus.statusResponseMessage',\n defaultMessage: 'Enrollment status for {learnerIdentifier}: {status}',\n description: 'Message displaying the enrollment status for a learner',\n },\n userIdentifierPlaceholder: {\n id: 'instruct.enrollments.modals.enrollLearners.userIdentifierPlaceholder',\n defaultMessage: 'Email addresses / Usernames',\n description: 'Placeholder text for enrolling learners textarea',\n },\n enrollLearnerInstructions: {\n id: 'instruct.enrollments.modals.enrollLearners.enrollLearnerInstructions',\n defaultMessage: 'Enter email addresses and/or usernames separated by new lines or commas. You will not get notification for emails that bounce, so please double-check spelling.',\n description: 'Instructions for enrolling learners to the course',\n },\n unenrollLearners: {\n id: 'instruct.enrollments.modals.unenrollLearners',\n defaultMessage: 'Unenroll Learners',\n description: 'Title for unenroll learners modal',\n },\n unenrollLearnersConfirmation: {\n id: 'instruct.enrollments.modals.unenrollLearnersConfirmation',\n defaultMessage: 'Unenroll {name} from course?',\n description: 'Confirmation message for unenrolling learners',\n },\n unenrollLearnerTitle: {\n id: 'instruct.enrollments.modals.unenrollLearnerTitle',\n defaultMessage: 'Unenroll Learner?',\n description: 'Title for unenroll learner modal',\n },\n saveButton: {\n id: 'instruct.enrollments.modals.saveButton',\n defaultMessage: 'Save',\n description: 'Label for save button in modals',\n },\n cancelButton: {\n id: 'instruct.enrollments.modals.cancelButton',\n defaultMessage: 'Cancel',\n description: 'Label for cancel button in modals',\n },\n autoEnrollCheckbox: {\n id: 'instruct.enrollments.modals.autoEnrollCheckbox',\n defaultMessage: 'Auto Enroll',\n description: 'Label for auto enroll checkbox in enroll learners modal',\n },\n notifyUsersCheckbox: {\n id: 'instruct.enrollments.modals.notifyUsersCheckbox',\n defaultMessage: 'Notify Users by Email',\n description: 'Label for notify users by email checkbox in enroll learners modal',\n },\n enrollLearnerError: {\n id: 'instruct.enrollments.modals.enrollLearnerError',\n defaultMessage: 'An error occurred while enrolling learners. Please try again.',\n description: 'Error message displayed when enrolling learners fails',\n },\n unenrollLearnerError: {\n id: 'instruct.enrollments.modals.unenrollLearnerError',\n defaultMessage: 'An error occurred while unenrolling learner. Please try again.',\n description: 'Error message displayed when unenrolling learner fails',\n },\n enrollLearnerNotFoundError: {\n id: 'instruct.enrollments.modals.enrollLearnerNotFoundError',\n defaultMessage: 'One or more learners were not found. Please check the email addresses or usernames and try again.',\n description: 'Error message displayed when enrolling learners fails due to learner not found',\n },\n addBetaTestersInstructions: {\n id: 'instruct.enrollments.modals.addBetaTesters.addBetaTestersInstructions',\n defaultMessage: 'Enter email addresses and/or usernames separated by new lines or commas. Note: Users must have an activated My Open edX account before they can be enrolled as beta testers.',\n description: 'Instructions for adding beta testers to the course',\n },\n failedEnrollLearners: {\n id: 'instruct.enrollments.modals.enrollLearners.failedEnrollLearners',\n defaultMessage: 'The following usernames and/or email addresses are invalid. All other learners have been enrolled.',\n description: 'Message displaying the learners that could not be enrolled',\n },\n unknownLearner: {\n id: 'instruct.enrollments.unknownLearner',\n defaultMessage: 'Unknown learner: {learner}',\n description: 'Displayed when a learner does not have a full name or username available',\n },\n removeBetaTesterError: {\n id: 'instruct.enrollments.modals.removeBetaTesters.removeBetaTesterError',\n defaultMessage: 'Error removing user as beta tester.',\n description: 'Error message displayed when removing beta testers fails',\n },\n failedBetaTesters: {\n id: 'instruct.enrollments.modals.addBetaTesters.failedBetaTesters',\n defaultMessage: 'The following usernames and/or email addresses are invalid. All other beta testers have been added.',\n description: 'Message displaying the learners that could not be added as beta testers',\n },\n addBetaTesterError: {\n id: 'instruct.enrollments.modals.addBetaTesters.addBetaTesterError',\n defaultMessage: 'Error adding users as beta testers.',\n description: 'Error message displayed when adding beta testers fails',\n },\n removeBetaTesterTitle: {\n id: 'instruct.enrollments.modals.removeBetaTester',\n defaultMessage: 'Revoke access?',\n description: 'Title for remove beta tester modal',\n },\n removeBetaTesterDescription: {\n id: 'instruct.enrollments.modals.removeBetaTesterDescription',\n defaultMessage: 'Revoke Beta Tester access?',\n description: 'Description for remove beta tester modal',\n },\n revoke: {\n id: 'instruct.enrollments.revoke',\n defaultMessage: 'Revoke',\n description: 'Button label for revoking access',\n }\n});\n\nexport default messages;\n"]}
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/enrollments/messages.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n enrollmentsPageTitle: {\n id: 'instruct.enrollments.page.title',\n defaultMessage: 'Enrollment Management',\n description: 'Title for the enrollments page',\n },\n addBetaTesters: {\n id: 'instruct.enrollments.addBetaTesters',\n defaultMessage: 'Add Beta Testers',\n description: 'Button label for adding beta testers',\n },\n enrollLearners: {\n id: 'instruct.enrollments.enrollLearners',\n defaultMessage: 'Enroll Learners',\n description: 'Button label and modal title for enrolling learners',\n },\n checkEnrollmentStatus: {\n id: 'instruct.enrollments.checkEnrollmentStatus',\n defaultMessage: 'Check Enrollment Status',\n description: 'Check enrollment status modal title and alt for icon button',\n },\n username: {\n id: 'instruct.enrollments.username',\n defaultMessage: 'Username',\n description: 'Column header for username in enrollments list',\n },\n fullName: {\n id: 'instruct.enrollments.fullName',\n defaultMessage: 'Name',\n description: 'Column header for full name in enrollments list',\n },\n email: {\n id: 'instruct.enrollments.email',\n defaultMessage: 'Email',\n description: 'Column header for email in enrollments list',\n },\n track: {\n id: 'instruct.enrollments.track',\n defaultMessage: 'Track',\n description: 'Column header for track in enrollments list',\n },\n betaTester: {\n id: 'instruct.enrollments.betaTester',\n defaultMessage: 'Beta Tester',\n description: 'Column header for beta tester status in enrollments list',\n },\n actions: {\n id: 'instruct.enrollments.actions',\n defaultMessage: 'Actions',\n description: 'Column header for actions in enrollments list',\n },\n unenrollButton: {\n id: 'instruct.enrollments.unenrollButton',\n defaultMessage: 'Unenroll',\n description: 'Button label for unenrolling a learner',\n },\n trueLabel: {\n id: 'instruct.enrollments.trueLabel',\n defaultMessage: 'True',\n description: 'Label for true boolean value',\n },\n addLearnerInstructions: {\n id: 'instruct.enrollments.modals.checkEnrollmentStatus.addLearnerInstructions',\n defaultMessage: 'Enter email addresses and/or usernames separated by new lines or commas. You will not get notification for emails that bounce, so please double-check spelling.',\n description: 'Instructions for enroll learners to the course',\n },\n enrollmentStatusPlaceholder: {\n id: 'instruct.enrollments.modals.checkEnrollmentStatus.enrollmentStatusPlaceholder',\n defaultMessage: 'Learner email address or username',\n description: 'Placeholder text for enrolling learners textarea',\n },\n closeButton: {\n id: 'instruct.enrollments.modals.closeButton',\n defaultMessage: 'Close',\n description: 'Label for close button in modals',\n },\n searchPlaceholder: {\n id: 'instruct.enrollments.searchPlaceholder',\n defaultMessage: 'Search enrollments',\n description: 'Placeholder for the search input in enrollments list',\n },\n noEnrollments: {\n id: 'instruct.enrollments.noEnrollments',\n defaultMessage: 'No enrollments found',\n description: 'Message displayed when there are no enrollments to show',\n },\n changeBetaTesterStatus: {\n id: 'instruct.enrollments.changeBetaTesterStatus',\n defaultMessage: 'Change Beta Tester Status',\n description: 'Alt text for change beta tester status icon button',\n },\n grantBetaTester: {\n id: 'instruct.enrollments.grantBetaTester',\n defaultMessage: 'Grant Beta Tester Role',\n description: 'Menu option to grant beta tester status',\n },\n revokeBetaTester: {\n id: 'instruct.enrollments.revokeBetaTester',\n defaultMessage: 'Remove Beta Tester Role',\n description: 'Menu option to revoke beta tester status',\n },\n allEnrollees: {\n id: 'instruct.enrollments.allEnrollees',\n defaultMessage: 'All Enrollees',\n description: 'Option for showing all enrollees in beta tester filter',\n },\n betaTesters: {\n id: 'instruct.enrollments.betaTesters',\n defaultMessage: 'Beta Testers',\n description: 'Option for showing only beta testers in beta tester filter',\n },\n nonBetaTesters: {\n id: 'instruct.enrollments.nonBetaTesters',\n defaultMessage: 'Non-Beta Testers',\n description: 'Option for showing only non-beta testers in beta tester filter',\n },\n statusResponseMessage: {\n id: 'instruct.enrollments.modals.checkEnrollmentStatus.statusResponseMessage',\n defaultMessage: 'Enrollment status for {learnerIdentifier}: {status}',\n description: 'Message displaying the enrollment status for a learner',\n },\n userIdentifierPlaceholder: {\n id: 'instruct.enrollments.modals.enrollLearners.userIdentifierPlaceholder',\n defaultMessage: 'Email addresses / Usernames',\n description: 'Placeholder text for enrolling learners textarea',\n },\n enrollLearnerInstructions: {\n id: 'instruct.enrollments.modals.enrollLearners.enrollLearnerInstructions',\n defaultMessage: 'Enter email addresses and/or usernames separated by new lines or commas. You will not get notification for emails that bounce, so please double-check spelling.',\n description: 'Instructions for enrolling learners to the course',\n },\n unenrollLearners: {\n id: 'instruct.enrollments.modals.unenrollLearners',\n defaultMessage: 'Unenroll Learners',\n description: 'Title for unenroll learners modal',\n },\n unenrollLearnersConfirmation: {\n id: 'instruct.enrollments.modals.unenrollLearnersConfirmation',\n defaultMessage: 'Unenroll {name} from course?',\n description: 'Confirmation message for unenrolling learners',\n },\n unenrollLearnerTitle: {\n id: 'instruct.enrollments.modals.unenrollLearnerTitle',\n defaultMessage: 'Unenroll Learner?',\n description: 'Title for unenroll learner modal',\n },\n saveButton: {\n id: 'instruct.enrollments.modals.saveButton',\n defaultMessage: 'Save',\n description: 'Label for save button in modals',\n },\n cancelButton: {\n id: 'instruct.enrollments.modals.cancelButton',\n defaultMessage: 'Cancel',\n description: 'Label for cancel button in modals',\n },\n autoEnrollCheckbox: {\n id: 'instruct.enrollments.modals.autoEnrollCheckbox',\n defaultMessage: 'Auto Enroll',\n description: 'Label for auto enroll checkbox in enroll learners modal',\n },\n notifyUsersCheckbox: {\n id: 'instruct.enrollments.modals.notifyUsersCheckbox',\n defaultMessage: 'Notify Users by Email',\n description: 'Label for notify users by email checkbox in enroll learners modal',\n },\n enrollLearnerError: {\n id: 'instruct.enrollments.modals.enrollLearnerError',\n defaultMessage: 'An error occurred while enrolling learners. Please try again.',\n description: 'Error message displayed when enrolling learners fails',\n },\n unenrollLearnerError: {\n id: 'instruct.enrollments.modals.unenrollLearnerError',\n defaultMessage: 'An error occurred while unenrolling learner. Please try again.',\n description: 'Error message displayed when unenrolling learner fails',\n },\n enrollLearnerNotFoundError: {\n id: 'instruct.enrollments.modals.enrollLearnerNotFoundError',\n defaultMessage: 'One or more learners were not found. Please check the email addresses or usernames and try again.',\n description: 'Error message displayed when enrolling learners fails due to learner not found',\n },\n addBetaTestersInstructions: {\n id: 'instruct.enrollments.modals.addBetaTesters.addBetaTestersInstructions',\n defaultMessage: 'Enter email addresses and/or usernames separated by new lines or commas. Note: Users must have an activated My Open edX account before they can be enrolled as beta testers.',\n description: 'Instructions for adding beta testers to the course',\n },\n failedEnrollLearners: {\n id: 'instruct.enrollments.modals.enrollLearners.failedEnrollLearners',\n defaultMessage: 'The following usernames and/or email addresses are invalid. All other learners have been enrolled.',\n description: 'Message displaying the learners that could not be enrolled',\n },\n unknownLearner: {\n id: 'instruct.enrollments.unknownLearner',\n defaultMessage: 'Unknown learner: {learner}',\n description: 'Displayed when a learner does not have a full name or username available',\n },\n removeBetaTesterError: {\n id: 'instruct.enrollments.modals.removeBetaTesters.removeBetaTesterError',\n defaultMessage: 'Error removing user as beta tester.',\n description: 'Error message displayed when removing beta testers fails',\n },\n failedBetaTesters: {\n id: 'instruct.enrollments.modals.addBetaTesters.failedBetaTesters',\n defaultMessage: 'The following usernames and/or email addresses are invalid. All other beta testers have been added.',\n description: 'Message displaying the learners that could not be added as beta testers',\n },\n inactiveUsers: {\n id: 'instruct.enrollments.modals.addBetaTesters.inactiveUsers',\n defaultMessage: 'The following users are inactive. They have been added as beta testers, but may not have access to the course until their accounts are active.',\n description: 'Message displaying the learners that are inactive when adding beta testers',\n },\n inactiveLearner: {\n id: 'instruct.enrollments.inactiveLearner',\n defaultMessage: 'Inactive learner: {learner}',\n description: 'Displayed when a learner is inactive',\n },\n addBetaTesterError: {\n id: 'instruct.enrollments.modals.addBetaTesters.addBetaTesterError',\n defaultMessage: 'Error adding users as beta testers.',\n description: 'Error message displayed when adding beta testers fails',\n },\n removeBetaTesterTitle: {\n id: 'instruct.enrollments.modals.removeBetaTester',\n defaultMessage: 'Revoke access?',\n description: 'Title for remove beta tester modal',\n },\n removeBetaTesterDescription: {\n id: 'instruct.enrollments.modals.removeBetaTesterDescription',\n defaultMessage: 'Revoke Beta Tester access?',\n description: 'Description for remove beta tester modal',\n },\n revoke: {\n id: 'instruct.enrollments.revoke',\n defaultMessage: 'Revoke',\n description: 'Button label for revoking access',\n }\n});\n\nexport default messages;\n"]}
@@ -32,5 +32,6 @@ export interface UpdateBetaTestersResponse {
32
32
  results: {
33
33
  identifier: string;
34
34
  userDoesNotExist: boolean;
35
+ isActive: boolean | null;
35
36
  }[];
36
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/enrollments/types.ts"],"names":[],"mappings":"","sourcesContent":["import { Learner, PaginationParams } from '@src/types';\n\nexport interface EnrollmentStatusResponse {\n enrollmentStatus: string,\n}\n\nexport interface EnrolledLearner extends Learner {\n mode: string,\n isBetaTester: boolean,\n}\n\nexport interface EnrollmentsParams extends PaginationParams {\n emailOrUsername: string,\n isBetaTester: string,\n}\n\nexport interface UpdateEnrollmentsParams {\n identifier: string[],\n action: 'enroll' | 'unenroll',\n autoEnroll?: boolean,\n emailStudents?: boolean,\n}\n\nexport interface UpdateBetaTestersParams {\n identifier: string[],\n action: 'add' | 'remove',\n autoEnroll?: boolean,\n emailStudents?: boolean,\n}\n\nexport interface UpdateEnrollmentsResponse {\n results: {\n identifier: string,\n invalidIdentifier: boolean,\n }[],\n}\n\nexport interface UpdateBetaTestersResponse {\n results: {\n identifier: string,\n userDoesNotExist: boolean,\n }[],\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/enrollments/types.ts"],"names":[],"mappings":"","sourcesContent":["import { Learner, PaginationParams } from '@src/types';\n\nexport interface EnrollmentStatusResponse {\n enrollmentStatus: string,\n}\n\nexport interface EnrolledLearner extends Learner {\n mode: string,\n isBetaTester: boolean,\n}\n\nexport interface EnrollmentsParams extends PaginationParams {\n emailOrUsername: string,\n isBetaTester: string,\n}\n\nexport interface UpdateEnrollmentsParams {\n identifier: string[],\n action: 'enroll' | 'unenroll',\n autoEnroll?: boolean,\n emailStudents?: boolean,\n}\n\nexport interface UpdateBetaTestersParams {\n identifier: string[],\n action: 'add' | 'remove',\n autoEnroll?: boolean,\n emailStudents?: boolean,\n}\n\nexport interface UpdateEnrollmentsResponse {\n results: {\n identifier: string,\n invalidIdentifier: boolean,\n }[],\n}\n\nexport interface UpdateBetaTestersResponse {\n results: {\n identifier: string,\n userDoesNotExist: boolean,\n isActive: boolean | null,\n }[],\n}\n"]}
@@ -73,7 +73,7 @@ const GradingLearnerContent = ({ toolType, onShowTasks }) => {
73
73
  {
74
74
  title: intl.formatMessage(messages.deleteHistory),
75
75
  description: intl.formatMessage(messages.deleteHistoryDescription),
76
- customAction: (_jsxs("div", { className: "d-flex flex-column gap-3", children: [_jsx(Button, { disabled: !usernameOrEmail || !blockId, onClick: handleResetAttempts, children: intl.formatMessage(messages.resetAttemptsButtonLabel) }), _jsx(Button, { disabled: !usernameOrEmail || !blockId, onClick: handleDeleteHistory, children: intl.formatMessage(messages.deleteHistoryButtonLabel) })] })),
76
+ customAction: (_jsx("div", { className: "d-flex flex-column gap-3", children: _jsx(Button, { disabled: !usernameOrEmail || !blockId, onClick: handleDeleteHistory, children: intl.formatMessage(messages.deleteHistoryButtonLabel) }) })),
77
77
  },
78
78
  {
79
79
  title: intl.formatMessage(messages.taskStatus),
@@ -1 +1 @@
1
- {"version":3,"file":"GradingLearnerContent.js","sourceRoot":"","sources":["../../../src/grading/components/GradingLearnerContent.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useParams } from 'react-router-dom';\nimport { useEffect, useState, useRef } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, FormControl } from '@openedx/paragon';\nimport ActionCard, { ActionCardProps } from '@src/components/ActionCard';\nimport SpecifyLearnerField from '@src/components/SpecifyLearnerField';\nimport SpecifyProblemField from '@src/components/SpecifyProblemField';\nimport { useChangeScore, useDeleteHistory, useRescoreSubmission, useResetAttempts } from '@src/grading/data/apiHook';\nimport messages from '@src/grading/messages';\nimport { GradingToolsType } from '@src/grading/types';\nimport { usePendingTasks } from '@src/data/apiHook';\n\ninterface GradingLearnerContentProps {\n toolType: GradingToolsType,\n onShowTasks: () => void,\n}\n\nconst GradingLearnerContent = ({ toolType, onShowTasks }: GradingLearnerContentProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [usernameOrEmail, setUsernameOrEmail] = useState('');\n const [blockId, setBlockId] = useState('');\n const [score, setScore] = useState('');\n const learnerFieldRef = useRef<{ reset: () => void }>(null);\n const problemFieldRef = useRef<{ reset: () => void }>(null);\n\n const { mutate: resetAttempts } = useResetAttempts(courseId);\n const { mutate: deleteHistory } = useDeleteHistory(courseId);\n const { mutate: changeScore } = useChangeScore(courseId);\n const { mutate: rescoreSubmission } = useRescoreSubmission(courseId);\n const { refetch: refetchTasks } = usePendingTasks(courseId);\n\n const handleResetAttempts = (): void => {\n resetAttempts({ learner: usernameOrEmail, problem: blockId });\n };\n\n const handleRescoreSubmission = (onlyIfHigher = false): void => {\n rescoreSubmission({ learner: usernameOrEmail, problem: blockId, onlyIfHigher });\n };\n\n const handleDeleteHistory = (): void => {\n deleteHistory({ learner: usernameOrEmail, problem: blockId });\n };\n\n const handleOverrideScore = (): void => {\n changeScore({ learner: usernameOrEmail, problem: blockId, newScore: Number(score) });\n };\n\n const handleScoreChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n const value = e.target.value;\n const numericRegex = /^-?\\d*\\.?\\d*$/;\n\n if (numericRegex.test(value) || value === '') {\n setScore(value);\n }\n };\n\n const handleTaskStatusClick = (): void => {\n refetchTasks();\n onShowTasks();\n };\n\n useEffect(() => {\n setUsernameOrEmail('');\n setBlockId('');\n setScore('');\n learnerFieldRef.current?.reset();\n problemFieldRef.current?.reset();\n }, [toolType]);\n\n const singleLearnerActionRows: ActionCardProps[] = [\n {\n title: intl.formatMessage(messages.resetAttempts),\n description: intl.formatMessage(messages.resetAttemptsDescription),\n customAction: (\n <Button disabled={!usernameOrEmail || !blockId} onClick={handleResetAttempts}>\n {intl.formatMessage(messages.resetAttemptsButtonLabel)}\n </Button>\n )\n },\n {\n title: intl.formatMessage(messages.rescoreSubmission),\n description: intl.formatMessage(messages.rescoreSubmissionDescription),\n customAction: (\n <div className=\"d-flex flex-column gap-3\">\n <Button disabled={!usernameOrEmail || !blockId} onClick={() => handleRescoreSubmission()}>{intl.formatMessage(messages.rescoreSubmissionButtonLabel)}</Button>\n <Button disabled={!usernameOrEmail || !blockId} onClick={() => handleRescoreSubmission(true)}>{intl.formatMessage(messages.rescoreIfImprovesScoreButtonLabel)}</Button>\n </div>\n ),\n },\n {\n title: intl.formatMessage(messages.overrideScore),\n description: intl.formatMessage(messages.overrideScoreDescription),\n buttonLabel: intl.formatMessage(messages.overrideScoreButtonLabel),\n customAction: (\n <div className=\"d-flex align-items-center gap-2\">\n <FormControl\n name={intl.formatMessage(messages.overrideScorePlaceholder)}\n type=\"number\"\n placeholder={intl.formatMessage(messages.overrideScorePlaceholder)}\n value={score}\n onChange={handleScoreChange}\n />\n <Button disabled={!usernameOrEmail || !blockId || !score} onClick={handleOverrideScore}>{intl.formatMessage(messages.overrideScoreButtonLabel)}</Button>\n </div>\n )\n },\n {\n title: intl.formatMessage(messages.deleteHistory),\n description: intl.formatMessage(messages.deleteHistoryDescription),\n customAction: (\n <div className=\"d-flex flex-column gap-3\">\n <Button disabled={!usernameOrEmail || !blockId} onClick={handleResetAttempts}>{intl.formatMessage(messages.resetAttemptsButtonLabel)}</Button>\n <Button disabled={!usernameOrEmail || !blockId} onClick={handleDeleteHistory}>{intl.formatMessage(messages.deleteHistoryButtonLabel)}</Button>\n </div>\n ),\n },\n {\n title: intl.formatMessage(messages.taskStatus),\n description: intl.formatMessage(messages.taskStatusDescription),\n customAction: (\n <Button disabled={!usernameOrEmail || !blockId} onClick={handleTaskStatusClick}>\n {intl.formatMessage(messages.taskStatusButtonLabel)}\n </Button>\n )\n }\n ];\n\n const allLearnersActionRows = [\n {\n title: intl.formatMessage(messages.resetAttempts),\n description: intl.formatMessage(messages.resetAllLearnersAttemptsDescription),\n buttonLabel: intl.formatMessage(messages.resetAttemptsButtonLabel),\n customAction: (\n <Button disabled={!blockId} onClick={handleResetAttempts}>\n {intl.formatMessage(messages.resetAttemptsButtonLabel)}\n </Button>\n )\n },\n {\n title: intl.formatMessage(messages.rescoreSubmission),\n description: intl.formatMessage(messages.rescoreSubmissionAllLearnersDescription),\n customAction: (\n <div className=\"d-flex flex-column gap-3\">\n <Button disabled={!blockId} onClick={() => handleRescoreSubmission()}>{intl.formatMessage(messages.rescoreAllSubmissionButtonLabel)}</Button>\n <Button disabled={!blockId} onClick={() => handleRescoreSubmission(true)}>{intl.formatMessage(messages.rescoreIfImprovesScoreButtonLabel)}</Button>\n </div>\n ),\n },\n {\n title: intl.formatMessage(messages.taskStatus),\n description: intl.formatMessage(messages.taskStatusDescription),\n customAction: (\n <Button onClick={handleTaskStatusClick}>\n {intl.formatMessage(messages.taskStatusButtonLabel)}\n </Button>\n )\n }\n ];\n\n const rows = toolType === 'single' ? singleLearnerActionRows : allLearnersActionRows;\n\n const handleProblemChange = (location: string): void => {\n setBlockId(location);\n };\n\n const handleLearnerChange = (usernameOrEmail: string): void => {\n setUsernameOrEmail(usernameOrEmail);\n };\n\n return (\n <>\n <p className=\"x-small text-primary mt-3\">\n {\n toolType === 'single'\n ? intl.formatMessage(messages.descriptionSingleLearner)\n : intl.formatMessage(messages.descriptionAllLearners)\n }\n </p>\n <div className=\"d-flex justify-content-between gap-4\">\n {toolType === 'single' && (\n <div className=\"w-50\">\n <SpecifyLearnerField ref={learnerFieldRef} onClickSelect={handleLearnerChange} />\n </div>\n )}\n <div className=\"w-50\">\n <SpecifyProblemField\n ref={problemFieldRef}\n fieldLabel={intl.formatMessage(messages.specifyProblem)}\n buttonLabel={intl.formatMessage(messages.select)}\n disabled={!usernameOrEmail && toolType === 'single'}\n usernameOrEmail={usernameOrEmail}\n onClickSelect={handleProblemChange}\n />\n </div>\n </div>\n {\n rows.map(({ title, description, buttonLabel, customAction, onButtonClick }, index) => (\n <ActionCard key={title} buttonLabel={buttonLabel} description={description} title={title} hasBorderBottom={index !== rows.length - 1} customAction={customAction} onButtonClick={onButtonClick} />\n ))\n }\n </>\n );\n};\n\nexport default GradingLearnerContent;\n"]}
1
+ {"version":3,"file":"GradingLearnerContent.js","sourceRoot":"","sources":["../../../src/grading/components/GradingLearnerContent.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useParams } from 'react-router-dom';\nimport { useEffect, useState, useRef } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, FormControl } from '@openedx/paragon';\nimport ActionCard, { ActionCardProps } from '@src/components/ActionCard';\nimport SpecifyLearnerField from '@src/components/SpecifyLearnerField';\nimport SpecifyProblemField from '@src/components/SpecifyProblemField';\nimport { useChangeScore, useDeleteHistory, useRescoreSubmission, useResetAttempts } from '@src/grading/data/apiHook';\nimport messages from '@src/grading/messages';\nimport { GradingToolsType } from '@src/grading/types';\nimport { usePendingTasks } from '@src/data/apiHook';\n\ninterface GradingLearnerContentProps {\n toolType: GradingToolsType,\n onShowTasks: () => void,\n}\n\nconst GradingLearnerContent = ({ toolType, onShowTasks }: GradingLearnerContentProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [usernameOrEmail, setUsernameOrEmail] = useState('');\n const [blockId, setBlockId] = useState('');\n const [score, setScore] = useState('');\n const learnerFieldRef = useRef<{ reset: () => void }>(null);\n const problemFieldRef = useRef<{ reset: () => void }>(null);\n\n const { mutate: resetAttempts } = useResetAttempts(courseId);\n const { mutate: deleteHistory } = useDeleteHistory(courseId);\n const { mutate: changeScore } = useChangeScore(courseId);\n const { mutate: rescoreSubmission } = useRescoreSubmission(courseId);\n const { refetch: refetchTasks } = usePendingTasks(courseId);\n\n const handleResetAttempts = (): void => {\n resetAttempts({ learner: usernameOrEmail, problem: blockId });\n };\n\n const handleRescoreSubmission = (onlyIfHigher = false): void => {\n rescoreSubmission({ learner: usernameOrEmail, problem: blockId, onlyIfHigher });\n };\n\n const handleDeleteHistory = (): void => {\n deleteHistory({ learner: usernameOrEmail, problem: blockId });\n };\n\n const handleOverrideScore = (): void => {\n changeScore({ learner: usernameOrEmail, problem: blockId, newScore: Number(score) });\n };\n\n const handleScoreChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n const value = e.target.value;\n const numericRegex = /^-?\\d*\\.?\\d*$/;\n\n if (numericRegex.test(value) || value === '') {\n setScore(value);\n }\n };\n\n const handleTaskStatusClick = (): void => {\n refetchTasks();\n onShowTasks();\n };\n\n useEffect(() => {\n setUsernameOrEmail('');\n setBlockId('');\n setScore('');\n learnerFieldRef.current?.reset();\n problemFieldRef.current?.reset();\n }, [toolType]);\n\n const singleLearnerActionRows: ActionCardProps[] = [\n {\n title: intl.formatMessage(messages.resetAttempts),\n description: intl.formatMessage(messages.resetAttemptsDescription),\n customAction: (\n <Button disabled={!usernameOrEmail || !blockId} onClick={handleResetAttempts}>\n {intl.formatMessage(messages.resetAttemptsButtonLabel)}\n </Button>\n )\n },\n {\n title: intl.formatMessage(messages.rescoreSubmission),\n description: intl.formatMessage(messages.rescoreSubmissionDescription),\n customAction: (\n <div className=\"d-flex flex-column gap-3\">\n <Button disabled={!usernameOrEmail || !blockId} onClick={() => handleRescoreSubmission()}>{intl.formatMessage(messages.rescoreSubmissionButtonLabel)}</Button>\n <Button disabled={!usernameOrEmail || !blockId} onClick={() => handleRescoreSubmission(true)}>{intl.formatMessage(messages.rescoreIfImprovesScoreButtonLabel)}</Button>\n </div>\n ),\n },\n {\n title: intl.formatMessage(messages.overrideScore),\n description: intl.formatMessage(messages.overrideScoreDescription),\n buttonLabel: intl.formatMessage(messages.overrideScoreButtonLabel),\n customAction: (\n <div className=\"d-flex align-items-center gap-2\">\n <FormControl\n name={intl.formatMessage(messages.overrideScorePlaceholder)}\n type=\"number\"\n placeholder={intl.formatMessage(messages.overrideScorePlaceholder)}\n value={score}\n onChange={handleScoreChange}\n />\n <Button disabled={!usernameOrEmail || !blockId || !score} onClick={handleOverrideScore}>{intl.formatMessage(messages.overrideScoreButtonLabel)}</Button>\n </div>\n )\n },\n {\n title: intl.formatMessage(messages.deleteHistory),\n description: intl.formatMessage(messages.deleteHistoryDescription),\n customAction: (\n <div className=\"d-flex flex-column gap-3\">\n <Button disabled={!usernameOrEmail || !blockId} onClick={handleDeleteHistory}>{intl.formatMessage(messages.deleteHistoryButtonLabel)}</Button>\n </div>\n ),\n },\n {\n title: intl.formatMessage(messages.taskStatus),\n description: intl.formatMessage(messages.taskStatusDescription),\n customAction: (\n <Button disabled={!usernameOrEmail || !blockId} onClick={handleTaskStatusClick}>\n {intl.formatMessage(messages.taskStatusButtonLabel)}\n </Button>\n )\n }\n ];\n\n const allLearnersActionRows = [\n {\n title: intl.formatMessage(messages.resetAttempts),\n description: intl.formatMessage(messages.resetAllLearnersAttemptsDescription),\n buttonLabel: intl.formatMessage(messages.resetAttemptsButtonLabel),\n customAction: (\n <Button disabled={!blockId} onClick={handleResetAttempts}>\n {intl.formatMessage(messages.resetAttemptsButtonLabel)}\n </Button>\n )\n },\n {\n title: intl.formatMessage(messages.rescoreSubmission),\n description: intl.formatMessage(messages.rescoreSubmissionAllLearnersDescription),\n customAction: (\n <div className=\"d-flex flex-column gap-3\">\n <Button disabled={!blockId} onClick={() => handleRescoreSubmission()}>{intl.formatMessage(messages.rescoreAllSubmissionButtonLabel)}</Button>\n <Button disabled={!blockId} onClick={() => handleRescoreSubmission(true)}>{intl.formatMessage(messages.rescoreIfImprovesScoreButtonLabel)}</Button>\n </div>\n ),\n },\n {\n title: intl.formatMessage(messages.taskStatus),\n description: intl.formatMessage(messages.taskStatusDescription),\n customAction: (\n <Button onClick={handleTaskStatusClick}>\n {intl.formatMessage(messages.taskStatusButtonLabel)}\n </Button>\n )\n }\n ];\n\n const rows = toolType === 'single' ? singleLearnerActionRows : allLearnersActionRows;\n\n const handleProblemChange = (location: string): void => {\n setBlockId(location);\n };\n\n const handleLearnerChange = (usernameOrEmail: string): void => {\n setUsernameOrEmail(usernameOrEmail);\n };\n\n return (\n <>\n <p className=\"x-small text-primary mt-3\">\n {\n toolType === 'single'\n ? intl.formatMessage(messages.descriptionSingleLearner)\n : intl.formatMessage(messages.descriptionAllLearners)\n }\n </p>\n <div className=\"d-flex justify-content-between gap-4\">\n {toolType === 'single' && (\n <div className=\"w-50\">\n <SpecifyLearnerField ref={learnerFieldRef} onClickSelect={handleLearnerChange} />\n </div>\n )}\n <div className=\"w-50\">\n <SpecifyProblemField\n ref={problemFieldRef}\n fieldLabel={intl.formatMessage(messages.specifyProblem)}\n buttonLabel={intl.formatMessage(messages.select)}\n disabled={!usernameOrEmail && toolType === 'single'}\n usernameOrEmail={usernameOrEmail}\n onClickSelect={handleProblemChange}\n />\n </div>\n </div>\n {\n rows.map(({ title, description, buttonLabel, customAction, onButtonClick }, index) => (\n <ActionCard key={title} buttonLabel={buttonLabel} description={description} title={title} hasBorderBottom={index !== rows.length - 1} customAction={customAction} onButtonClick={onButtonClick} />\n ))\n }\n </>\n );\n};\n\nexport default GradingLearnerContent;\n"]}
package/dist/testUtils.js CHANGED
@@ -4,7 +4,7 @@ import { IntlProvider } from '@openedx/frontend-base';
4
4
  import { AlertProvider } from './providers/AlertProvider';
5
5
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
6
6
  const queryClient = new QueryClient();
7
- export const renderWithQueryClient = (ui) => renderWithIntl(_jsx(QueryClientProvider, { client: queryClient, children: ui }));
7
+ export const renderWithQueryClient = (ui) => renderWithAlertAndIntl(_jsx(QueryClientProvider, { client: queryClient, children: ui }));
8
8
  export const renderWithIntl = (component) => {
9
9
  return render(_jsx(IntlProvider, { locale: "en", messages: {}, children: component }));
10
10
  };
@@ -1 +1 @@
1
- {"version":3,"file":"testUtils.js","sourceRoot":"","sources":["../src/testUtils.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEzE,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;AAEtC,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,EAAsB,EAAE,EAAE,CAC9D,cAAc,CACZ,KAAC,mBAAmB,IAAC,MAAM,EAAE,WAAW,YACrC,EAAE,GACiB,CACvB,CAAC;AAEJ,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,SAAS,EAAE,EAAE;IAC1C,OAAO,MAAM,CAAC,KAAC,YAAY,IAAC,MAAM,EAAC,IAAI,EAAC,QAAQ,EAAE,EAAE,YAAI,SAAS,GAAiB,CAAC,CAAC;AACtF,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,SAAS,EAAE,EAAE;IAClD,OAAO,MAAM,CACX,KAAC,YAAY,IAAC,MAAM,EAAC,IAAI,EAAC,QAAQ,EAAE,EAAE,YACpC,KAAC,aAAa,cACX,SAAS,GACI,GACH,CAChB,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAY,SAAS,EAAE,SAAS,GAAG,KAAK,EAAE,EAAE,CAAC,CAAC;IAC5E,IAAI;IACJ,SAAS;IACT,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,CAAC,SAAS,IAAI,IAAI,KAAK,SAAS;IAC3C,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;IACzD,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM;IAC5C,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;CACX,CAAA,CAAC","sourcesContent":["import { render } from '@testing-library/react';\nimport { IntlProvider } from '@openedx/frontend-base';\nimport { AlertProvider } from './providers/AlertProvider';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\n\nconst queryClient = new QueryClient();\n\nexport const renderWithQueryClient = (ui: React.ReactElement) =>\n renderWithIntl(\n <QueryClientProvider client={queryClient}>\n {ui}\n </QueryClientProvider>\n );\n\nexport const renderWithIntl = (component) => {\n return render(<IntlProvider locale=\"en\" messages={{}}>{ component }</IntlProvider>);\n};\n\nexport const renderWithAlertAndIntl = (component) => {\n return render(\n <IntlProvider locale=\"en\" messages={{}}>\n <AlertProvider>\n {component}\n </AlertProvider>\n </IntlProvider>\n );\n};\n\nexport const createQueryMock = (data: any = undefined, isLoading = false) => ({\n data,\n isLoading,\n error: null,\n isError: false,\n isSuccess: !isLoading && data !== undefined,\n status: isLoading ? 'loading' : data ? 'success' : 'idle',\n fetchStatus: isLoading ? 'fetching' : 'idle',\n refetch: jest.fn(),\n} as any);\n"]}
1
+ {"version":3,"file":"testUtils.js","sourceRoot":"","sources":["../src/testUtils.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEzE,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;AAEtC,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,EAAsB,EAAE,EAAE,CAC9D,sBAAsB,CACpB,KAAC,mBAAmB,IAAC,MAAM,EAAE,WAAW,YACrC,EAAE,GACiB,CACvB,CAAC;AAEJ,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,SAAS,EAAE,EAAE;IAC1C,OAAO,MAAM,CAAC,KAAC,YAAY,IAAC,MAAM,EAAC,IAAI,EAAC,QAAQ,EAAE,EAAE,YAAI,SAAS,GAAiB,CAAC,CAAC;AACtF,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,SAAS,EAAE,EAAE;IAClD,OAAO,MAAM,CACX,KAAC,YAAY,IAAC,MAAM,EAAC,IAAI,EAAC,QAAQ,EAAE,EAAE,YACpC,KAAC,aAAa,cACX,SAAS,GACI,GACH,CAChB,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAY,SAAS,EAAE,SAAS,GAAG,KAAK,EAAE,EAAE,CAAC,CAAC;IAC5E,IAAI;IACJ,SAAS;IACT,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,CAAC,SAAS,IAAI,IAAI,KAAK,SAAS;IAC3C,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;IACzD,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM;IAC5C,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;CACX,CAAA,CAAC","sourcesContent":["import { render } from '@testing-library/react';\nimport { IntlProvider } from '@openedx/frontend-base';\nimport { AlertProvider } from './providers/AlertProvider';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\n\nconst queryClient = new QueryClient();\n\nexport const renderWithQueryClient = (ui: React.ReactElement) =>\n renderWithAlertAndIntl(\n <QueryClientProvider client={queryClient}>\n {ui}\n </QueryClientProvider>\n );\n\nexport const renderWithIntl = (component) => {\n return render(<IntlProvider locale=\"en\" messages={{}}>{ component }</IntlProvider>);\n};\n\nexport const renderWithAlertAndIntl = (component) => {\n return render(\n <IntlProvider locale=\"en\" messages={{}}>\n <AlertProvider>\n {component}\n </AlertProvider>\n </IntlProvider>\n );\n};\n\nexport const createQueryMock = (data: any = undefined, isLoading = false) => ({\n data,\n isLoading,\n error: null,\n isError: false,\n isSuccess: !isLoading && data !== undefined,\n status: isLoading ? 'loading' : data ? 'success' : 'idle',\n fetchStatus: isLoading ? 'fetching' : 'idle',\n refetch: jest.fn(),\n} as any);\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openedx/frontend-app-instructor-dashboard",
3
- "version": "1.0.0-alpha.30",
3
+ "version": "1.0.0-alpha.31",
4
4
  "description": "The Open edX Instructor Dashboard",
5
5
  "repository": {
6
6
  "type": "git",