@openedx/frontend-app-instructor-dashboard 1.0.0-alpha.10 → 1.0.0-alpha.11
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.
- package/dist/enrollments/EnrollmentsPage.js +21 -2
- package/dist/enrollments/EnrollmentsPage.js.map +1 -1
- package/dist/enrollments/components/AddBetaTestersModal.d.ts +6 -0
- package/dist/enrollments/components/AddBetaTestersModal.js +61 -0
- package/dist/enrollments/components/AddBetaTestersModal.js.map +1 -0
- package/dist/enrollments/components/EnrollLearnersModal.d.ts +1 -2
- package/dist/enrollments/components/EnrollLearnersModal.js +15 -6
- package/dist/enrollments/components/EnrollLearnersModal.js.map +1 -1
- package/dist/enrollments/components/EnrollmentsList.d.ts +2 -1
- package/dist/enrollments/components/EnrollmentsList.js +9 -10
- package/dist/enrollments/components/EnrollmentsList.js.map +1 -1
- package/dist/enrollments/components/UnenrollModal.d.ts +1 -2
- package/dist/enrollments/components/UnenrollModal.js +1 -2
- package/dist/enrollments/components/UnenrollModal.js.map +1 -1
- package/dist/enrollments/components/UpdateBetaTesterModal.d.ts +8 -0
- package/dist/enrollments/components/UpdateBetaTesterModal.js +52 -0
- package/dist/enrollments/components/UpdateBetaTesterModal.js.map +1 -0
- package/dist/enrollments/data/api.d.ts +3 -2
- package/dist/enrollments/data/api.js +7 -1
- package/dist/enrollments/data/api.js.map +1 -1
- package/dist/enrollments/data/apiHook.d.ts +3 -2
- package/dist/enrollments/data/apiHook.js +10 -1
- package/dist/enrollments/data/apiHook.js.map +1 -1
- package/dist/enrollments/messages.d.ts +55 -0
- package/dist/enrollments/messages.js +56 -1
- package/dist/enrollments/messages.js.map +1 -1
- package/dist/enrollments/types.d.ts +18 -0
- package/dist/enrollments/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,16 +4,22 @@ import { useIntl } from '@openedx/frontend-base';
|
|
|
4
4
|
import { ActionRow, Button, IconButton } from '@openedx/paragon';
|
|
5
5
|
import { MoreVert } from '@openedx/paragon/icons';
|
|
6
6
|
import messages from '../enrollments/messages';
|
|
7
|
+
import AddBetaTestersModal from '../enrollments/components/AddBetaTestersModal';
|
|
8
|
+
import EnrollLearnersModal from '../enrollments/components/EnrollLearnersModal';
|
|
7
9
|
import EnrollmentsList from '../enrollments/components/EnrollmentsList';
|
|
8
10
|
import EnrollmentStatusModal from '../enrollments/components/EnrollmentStatusModal';
|
|
9
11
|
import UnenrollModal from '../enrollments/components/UnenrollModal';
|
|
10
|
-
import
|
|
12
|
+
import { AlertOutlet, useAlert } from '../providers/AlertProvider';
|
|
13
|
+
import UpdateBetaTesterModal from './components/UpdateBetaTesterModal';
|
|
11
14
|
const EnrollmentsPage = () => {
|
|
12
15
|
const intl = useIntl();
|
|
13
16
|
const [isEnrollmentStatusModalOpen, setIsEnrollmentStatusModalOpen] = useState(false);
|
|
14
17
|
const [isEnrollLearnersModalOpen, setIsEnrollLearnersModalOpen] = useState(false);
|
|
18
|
+
const [isAddBetaTestersModalOpen, setIsAddBetaTestersModalOpen] = useState(false);
|
|
15
19
|
const [isUnenrollModalOpen, setIsUnenrollModalOpen] = useState(false);
|
|
20
|
+
const [isUpdateBetaTesterModalOpen, setIsUpdateBetaTesterModalOpen] = useState(false);
|
|
16
21
|
const [selectedLearner, setSelectedLearner] = useState(null);
|
|
22
|
+
const { clearAlerts } = useAlert();
|
|
17
23
|
const handleMoreButton = () => {
|
|
18
24
|
setIsEnrollmentStatusModalOpen(true);
|
|
19
25
|
};
|
|
@@ -30,11 +36,24 @@ const EnrollmentsPage = () => {
|
|
|
30
36
|
};
|
|
31
37
|
const handleEnrollLearners = () => {
|
|
32
38
|
setIsEnrollLearnersModalOpen(true);
|
|
39
|
+
clearAlerts();
|
|
33
40
|
};
|
|
34
41
|
const handleCloseEnrollLearnersModal = () => {
|
|
35
42
|
setIsEnrollLearnersModalOpen(false);
|
|
36
43
|
};
|
|
37
|
-
|
|
44
|
+
const handleAddBetaTesters = () => {
|
|
45
|
+
setIsAddBetaTestersModalOpen(true);
|
|
46
|
+
clearAlerts();
|
|
47
|
+
};
|
|
48
|
+
const handleBetaTesterChange = (learner) => {
|
|
49
|
+
setIsUpdateBetaTesterModalOpen(true);
|
|
50
|
+
setSelectedLearner(learner);
|
|
51
|
+
};
|
|
52
|
+
const handleCloseUpdateBetaTesterModal = () => {
|
|
53
|
+
setIsUpdateBetaTesterModalOpen(false);
|
|
54
|
+
setSelectedLearner(null);
|
|
55
|
+
};
|
|
56
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "d-flex justify-content-between align-items-center", children: [_jsx("h3", { className: "text-primary-700", children: intl.formatMessage(messages.enrollmentsPageTitle) }), _jsxs(ActionRow, { children: [_jsx(IconButton, { alt: intl.formatMessage(messages.checkEnrollmentStatus), className: "lead", iconAs: MoreVert, onClick: handleMoreButton }), _jsxs(Button, { variant: "outline-primary", onClick: handleAddBetaTesters, children: ["+ ", intl.formatMessage(messages.addBetaTesters)] }), _jsxs(Button, { onClick: handleEnrollLearners, children: ["+ ", intl.formatMessage(messages.enrollLearners)] })] })] }), _jsx(AlertOutlet, {}), _jsx(EnrollmentsList, { onUnenroll: handleUnenroll, onBetaTesterChange: handleBetaTesterChange }), _jsx(EnrollmentStatusModal, { isOpen: isEnrollmentStatusModalOpen, onClose: handleCloseEnrollmentStatusModal }), selectedLearner && _jsx(UnenrollModal, { isOpen: isUnenrollModalOpen, learner: selectedLearner, onClose: handleUnenrollModalClose }), _jsx(EnrollLearnersModal, { isOpen: isEnrollLearnersModalOpen, onClose: handleCloseEnrollLearnersModal }), _jsx(AddBetaTestersModal, { isOpen: isAddBetaTestersModalOpen, onClose: () => setIsAddBetaTestersModalOpen(false) }), selectedLearner && _jsx(UpdateBetaTesterModal, { isOpen: isUpdateBetaTesterModalOpen, learner: selectedLearner, onClose: handleCloseUpdateBetaTesterModal })] }));
|
|
38
57
|
};
|
|
39
58
|
export default EnrollmentsPage;
|
|
40
59
|
//# sourceMappingURL=EnrollmentsPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnrollmentsPage.js","sourceRoot":"","sources":["../../src/enrollments/EnrollmentsPage.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,QAAQ,MAAM,2BAA2B,CAAC;AACjD,OAAO,eAAe,MAAM,6CAA6C,CAAC;AAC1E,OAAO,qBAAqB,MAAM,mDAAmD,CAAC;AACtF,OAAO,aAAa,MAAM,2CAA2C,CAAC;
|
|
1
|
+
{"version":3,"file":"EnrollmentsPage.js","sourceRoot":"","sources":["../../src/enrollments/EnrollmentsPage.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport { ActionRow, Button, IconButton } from '@openedx/paragon';\nimport { MoreVert } from '@openedx/paragon/icons';\nimport messages from '@src/enrollments/messages';\nimport AddBetaTestersModal from '@src/enrollments/components/AddBetaTestersModal';\nimport EnrollLearnersModal from '@src/enrollments/components/EnrollLearnersModal';\nimport EnrollmentsList from '@src/enrollments/components/EnrollmentsList';\nimport EnrollmentStatusModal from '@src/enrollments/components/EnrollmentStatusModal';\nimport UnenrollModal from '@src/enrollments/components/UnenrollModal';\nimport { EnrolledLearner } from '@src/enrollments/types';\nimport { AlertOutlet, useAlert } from '@src/providers/AlertProvider';\nimport UpdateBetaTesterModal from './components/UpdateBetaTesterModal';\n\nconst EnrollmentsPage = () => {\n const intl = useIntl();\n const [isEnrollmentStatusModalOpen, setIsEnrollmentStatusModalOpen] = useState(false);\n const [isEnrollLearnersModalOpen, setIsEnrollLearnersModalOpen] = useState(false);\n const [isAddBetaTestersModalOpen, setIsAddBetaTestersModalOpen] = useState(false);\n const [isUnenrollModalOpen, setIsUnenrollModalOpen] = useState(false);\n const [isUpdateBetaTesterModalOpen, setIsUpdateBetaTesterModalOpen] = useState(false);\n const [selectedLearner, setSelectedLearner] = useState<EnrolledLearner | null>(null);\n const { clearAlerts } = useAlert();\n\n const handleMoreButton = () => {\n setIsEnrollmentStatusModalOpen(true);\n };\n\n const handleUnenroll = (learner: EnrolledLearner) => {\n setIsUnenrollModalOpen(true);\n setSelectedLearner(learner);\n };\n\n const handleUnenrollModalClose = () => {\n setIsUnenrollModalOpen(false);\n setSelectedLearner(null);\n };\n\n const handleCloseEnrollmentStatusModal = () => {\n setIsEnrollmentStatusModalOpen(false);\n };\n\n const handleEnrollLearners = () => {\n setIsEnrollLearnersModalOpen(true);\n clearAlerts();\n };\n\n const handleCloseEnrollLearnersModal = () => {\n setIsEnrollLearnersModalOpen(false);\n };\n\n const handleAddBetaTesters = () => {\n setIsAddBetaTestersModalOpen(true);\n clearAlerts();\n };\n\n const handleBetaTesterChange = (learner: EnrolledLearner) => {\n setIsUpdateBetaTesterModalOpen(true);\n setSelectedLearner(learner);\n };\n\n const handleCloseUpdateBetaTesterModal = () => {\n setIsUpdateBetaTesterModalOpen(false);\n setSelectedLearner(null);\n };\n\n return (\n <>\n <div className=\"d-flex justify-content-between align-items-center\">\n <h3 className=\"text-primary-700\">{intl.formatMessage(messages.enrollmentsPageTitle)}</h3>\n <ActionRow>\n <IconButton\n alt={intl.formatMessage(messages.checkEnrollmentStatus)}\n className=\"lead\"\n iconAs={MoreVert}\n onClick={handleMoreButton}\n />\n <Button variant=\"outline-primary\" onClick={handleAddBetaTesters}>+ {intl.formatMessage(messages.addBetaTesters)}</Button>\n <Button onClick={handleEnrollLearners}>+ {intl.formatMessage(messages.enrollLearners)}</Button>\n </ActionRow>\n </div>\n <AlertOutlet />\n <EnrollmentsList onUnenroll={handleUnenroll} onBetaTesterChange={handleBetaTesterChange} />\n <EnrollmentStatusModal isOpen={isEnrollmentStatusModalOpen} onClose={handleCloseEnrollmentStatusModal} />\n {selectedLearner && <UnenrollModal isOpen={isUnenrollModalOpen} learner={selectedLearner} onClose={handleUnenrollModalClose} />}\n <EnrollLearnersModal isOpen={isEnrollLearnersModalOpen} onClose={handleCloseEnrollLearnersModal} />\n <AddBetaTestersModal isOpen={isAddBetaTestersModalOpen} onClose={() => setIsAddBetaTestersModalOpen(false)} />\n {selectedLearner && <UpdateBetaTesterModal isOpen={isUpdateBetaTesterModalOpen} learner={selectedLearner} onClose={handleCloseUpdateBetaTesterModal} />}\n </>\n );\n};\n\nexport default EnrollmentsPage;\n"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { useParams } from 'react-router-dom';
|
|
4
|
+
import { isAxiosError } from 'axios';
|
|
5
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
6
|
+
import { Button, FormControl, ModalDialog, Form } from '@openedx/paragon';
|
|
7
|
+
import { useUpdateBetaTesters } from '../../enrollments/data/apiHook';
|
|
8
|
+
import messages from '../../enrollments/messages';
|
|
9
|
+
import { useAlert } from '../../providers/AlertProvider';
|
|
10
|
+
import { useDebouncedFilter } from '../../hooks/useDebouncedFilter';
|
|
11
|
+
const AddBetaTestersModal = ({ isOpen, onClose }) => {
|
|
12
|
+
const intl = useIntl();
|
|
13
|
+
const { courseId = '' } = useParams();
|
|
14
|
+
const [emails, setEmails] = useState('');
|
|
15
|
+
const [autoEnroll, setAutoEnroll] = useState(true);
|
|
16
|
+
const [emailStudents, setEmailStudents] = useState(true);
|
|
17
|
+
const { mutate: addBetaTesters } = useUpdateBetaTesters(courseId);
|
|
18
|
+
const { showModal, addAlert } = useAlert();
|
|
19
|
+
const { inputValue, handleChange } = useDebouncedFilter({
|
|
20
|
+
filterValue: emails,
|
|
21
|
+
setFilter: setEmails,
|
|
22
|
+
});
|
|
23
|
+
const handleInputChange = (e) => {
|
|
24
|
+
handleChange(e.target.value);
|
|
25
|
+
};
|
|
26
|
+
const handleSave = () => {
|
|
27
|
+
const identifier = inputValue.split(',').map(email => email.trim()).filter(email => email);
|
|
28
|
+
addBetaTesters({ identifier, action: 'add', autoEnroll, emailStudents }, {
|
|
29
|
+
onSuccess: (data) => {
|
|
30
|
+
var _a;
|
|
31
|
+
const failedUsernames = ((_a = data.results) === null || _a === void 0 ? void 0 : _a.filter(user => user.userDoesNotExist).map(user => user.identifier)) || [];
|
|
32
|
+
if (failedUsernames.length > 0) {
|
|
33
|
+
addAlert({
|
|
34
|
+
type: 'danger',
|
|
35
|
+
message: intl.formatMessage(messages.failedBetaTesters),
|
|
36
|
+
extraContent: (failedUsernames.map((learner) => (_jsxs("p", { className: "mb-0", children: ["\u2022 ", intl.formatMessage(messages.unknownLearner, { learner })] }, learner))))
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
handleChange('');
|
|
40
|
+
setAutoEnroll(true);
|
|
41
|
+
setEmailStudents(true);
|
|
42
|
+
onClose();
|
|
43
|
+
},
|
|
44
|
+
onError: (error) => {
|
|
45
|
+
var _a;
|
|
46
|
+
const notFound = isAxiosError(error) && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404;
|
|
47
|
+
const errorMessage = notFound
|
|
48
|
+
? intl.formatMessage(messages.enrollLearnerNotFoundError)
|
|
49
|
+
: intl.formatMessage(messages.enrollLearnerError);
|
|
50
|
+
showModal({
|
|
51
|
+
message: errorMessage,
|
|
52
|
+
variant: 'danger',
|
|
53
|
+
confirmText: intl.formatMessage(messages.closeButton),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
return (_jsxs(ModalDialog, { isOpen: isOpen, onClose: onClose, isOverflowVisible: false, title: intl.formatMessage(messages.addBetaTesters), children: [_jsx(ModalDialog.Header, { className: "border-light-700 border-bottom", children: _jsx("h3", { className: "text-primary-500", children: intl.formatMessage(messages.addBetaTesters) }) }), _jsx("div", { className: "position-relative overflow-auto", children: _jsxs(ModalDialog.Body, { className: "py-4", children: [_jsx("p", { className: "text-gray-700 x-small mb-2", children: intl.formatMessage(messages.addBetaTestersInstructions) }), _jsx(FormControl, { name: "identifier", as: "textarea", rows: 4, placeholder: intl.formatMessage(messages.userIdentifierPlaceholder), onChange: handleInputChange, value: inputValue }), _jsxs("div", { className: "d-flex mt-3 text-primary-500", children: [_jsx(Form.Checkbox, { controlClassName: "border-primary-500", checked: autoEnroll, onChange: (e) => setAutoEnroll(e.target.checked), children: intl.formatMessage(messages.autoEnrollCheckbox) }), _jsx(Form.Checkbox, { controlClassName: "border-primary-500", className: "ml-4", checked: emailStudents, onChange: (e) => setEmailStudents(e.target.checked), children: intl.formatMessage(messages.notifyUsersCheckbox) })] })] }) }), _jsxs(ModalDialog.Footer, { className: "border-light-700 border-top", children: [_jsx(Button, { variant: "tertiary", onClick: onClose, children: intl.formatMessage(messages.cancelButton) }), _jsx(Button, { className: "ml-2", variant: "primary", onClick: handleSave, disabled: inputValue.trim().length === 0, children: intl.formatMessage(messages.saveButton) })] })] }));
|
|
59
|
+
};
|
|
60
|
+
export default AddBetaTestersModal;
|
|
61
|
+
//# sourceMappingURL=AddBetaTestersModal.js.map
|
|
@@ -0,0 +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,7 +1,6 @@
|
|
|
1
1
|
export interface EnrollLearnersModalProps {
|
|
2
2
|
isOpen: boolean;
|
|
3
3
|
onClose: () => void;
|
|
4
|
-
onSuccess: () => void;
|
|
5
4
|
}
|
|
6
|
-
declare const EnrollLearnersModal: ({ isOpen, onClose
|
|
5
|
+
declare const EnrollLearnersModal: ({ isOpen, onClose }: EnrollLearnersModalProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
6
|
export default EnrollLearnersModal;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { useParams } from 'react-router-dom';
|
|
4
4
|
import { isAxiosError } from 'axios';
|
|
@@ -7,29 +7,38 @@ import { Button, FormControl, ModalDialog, Form } from '@openedx/paragon';
|
|
|
7
7
|
import { useUpdateEnrollments } from '../../enrollments/data/apiHook';
|
|
8
8
|
import messages from '../../enrollments/messages';
|
|
9
9
|
import { useAlert } from '../../providers/AlertProvider';
|
|
10
|
-
const EnrollLearnersModal = ({ isOpen, onClose
|
|
10
|
+
const EnrollLearnersModal = ({ isOpen, onClose }) => {
|
|
11
11
|
const intl = useIntl();
|
|
12
12
|
const { courseId = '' } = useParams();
|
|
13
13
|
const [emails, setEmails] = useState('');
|
|
14
14
|
const [autoEnroll, setAutoEnroll] = useState(true);
|
|
15
15
|
const [emailStudents, setEmailStudents] = useState(true);
|
|
16
16
|
const { mutate: enrollLearners } = useUpdateEnrollments(courseId);
|
|
17
|
-
const { showModal } = useAlert();
|
|
17
|
+
const { showModal, addAlert } = useAlert();
|
|
18
18
|
const handleSave = () => {
|
|
19
19
|
const identifier = emails.split(',').map(email => email.trim()).filter(email => email);
|
|
20
20
|
enrollLearners({ identifier, action: 'enroll', autoEnroll, emailStudents }, {
|
|
21
|
-
onSuccess: () => {
|
|
21
|
+
onSuccess: (data) => {
|
|
22
|
+
var _a;
|
|
23
|
+
const failedUsernames = ((_a = data.results) === null || _a === void 0 ? void 0 : _a.filter(user => user.invalidIdentifier).map(user => user.identifier)) || [];
|
|
24
|
+
if (failedUsernames.length > 0) {
|
|
25
|
+
addAlert({
|
|
26
|
+
type: 'danger',
|
|
27
|
+
message: intl.formatMessage(messages.failedEnrollLearners),
|
|
28
|
+
extraContent: (failedUsernames.map((learner) => (_jsxs("p", { className: "mb-0", children: ["\u2022 ", intl.formatMessage(messages.unknownLearner, { learner })] }, learner))))
|
|
29
|
+
});
|
|
30
|
+
}
|
|
22
31
|
setEmails('');
|
|
23
32
|
setAutoEnroll(true);
|
|
24
33
|
setEmailStudents(true);
|
|
25
|
-
|
|
34
|
+
onClose();
|
|
26
35
|
},
|
|
27
36
|
onError: (error) => {
|
|
28
37
|
var _a;
|
|
29
38
|
const notFound = isAxiosError(error) && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404;
|
|
30
39
|
const errorMessage = notFound
|
|
31
40
|
? intl.formatMessage(messages.enrollLearnerNotFoundError)
|
|
32
|
-
:
|
|
41
|
+
: intl.formatMessage(messages.enrollLearnerError);
|
|
33
42
|
showModal({
|
|
34
43
|
message: errorMessage,
|
|
35
44
|
variant: 'danger',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnrollLearnersModal.js","sourceRoot":"","sources":["../../../src/enrollments/components/EnrollLearnersModal.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,QAAQ,MAAM,2BAA2B,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"EnrollLearnersModal.js","sourceRoot":"","sources":["../../../src/enrollments/components/EnrollLearnersModal.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 { useUpdateEnrollments } from '@src/enrollments/data/apiHook';\nimport messages from '@src/enrollments/messages';\nimport { useAlert } from '@src/providers/AlertProvider';\n\nexport interface EnrollLearnersModalProps {\n isOpen: boolean,\n onClose: () => void,\n}\n\nconst EnrollLearnersModal = ({\n isOpen,\n onClose\n}: EnrollLearnersModalProps) => {\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: enrollLearners } = useUpdateEnrollments(courseId);\n const { showModal, addAlert } = useAlert();\n\n const handleSave = () => {\n const identifier = emails.split(',').map(email => email.trim()).filter(email => email);\n enrollLearners({ identifier, action: 'enroll', autoEnroll, emailStudents }, {\n onSuccess: (data) => {\n const failedUsernames = data.results?.filter(user => user.invalidIdentifier).map(user => user.identifier) || [];\n if (failedUsernames.length > 0) {\n addAlert({\n type: 'danger',\n message: intl.formatMessage(messages.failedEnrollLearners),\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 setEmails('');\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.enrollLearners)}>\n <ModalDialog.Header className=\"border-light-700 border-bottom\">\n <h3 className=\"text-primary-500\">{intl.formatMessage(messages.enrollLearners)}</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.addLearnerInstructions)}</p>\n <FormControl\n name=\"identifier\"\n as=\"textarea\"\n rows={4}\n placeholder={intl.formatMessage(messages.userIdentifierPlaceholder)}\n onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => setEmails(e.target.value)}\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={emails.trim().length === 0}>\n {intl.formatMessage(messages.saveButton)}\n </Button>\n </ModalDialog.Footer>\n </ModalDialog>\n );\n};\n\nexport default EnrollLearnersModal;\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EnrolledLearner } from '../../enrollments/types';
|
|
2
2
|
interface EnrollmentsListProps {
|
|
3
3
|
onUnenroll: (learner: EnrolledLearner) => void;
|
|
4
|
+
onBetaTesterChange: (learner: EnrolledLearner) => void;
|
|
4
5
|
}
|
|
5
|
-
declare const EnrollmentsList: ({ onUnenroll }: EnrollmentsListProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
declare const EnrollmentsList: ({ onUnenroll, onBetaTesterChange }: EnrollmentsListProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
7
|
export default EnrollmentsList;
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useCallback, useState } from 'react';
|
|
3
3
|
import { useParams } from 'react-router-dom';
|
|
4
4
|
import { useIntl } from '@openedx/frontend-base';
|
|
5
|
-
import { ActionRow, Button, DataTable, FormControl, Icon, IconButton } from '@openedx/paragon';
|
|
5
|
+
import { ActionRow, Button, DataTable, FormControl, Icon, IconButton, OverlayTrigger, Popover } from '@openedx/paragon';
|
|
6
6
|
import { FilterList, MoreVert, Search } from '@openedx/paragon/icons';
|
|
7
7
|
import messages from '../../enrollments/messages';
|
|
8
8
|
import { useEnrollments } from '../../enrollments/data/apiHook';
|
|
@@ -31,7 +31,7 @@ const BetaTesterFilter = ({ column: { filterValue, setFilter } }) => {
|
|
|
31
31
|
};
|
|
32
32
|
return (_jsx(FormControl, { as: "select", className: "mb-0", name: "isBetaTester", size: "md", value: filterValue, onChange: handleSelectChange, leadingElement: _jsx(Icon, { src: FilterList }), children: betaTesterOptions.map((option) => (_jsx("option", { value: option.value, children: intl.formatMessage(option.label) }, option.value))) }));
|
|
33
33
|
};
|
|
34
|
-
const EnrollmentsList = ({ onUnenroll }) => {
|
|
34
|
+
const EnrollmentsList = ({ onUnenroll, onBetaTesterChange }) => {
|
|
35
35
|
const intl = useIntl();
|
|
36
36
|
const { courseId = '' } = useParams();
|
|
37
37
|
const [filters, setFilters] = useState({ page: 0, username: '', isBetaTester: '' });
|
|
@@ -56,10 +56,6 @@ const EnrollmentsList = ({ onUnenroll }) => {
|
|
|
56
56
|
setFilters((prevFilters) => (Object.assign(Object.assign({}, prevFilters), { page: data.pageIndex })));
|
|
57
57
|
}
|
|
58
58
|
};
|
|
59
|
-
const handleMoreButton = () => {
|
|
60
|
-
// Handle more button click
|
|
61
|
-
console.log('More button clicked');
|
|
62
|
-
};
|
|
63
59
|
const tableColumns = [
|
|
64
60
|
{ accessor: 'username', Header: intl.formatMessage(messages.username), Filter: UsernameFilter },
|
|
65
61
|
{ accessor: 'fullName', Header: intl.formatMessage(messages.fullName), disableFilters: true },
|
|
@@ -77,14 +73,17 @@ const EnrollmentsList = ({ onUnenroll }) => {
|
|
|
77
73
|
Filter: BetaTesterFilter
|
|
78
74
|
},
|
|
79
75
|
];
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
76
|
+
const ActionCustomCell = useCallback(({ row: { original } }) => {
|
|
77
|
+
const popoverContent = (_jsx(Popover, { id: `popover-${original.username}`, className: "border-0 shadow-sm", children: _jsx(Popover.Content, { className: "p-0 border-0", children: _jsx("div", { className: "dropdown-menu show position-static border shadow-sm", children: _jsx("button", { type: "button", className: "dropdown-item", onClick: () => onBetaTesterChange(original), children: original.isBetaTester
|
|
78
|
+
? intl.formatMessage(messages.revokeBetaTester)
|
|
79
|
+
: intl.formatMessage(messages.grantBetaTester) }) }) }) }));
|
|
80
|
+
return (_jsxs(ActionRow, { className: "justify-content-start", children: [_jsx(Button, { className: "pl-0", onClick: () => onUnenroll(original), variant: "link", children: intl.formatMessage(messages.unenrollButton) }), _jsx(OverlayTrigger, { trigger: "click", placement: "bottom-end", overlay: popoverContent, rootClose: true, children: _jsx(IconButton, { alt: intl.formatMessage(messages.changeBetaTesterStatus), className: "lead", iconAs: MoreVert }) })] }));
|
|
81
|
+
}, [intl, onBetaTesterChange, onUnenroll]);
|
|
83
82
|
return (_jsxs(DataTable, { className: "mt-3", columns: tableColumns, additionalColumns: [
|
|
84
83
|
{
|
|
85
84
|
id: 'actions',
|
|
86
85
|
Header: intl.formatMessage(messages.actions),
|
|
87
|
-
Cell:
|
|
86
|
+
Cell: ActionCustomCell,
|
|
88
87
|
}
|
|
89
88
|
], data: data.results, fetchData: handleFetchData, state: {
|
|
90
89
|
pageIndex: filters.page,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnrollmentsList.js","sourceRoot":"","sources":["../../../src/enrollments/components/EnrollmentsList.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { ActionRow, Button, DataTable, FormControl, Icon, IconButton } from '@openedx/paragon';\nimport { FilterList, MoreVert, Search } from '@openedx/paragon/icons';\nimport messages from '@src/enrollments/messages';\nimport { useEnrollments } from '@src/enrollments/data/apiHook';\nimport { EnrolledLearner } from '@src/enrollments/types';\nimport { useDebouncedFilter } from '@src/hooks/useDebouncedFilter';\nimport { DataTableFetchDataProps, TableCellValue } from '@src/types';\n\nconst ENROLLMENTS_PAGE_SIZE = 25;\n\nconst betaTesterOptions = [\n { value: '', label: messages.allEnrollees },\n { value: 'true', label: messages.betaTesters },\n { value: 'false', label: messages.nonBetaTesters },\n];\n\ninterface EnrollmentsListProps {\n onUnenroll: (learner: EnrolledLearner) => void,\n}\n\nconst UsernameFilter = ({ column: { filterValue, setFilter } }: { column: { filterValue: string, setFilter: (value: string) => void } }) => {\n const intl = useIntl();\n const { inputValue, handleChange } = useDebouncedFilter({\n filterValue,\n setFilter,\n });\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n handleChange(e.target.value);\n };\n\n return (\n <FormControl\n className=\"mb-0\"\n onChange={handleInputChange}\n placeholder={intl.formatMessage(messages.searchPlaceholder)}\n trailingElement={<Icon src={Search} />}\n value={inputValue}\n />\n );\n};\n\nconst BetaTesterFilter = ({ column: { filterValue, setFilter } }: { column: { filterValue: string, setFilter: (value: string) => void } }) => {\n const intl = useIntl();\n\n const handleSelectChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n setFilter(e.target.value);\n };\n\n return (\n <FormControl\n as=\"select\"\n className=\"mb-0\"\n name=\"isBetaTester\"\n size=\"md\"\n value={filterValue}\n onChange={handleSelectChange}\n leadingElement={<Icon src={FilterList} />}\n >\n {\n betaTesterOptions.map((option) => (\n <option key={option.value} value={option.value}>\n {intl.formatMessage(option.label)}\n </option>\n ))\n }\n </FormControl>\n );\n};\n\nconst EnrollmentsList = ({ onUnenroll }: EnrollmentsListProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams();\n const [filters, setFilters] = useState({ page: 0, username: '', isBetaTester: '' });\n const { data = { count: 0, results: [], numPages: 0 }, isLoading } = useEnrollments(courseId, {\n page: filters.page,\n pageSize: ENROLLMENTS_PAGE_SIZE,\n emailOrUsername: filters.username,\n isBetaTester: filters.isBetaTester,\n });\n\n const handleFetchData = (data: DataTableFetchDataProps) => {\n const usernameFilter = data.filters?.find((f) => f.id === 'username');\n const newEmailOrUsername = usernameFilter ? usernameFilter.value : '';\n const betaTesterFilter = data.filters?.find((f) => f.id === 'isBetaTester');\n const newIsBetaTester = betaTesterFilter ? betaTesterFilter.value : '';\n const filtersChanged = (newEmailOrUsername !== filters.username) || (newIsBetaTester !== filters.isBetaTester);\n\n if (filtersChanged) {\n setFilters((prevFilters) => ({\n ...prevFilters,\n username: newEmailOrUsername,\n isBetaTester: newIsBetaTester,\n page: 0,\n }));\n return;\n }\n\n if (data.pageIndex !== filters.page) {\n setFilters((prevFilters) => ({ ...prevFilters, page: data.pageIndex }));\n }\n };\n\n const handleMoreButton = () => {\n // Handle more button click\n console.log('More button clicked');\n };\n\n const tableColumns = [\n { accessor: 'username', Header: intl.formatMessage(messages.username), Filter: UsernameFilter },\n { accessor: 'fullName', Header: intl.formatMessage(messages.fullName), disableFilters: true },\n { accessor: 'email', Header: intl.formatMessage(messages.email), disableFilters: true },\n {\n accessor: 'mode',\n Header: intl.formatMessage(messages.track),\n Cell: ({ value }: { value: string }) => (\n <span className=\"text-capitalize\">{value || 'N/A'}</span>\n ),\n disableFilters: true,\n },\n {\n accessor: 'isBetaTester',\n Header: intl.formatMessage(messages.betaTester),\n Cell: ({ value }: { value: string }) => (value ? intl.formatMessage(messages.trueLabel) : ''),\n Filter: BetaTesterFilter\n },\n ];\n\n const actionCustomCell = useCallback(({ row: { original } }: TableCellValue<EnrolledLearner>) => {\n return (\n <ActionRow className=\"justify-content-start\">\n <Button className=\"pl-0\" onClick={() => onUnenroll(original)} variant=\"link\">\n {intl.formatMessage(messages.unenrollButton)}\n </Button>\n <IconButton\n alt={intl.formatMessage(messages.changeBetaTesterStatus)}\n className=\"lead\"\n iconAs={MoreVert}\n onClick={handleMoreButton}\n />\n </ActionRow>\n );\n }, [onUnenroll, intl]);\n\n return (\n <DataTable\n className=\"mt-3\"\n columns={tableColumns}\n additionalColumns={[\n {\n id: 'actions',\n Header: intl.formatMessage(messages.actions),\n Cell: actionCustomCell,\n }\n ]}\n data={data.results}\n fetchData={handleFetchData}\n state={{\n pageIndex: filters.page,\n pageSize: ENROLLMENTS_PAGE_SIZE,\n filters: [\n { id: 'username', value: filters.username },\n { id: 'isBetaTester', value: filters.isBetaTester },\n ]\n }}\n isFilterable\n isLoading={isLoading}\n isPaginated\n itemCount={data.count}\n manualFilters\n manualPagination\n numBreakoutFilters={2}\n pageSize={ENROLLMENTS_PAGE_SIZE}\n pageCount={data.numPages}\n FilterStatusComponent={() => null}\n >\n <DataTable.TableControlBar className=\"px-3 pt-3 pb-2\" />\n <DataTable.Table />\n <DataTable.EmptyTable content={intl.formatMessage(messages.noEnrollments)} />\n <DataTable.TableFooter />\n </DataTable>\n );\n};\n\nexport default EnrollmentsList;\n"]}
|
|
1
|
+
{"version":3,"file":"EnrollmentsList.js","sourceRoot":"","sources":["../../../src/enrollments/components/EnrollmentsList.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { ActionRow, Button, DataTable, FormControl, Icon, IconButton, OverlayTrigger, Popover } from '@openedx/paragon';\nimport { FilterList, MoreVert, Search } from '@openedx/paragon/icons';\nimport messages from '@src/enrollments/messages';\nimport { useEnrollments } from '@src/enrollments/data/apiHook';\nimport { EnrolledLearner } from '@src/enrollments/types';\nimport { useDebouncedFilter } from '@src/hooks/useDebouncedFilter';\nimport { DataTableFetchDataProps, TableCellValue } from '@src/types';\n\nconst ENROLLMENTS_PAGE_SIZE = 25;\n\nconst betaTesterOptions = [\n { value: '', label: messages.allEnrollees },\n { value: 'true', label: messages.betaTesters },\n { value: 'false', label: messages.nonBetaTesters },\n];\n\ninterface EnrollmentsListProps {\n onUnenroll: (learner: EnrolledLearner) => void,\n onBetaTesterChange: (learner: EnrolledLearner) => void,\n}\n\nconst UsernameFilter = ({ column: { filterValue, setFilter } }: { column: { filterValue: string, setFilter: (value: string) => void } }) => {\n const intl = useIntl();\n const { inputValue, handleChange } = useDebouncedFilter({\n filterValue,\n setFilter,\n });\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n handleChange(e.target.value);\n };\n\n return (\n <FormControl\n className=\"mb-0\"\n onChange={handleInputChange}\n placeholder={intl.formatMessage(messages.searchPlaceholder)}\n trailingElement={<Icon src={Search} />}\n value={inputValue}\n />\n );\n};\n\nconst BetaTesterFilter = ({ column: { filterValue, setFilter } }: { column: { filterValue: string, setFilter: (value: string) => void } }) => {\n const intl = useIntl();\n\n const handleSelectChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n setFilter(e.target.value);\n };\n\n return (\n <FormControl\n as=\"select\"\n className=\"mb-0\"\n name=\"isBetaTester\"\n size=\"md\"\n value={filterValue}\n onChange={handleSelectChange}\n leadingElement={<Icon src={FilterList} />}\n >\n {\n betaTesterOptions.map((option) => (\n <option key={option.value} value={option.value}>\n {intl.formatMessage(option.label)}\n </option>\n ))\n }\n </FormControl>\n );\n};\n\nconst EnrollmentsList = ({ onUnenroll, onBetaTesterChange }: EnrollmentsListProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams();\n const [filters, setFilters] = useState({ page: 0, username: '', isBetaTester: '' });\n const { data = { count: 0, results: [], numPages: 0 }, isLoading } = useEnrollments(courseId, {\n page: filters.page,\n pageSize: ENROLLMENTS_PAGE_SIZE,\n emailOrUsername: filters.username,\n isBetaTester: filters.isBetaTester,\n });\n\n const handleFetchData = (data: DataTableFetchDataProps) => {\n const usernameFilter = data.filters?.find((f) => f.id === 'username');\n const newEmailOrUsername = usernameFilter ? usernameFilter.value : '';\n const betaTesterFilter = data.filters?.find((f) => f.id === 'isBetaTester');\n const newIsBetaTester = betaTesterFilter ? betaTesterFilter.value : '';\n const filtersChanged = (newEmailOrUsername !== filters.username) || (newIsBetaTester !== filters.isBetaTester);\n\n if (filtersChanged) {\n setFilters((prevFilters) => ({\n ...prevFilters,\n username: newEmailOrUsername,\n isBetaTester: newIsBetaTester,\n page: 0,\n }));\n return;\n }\n\n if (data.pageIndex !== filters.page) {\n setFilters((prevFilters) => ({ ...prevFilters, page: data.pageIndex }));\n }\n };\n\n const tableColumns = [\n { accessor: 'username', Header: intl.formatMessage(messages.username), Filter: UsernameFilter },\n { accessor: 'fullName', Header: intl.formatMessage(messages.fullName), disableFilters: true },\n { accessor: 'email', Header: intl.formatMessage(messages.email), disableFilters: true },\n {\n accessor: 'mode',\n Header: intl.formatMessage(messages.track),\n Cell: ({ value }: { value: string }) => (\n <span className=\"text-capitalize\">{value || 'N/A'}</span>\n ),\n disableFilters: true,\n },\n {\n accessor: 'isBetaTester',\n Header: intl.formatMessage(messages.betaTester),\n Cell: ({ value }: { value: string }) => (value ? intl.formatMessage(messages.trueLabel) : ''),\n Filter: BetaTesterFilter\n },\n ];\n\n const ActionCustomCell = useCallback(({ row: { original } }: TableCellValue<EnrolledLearner>) => {\n const popoverContent = (\n <Popover\n id={`popover-${original.username}`}\n className=\"border-0 shadow-sm\"\n >\n <Popover.Content className=\"p-0 border-0\">\n <div className=\"dropdown-menu show position-static border shadow-sm\">\n <button\n type=\"button\"\n className=\"dropdown-item\"\n onClick={() => onBetaTesterChange(original)}\n >\n {original.isBetaTester\n ? intl.formatMessage(messages.revokeBetaTester)\n : intl.formatMessage(messages.grantBetaTester)}\n </button>\n </div>\n </Popover.Content>\n </Popover>\n );\n\n return (\n <ActionRow className=\"justify-content-start\">\n <Button className=\"pl-0\" onClick={() => onUnenroll(original)} variant=\"link\">\n {intl.formatMessage(messages.unenrollButton)}\n </Button>\n <OverlayTrigger\n trigger=\"click\"\n placement=\"bottom-end\"\n overlay={popoverContent}\n rootClose\n >\n <IconButton\n alt={intl.formatMessage(messages.changeBetaTesterStatus)}\n className=\"lead\"\n iconAs={MoreVert}\n />\n </OverlayTrigger>\n </ActionRow>\n );\n }, [intl, onBetaTesterChange, onUnenroll]);\n\n return (\n <DataTable\n className=\"mt-3\"\n columns={tableColumns}\n additionalColumns={[\n {\n id: 'actions',\n Header: intl.formatMessage(messages.actions),\n Cell: ActionCustomCell,\n }\n ]}\n data={data.results}\n fetchData={handleFetchData}\n state={{\n pageIndex: filters.page,\n pageSize: ENROLLMENTS_PAGE_SIZE,\n filters: [\n { id: 'username', value: filters.username },\n { id: 'isBetaTester', value: filters.isBetaTester },\n ]\n }}\n isFilterable\n isLoading={isLoading}\n isPaginated\n itemCount={data.count}\n manualFilters\n manualPagination\n numBreakoutFilters={2}\n pageSize={ENROLLMENTS_PAGE_SIZE}\n pageCount={data.numPages}\n FilterStatusComponent={() => null}\n >\n <DataTable.TableControlBar className=\"px-3 pt-3 pb-2\" />\n <DataTable.Table />\n <DataTable.EmptyTable content={intl.formatMessage(messages.noEnrollments)} />\n <DataTable.TableFooter />\n </DataTable>\n );\n};\n\nexport default EnrollmentsList;\n"]}
|
|
@@ -3,7 +3,6 @@ interface UnenrollModalProps {
|
|
|
3
3
|
learner: EnrolledLearner;
|
|
4
4
|
isOpen: boolean;
|
|
5
5
|
onClose: () => void;
|
|
6
|
-
onSuccess: () => void;
|
|
7
6
|
}
|
|
8
|
-
declare const UnenrollModal: ({ learner, isOpen, onClose
|
|
7
|
+
declare const UnenrollModal: ({ learner, isOpen, onClose }: UnenrollModalProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
8
|
export default UnenrollModal;
|
|
@@ -5,7 +5,7 @@ import { Button, ModalDialog } from '@openedx/paragon';
|
|
|
5
5
|
import { useAlert } from '../../providers/AlertProvider';
|
|
6
6
|
import { useUpdateEnrollments } from '../../enrollments/data/apiHook';
|
|
7
7
|
import messages from '../../enrollments/messages';
|
|
8
|
-
const UnenrollModal = ({ learner, isOpen, onClose
|
|
8
|
+
const UnenrollModal = ({ learner, isOpen, onClose }) => {
|
|
9
9
|
const intl = useIntl();
|
|
10
10
|
const { courseId = '' } = useParams();
|
|
11
11
|
const { mutate: unenrollLearners, isPending } = useUpdateEnrollments(courseId);
|
|
@@ -16,7 +16,6 @@ const UnenrollModal = ({ learner, isOpen, onClose, onSuccess }) => {
|
|
|
16
16
|
action: 'unenroll',
|
|
17
17
|
}, {
|
|
18
18
|
onSuccess: () => {
|
|
19
|
-
onSuccess();
|
|
20
19
|
onClose();
|
|
21
20
|
},
|
|
22
21
|
onError: (error) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UnenrollModal.js","sourceRoot":"","sources":["../../../src/enrollments/components/UnenrollModal.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,QAAQ,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"UnenrollModal.js","sourceRoot":"","sources":["../../../src/enrollments/components/UnenrollModal.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,QAAQ,MAAM,2BAA2B,CAAC;AASjD,MAAM,aAAa,GAAG,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAsB,EAAE,EAAE;IACzE,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,EAAE,QAAQ,GAAG,EAAE,EAAE,GAAG,SAAS,EAAwB,CAAC;IAC5D,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC/E,MAAM,EAAE,SAAS,EAAE,GAAG,QAAQ,EAAE,CAAC;IAEjC,MAAM,cAAc,GAAG,GAAG,EAAE;QAC1B,gBAAgB,CAAC;YACf,UAAU,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;YAC9B,MAAM,EAAE,UAAU;SACnB,EAAE;YACD,SAAS,EAAE,GAAG,EAAE;gBACd,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBACjB,SAAS,CAAC;oBACR,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,oBAAoB,CAAC;oBAC3E,OAAO,EAAE,QAAQ;oBACjB,WAAW,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC;iBACtD,CAAC,CAAC;YACL,CAAC;SACF,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,OAAO,CACL,MAAC,WAAW,IAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,iBAAiB,EAAE,KAAK,aAC3H,KAAC,WAAW,CAAC,MAAM,cACjB,aAAI,SAAS,EAAC,kBAAkB,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,oBAAoB,CAAC,GAAM,GACtE,EACrB,KAAC,WAAW,CAAC,IAAI,IAAC,SAAS,EAAC,MAAM,YAChC,sBAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,4BAA4B,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,GAAK,GAC7E,EACnB,MAAC,WAAW,CAAC,MAAM,eACjB,KAAC,MAAM,IAAC,OAAO,EAAC,UAAU,EAAC,OAAO,EAAE,OAAO,YAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,YAAY,CAAC,GAAU,EACjG,KAAC,MAAM,IACL,SAAS,EAAC,MAAM,EAChB,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,SAAS,YAElB,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,cAAc,CAAC,GACrC,IACU,IACT,CACf,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,aAAa,CAAC","sourcesContent":["import { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, ModalDialog } from '@openedx/paragon';\nimport { useAlert } from '@src/providers/AlertProvider';\nimport { useUpdateEnrollments } from '@src/enrollments/data/apiHook';\nimport messages from '@src/enrollments/messages';\nimport { EnrolledLearner } from '@src/enrollments/types';\n\ninterface UnenrollModalProps {\n learner: EnrolledLearner,\n isOpen: boolean,\n onClose: () => void,\n}\n\nconst UnenrollModal = ({ learner, isOpen, onClose }: UnenrollModalProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const { mutate: unenrollLearners, isPending } = useUpdateEnrollments(courseId);\n const { showModal } = useAlert();\n\n const handleUnenroll = () => {\n unenrollLearners({\n identifier: [learner.username],\n action: 'unenroll',\n }, {\n onSuccess: () => {\n onClose();\n },\n onError: (error) => {\n showModal({\n message: error.message || intl.formatMessage(messages.unenrollLearnerError),\n variant: 'danger',\n confirmText: intl.formatMessage(messages.closeButton),\n });\n }\n });\n };\n\n return (\n <ModalDialog isOpen={isOpen} onClose={onClose} title={intl.formatMessage(messages.unenrollLearners)} isOverflowVisible={false}>\n <ModalDialog.Header>\n <h3 className=\"text-primary-500\">{intl.formatMessage(messages.unenrollLearnerTitle)}</h3>\n </ModalDialog.Header>\n <ModalDialog.Body className=\"py-4\">\n <p>{intl.formatMessage(messages.unenrollLearnersConfirmation, { name: learner.fullName })}</p>\n </ModalDialog.Body>\n <ModalDialog.Footer>\n <Button variant=\"tertiary\" onClick={onClose}>{intl.formatMessage(messages.cancelButton)}</Button>\n <Button\n className=\"ml-2\"\n onClick={handleUnenroll}\n disabled={isPending}\n >\n {intl.formatMessage(messages.unenrollButton)}\n </Button>\n </ModalDialog.Footer>\n </ModalDialog>\n );\n};\n\nexport default UnenrollModal;\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { EnrolledLearner } from '../../enrollments/types';
|
|
2
|
+
interface UpdateBetaTesterModalProps {
|
|
3
|
+
learner: EnrolledLearner;
|
|
4
|
+
isOpen: boolean;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
}
|
|
7
|
+
declare const UpdateBetaTesterModal: ({ learner, isOpen, onClose }: UpdateBetaTesterModalProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
8
|
+
export default UpdateBetaTesterModal;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useParams } from 'react-router-dom';
|
|
3
|
+
import { useCallback, useEffect } from 'react';
|
|
4
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
5
|
+
import { Button, ModalDialog } from '@openedx/paragon';
|
|
6
|
+
import { useAlert } from '../../providers/AlertProvider';
|
|
7
|
+
import { useUpdateBetaTesters } from '../../enrollments/data/apiHook';
|
|
8
|
+
import messages from '../../enrollments/messages';
|
|
9
|
+
const UpdateBetaTesterModal = ({ learner, isOpen, onClose }) => {
|
|
10
|
+
const intl = useIntl();
|
|
11
|
+
const { courseId = '' } = useParams();
|
|
12
|
+
const { mutate: updateBetaTester, isPending } = useUpdateBetaTesters(courseId);
|
|
13
|
+
const { addAlert, showModal } = useAlert();
|
|
14
|
+
const handleUpdateBetaTester = useCallback(() => {
|
|
15
|
+
updateBetaTester({
|
|
16
|
+
identifier: [learner.username],
|
|
17
|
+
action: learner.isBetaTester ? 'remove' : 'add',
|
|
18
|
+
}, {
|
|
19
|
+
onSuccess: (data) => {
|
|
20
|
+
var _a;
|
|
21
|
+
const failedUsernames = ((_a = data.results) === null || _a === void 0 ? void 0 : _a.filter(user => user.userDoesNotExist).map(user => user.identifier)) || [];
|
|
22
|
+
if (failedUsernames.length > 0) {
|
|
23
|
+
addAlert({
|
|
24
|
+
type: 'danger',
|
|
25
|
+
message: intl.formatMessage(messages.failedBetaTesters),
|
|
26
|
+
extraContent: (failedUsernames.map((learner) => (_jsxs("p", { className: "mb-0", children: ["\u2022 ", intl.formatMessage(messages.unknownLearner, { learner })] }, learner))))
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
onError: () => {
|
|
31
|
+
showModal({
|
|
32
|
+
message: learner.isBetaTester ? intl.formatMessage(messages.removeBetaTesterError) : intl.formatMessage(messages.addBetaTesterError),
|
|
33
|
+
variant: 'danger',
|
|
34
|
+
confirmText: intl.formatMessage(messages.closeButton),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
onClose();
|
|
39
|
+
}, [updateBetaTester, learner.username, learner.isBetaTester, addAlert, intl, showModal, onClose]);
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (isOpen && !learner.isBetaTester) {
|
|
42
|
+
handleUpdateBetaTester();
|
|
43
|
+
}
|
|
44
|
+
}, [handleUpdateBetaTester, isOpen, learner.isBetaTester]);
|
|
45
|
+
// Only show modal for removing beta testers (requires confirmation)
|
|
46
|
+
if (!isOpen || !learner.isBetaTester) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
return (_jsxs(ModalDialog, { isOpen: isOpen, onClose: onClose, title: intl.formatMessage(messages.removeBetaTesterTitle), isOverflowVisible: false, children: [_jsx(ModalDialog.Header, { children: _jsx("h3", { className: "text-primary-500", children: intl.formatMessage(messages.removeBetaTesterTitle) }) }), _jsx(ModalDialog.Body, { className: "py-4", children: _jsx("p", { children: intl.formatMessage(messages.removeBetaTesterDescription) }) }), _jsxs(ModalDialog.Footer, { children: [_jsx(Button, { variant: "tertiary", onClick: onClose, children: intl.formatMessage(messages.cancelButton) }), _jsx(Button, { className: "ml-2", onClick: handleUpdateBetaTester, disabled: isPending, children: intl.formatMessage(messages.revoke) })] })] }));
|
|
50
|
+
};
|
|
51
|
+
export default UpdateBetaTesterModal;
|
|
52
|
+
//# sourceMappingURL=UpdateBetaTesterModal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UpdateBetaTesterModal.js","sourceRoot":"","sources":["../../../src/enrollments/components/UpdateBetaTesterModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useParams } from 'react-router-dom';\nimport { useCallback, useEffect } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, ModalDialog } from '@openedx/paragon';\nimport { useAlert } from '@src/providers/AlertProvider';\nimport { useUpdateBetaTesters } from '@src/enrollments/data/apiHook';\nimport messages from '@src/enrollments/messages';\nimport { EnrolledLearner } from '@src/enrollments/types';\n\ninterface UpdateBetaTesterModalProps {\n learner: EnrolledLearner,\n isOpen: boolean,\n onClose: () => void,\n}\n\nconst UpdateBetaTesterModal = ({ learner, isOpen, onClose }: UpdateBetaTesterModalProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const { mutate: updateBetaTester, isPending } = useUpdateBetaTesters(courseId);\n const { addAlert, showModal } = useAlert();\n\n const handleUpdateBetaTester = useCallback(() => {\n updateBetaTester({\n identifier: [learner.username],\n action: learner.isBetaTester ? 'remove' : 'add',\n }, {\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 },\n onError: () => {\n showModal({\n message: learner.isBetaTester ? intl.formatMessage(messages.removeBetaTesterError) : intl.formatMessage(messages.addBetaTesterError),\n variant: 'danger',\n confirmText: intl.formatMessage(messages.closeButton),\n });\n }\n });\n\n onClose();\n }, [updateBetaTester, learner.username, learner.isBetaTester, addAlert, intl, showModal, onClose]);\n\n useEffect(() => {\n if (isOpen && !learner.isBetaTester) {\n handleUpdateBetaTester();\n }\n }, [handleUpdateBetaTester, isOpen, learner.isBetaTester]);\n\n // Only show modal for removing beta testers (requires confirmation)\n if (!isOpen || !learner.isBetaTester) {\n return null;\n }\n\n return (\n <ModalDialog isOpen={isOpen} onClose={onClose} title={intl.formatMessage(messages.removeBetaTesterTitle)} isOverflowVisible={false}>\n <ModalDialog.Header>\n <h3 className=\"text-primary-500\">{intl.formatMessage(messages.removeBetaTesterTitle)}</h3>\n </ModalDialog.Header>\n <ModalDialog.Body className=\"py-4\">\n <p>{intl.formatMessage(messages.removeBetaTesterDescription)}</p>\n </ModalDialog.Body>\n <ModalDialog.Footer>\n <Button variant=\"tertiary\" onClick={onClose}>{intl.formatMessage(messages.cancelButton)}</Button>\n <Button\n className=\"ml-2\"\n onClick={handleUpdateBetaTester}\n disabled={isPending}\n >\n {intl.formatMessage(messages.revoke)}\n </Button>\n </ModalDialog.Footer>\n </ModalDialog>\n );\n};\n\nexport default UpdateBetaTesterModal;\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { EnrollmentsParams, EnrollmentStatusResponse, EnrolledLearner, UpdateEnrollmentsParams } from '../../enrollments/types';
|
|
1
|
+
import { EnrollmentsParams, EnrollmentStatusResponse, EnrolledLearner, UpdateEnrollmentsParams, UpdateBetaTestersParams, UpdateEnrollmentsResponse, UpdateBetaTestersResponse } from '../../enrollments/types';
|
|
2
2
|
import { DataList } from '../../types';
|
|
3
3
|
export declare const getEnrollments: (courseId: string, params: EnrollmentsParams) => Promise<DataList<EnrolledLearner>>;
|
|
4
4
|
export declare const getEnrollmentStatus: (courseId: string, userIdentifier: string) => Promise<EnrollmentStatusResponse>;
|
|
5
|
-
export declare const updateEnrollments: (courseId: string, params: UpdateEnrollmentsParams) => Promise<
|
|
5
|
+
export declare const updateEnrollments: (courseId: string, params: UpdateEnrollmentsParams) => Promise<UpdateEnrollmentsResponse>;
|
|
6
|
+
export declare const updateBetaTesters: (courseId: string, params: UpdateBetaTestersParams) => Promise<UpdateBetaTestersResponse>;
|
|
@@ -31,6 +31,12 @@ export const getEnrollmentStatus = (courseId, userIdentifier) => __awaiter(void
|
|
|
31
31
|
});
|
|
32
32
|
export const updateEnrollments = (courseId, params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
33
33
|
const snakeCaseParams = snakeCaseObject(params);
|
|
34
|
-
yield getAuthenticatedHttpClient().post(`${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/enrollments/modify`, snakeCaseParams);
|
|
34
|
+
const { data } = yield getAuthenticatedHttpClient().post(`${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/enrollments/modify`, snakeCaseParams);
|
|
35
|
+
return camelCaseObject(data);
|
|
36
|
+
});
|
|
37
|
+
export const updateBetaTesters = (courseId, params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
38
|
+
const snakeCaseParams = snakeCaseObject(params);
|
|
39
|
+
const { data } = yield getAuthenticatedHttpClient().post(`${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/beta_testers/modify`, snakeCaseParams);
|
|
40
|
+
return camelCaseObject(data);
|
|
35
41
|
});
|
|
36
42
|
//# sourceMappingURL=api.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/enrollments/data/api.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACtG,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAI9C,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,QAAgB,EAChB,MAAyB,EACW,EAAE;IACtC,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,QAAQ,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IACvD,CAAC;IAED,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,WAAW,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CACrD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,gBAAgB,WAAW,CAAC,QAAQ,EAAE,EAAE,CACjG,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,QAAgB,EAChB,cAAsB,EACa,EAAE;IACrC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,IAAI,CACtD,GAAG,aAAa,EAAE,YAAY,QAAQ,+CAA+C,EAAE;QACrF,yBAAyB,EAAE,cAAc;KAC1C,CACF,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,QAAgB,EAChB,MAA+B,
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/enrollments/data/api.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACtG,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAI9C,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,QAAgB,EAChB,MAAyB,EACW,EAAE;IACtC,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,QAAQ,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IACvD,CAAC;IAED,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,WAAW,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CACrD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,gBAAgB,WAAW,CAAC,QAAQ,EAAE,EAAE,CACjG,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,QAAgB,EAChB,cAAsB,EACa,EAAE;IACrC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,IAAI,CACtD,GAAG,aAAa,EAAE,YAAY,QAAQ,+CAA+C,EAAE;QACrF,yBAAyB,EAAE,cAAc;KAC1C,CACF,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,QAAgB,EAChB,MAA+B,EACK,EAAE;IACtC,MAAM,eAAe,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,IAAI,CACtD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,qBAAqB,EAC7E,eAAe,CAChB,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,QAAgB,EAChB,MAA+B,EACK,EAAE;IACtC,MAAM,eAAe,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,IAAI,CACtD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,sBAAsB,EAC9E,eAAe,CAChB,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC","sourcesContent":["import { camelCaseObject, getAuthenticatedHttpClient, snakeCaseObject } from '@openedx/frontend-base';\nimport { getApiBaseUrl } from '@src/data/api';\nimport { EnrollmentsParams, EnrollmentStatusResponse, EnrolledLearner, UpdateEnrollmentsParams, UpdateBetaTestersParams, UpdateEnrollmentsResponse, UpdateBetaTestersResponse } from '@src/enrollments/types';\nimport { DataList } from '@src/types';\n\nexport const getEnrollments = async (\n courseId: string,\n params: EnrollmentsParams\n): Promise<DataList<EnrolledLearner>> => {\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('search', params.emailOrUsername);\n }\n\n if (params.isBetaTester) {\n queryParams.append('is_beta_tester', params.isBetaTester);\n }\n\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/enrollments?${queryParams.toString()}`\n );\n return camelCaseObject(data);\n};\n\nexport const getEnrollmentStatus = async (\n courseId: string,\n userIdentifier: string\n): Promise<EnrollmentStatusResponse> => {\n const { data } = await getAuthenticatedHttpClient().post(\n `${getApiBaseUrl()}/courses/${courseId}/instructor/api/get_student_enrollment_status`, {\n unique_student_identifier: userIdentifier,\n }\n );\n return camelCaseObject(data);\n};\n\nexport const updateEnrollments = async (\n courseId: string,\n params: UpdateEnrollmentsParams\n): Promise<UpdateEnrollmentsResponse> => {\n const snakeCaseParams = snakeCaseObject(params);\n const { data } = await getAuthenticatedHttpClient().post(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/enrollments/modify`,\n snakeCaseParams\n );\n return camelCaseObject(data);\n};\n\nexport const updateBetaTesters = async (\n courseId: string,\n params: UpdateBetaTestersParams\n): Promise<UpdateBetaTestersResponse> => {\n const snakeCaseParams = snakeCaseObject(params);\n const { data } = await getAuthenticatedHttpClient().post(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/beta_testers/modify`,\n snakeCaseParams\n );\n return camelCaseObject(data);\n};\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { EnrollmentsParams, UpdateEnrollmentsParams } from '../../enrollments/types';
|
|
1
|
+
import { EnrollmentsParams, UpdateBetaTestersParams, UpdateEnrollmentsParams } from '../../enrollments/types';
|
|
2
2
|
export declare const useEnrollments: (courseId: string, params: EnrollmentsParams) => import("@tanstack/react-query").UseQueryResult<import("../../types").DataList<import("../../enrollments/types").EnrolledLearner>, Error>;
|
|
3
3
|
export declare const useEnrollmentByUserId: (courseId: string, userIdentifier: string) => import("@tanstack/react-query").UseQueryResult<import("../../enrollments/types").EnrollmentStatusResponse, Error>;
|
|
4
|
-
export declare const useUpdateEnrollments: (courseId: string) => import("@tanstack/react-query").UseMutationResult<
|
|
4
|
+
export declare const useUpdateEnrollments: (courseId: string) => import("@tanstack/react-query").UseMutationResult<import("../../enrollments/types").UpdateEnrollmentsResponse, Error, UpdateEnrollmentsParams, unknown>;
|
|
5
|
+
export declare const useUpdateBetaTesters: (courseId: string) => import("@tanstack/react-query").UseMutationResult<import("../../enrollments/types").UpdateBetaTestersResponse, Error, UpdateBetaTestersParams, unknown>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
2
|
-
import { getEnrollments, getEnrollmentStatus, updateEnrollments } from '../../enrollments/data/api';
|
|
2
|
+
import { getEnrollments, getEnrollmentStatus, updateBetaTesters, updateEnrollments } from '../../enrollments/data/api';
|
|
3
3
|
import { enrollmentsQueryKeys } from '../../enrollments/data/queryKeys';
|
|
4
4
|
export const useEnrollments = (courseId, params) => (useQuery({
|
|
5
5
|
queryKey: enrollmentsQueryKeys.byCoursePaginated(courseId, params),
|
|
@@ -20,4 +20,13 @@ export const useUpdateEnrollments = (courseId) => {
|
|
|
20
20
|
},
|
|
21
21
|
}));
|
|
22
22
|
};
|
|
23
|
+
export const useUpdateBetaTesters = (courseId) => {
|
|
24
|
+
const queryClient = useQueryClient();
|
|
25
|
+
return (useMutation({
|
|
26
|
+
mutationFn: (params) => updateBetaTesters(courseId, params),
|
|
27
|
+
onSuccess: () => {
|
|
28
|
+
queryClient.invalidateQueries({ queryKey: enrollmentsQueryKeys.byCourse(courseId) });
|
|
29
|
+
},
|
|
30
|
+
}));
|
|
31
|
+
};
|
|
23
32
|
//# sourceMappingURL=apiHook.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiHook.js","sourceRoot":"","sources":["../../../src/enrollments/data/apiHook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"apiHook.js","sourceRoot":"","sources":["../../../src/enrollments/data/apiHook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACtH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAGvE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,QAAgB,EAAE,MAAyB,EAAE,EAAE,CAAC,CAC7E,QAAQ,CAAC;IACP,QAAQ,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC;IAClE,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,qBAAqB,GAAG,CAAC,QAAgB,EAAE,cAAsB,EAAE,EAAE,CAAC,CACjF,QAAQ,CAAC;IACP,QAAQ,EAAE,oBAAoB,CAAC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IACjE,OAAO,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,cAAc,CAAC;IAC5D,OAAO,EAAE,KAAK;CACf,CAAC,CACH,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,QAAgB,EAAE,EAAE;IACvD,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,CAAC,WAAW,CAAC;QAClB,UAAU,EAAE,CAAC,MAA+B,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC;QACpF,SAAS,EAAE,GAAG,EAAE;YACd,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,oBAAoB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACvF,CAAC;KACF,CAAC,CAAC,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,QAAgB,EAAE,EAAE;IACvD,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,CAAC,WAAW,CAAC;QAClB,UAAU,EAAE,CAAC,MAA+B,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC;QACpF,SAAS,EAAE,GAAG,EAAE;YACd,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,oBAAoB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACvF,CAAC;KACF,CAAC,CAAC,CAAC;AACN,CAAC,CAAC","sourcesContent":["import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { getEnrollments, getEnrollmentStatus, updateBetaTesters, updateEnrollments } from '@src/enrollments/data/api';\nimport { enrollmentsQueryKeys } from '@src/enrollments/data/queryKeys';\nimport { EnrollmentsParams, UpdateBetaTestersParams, UpdateEnrollmentsParams } from '@src/enrollments/types';\n\nexport const useEnrollments = (courseId: string, params: EnrollmentsParams) => (\n useQuery({\n queryKey: enrollmentsQueryKeys.byCoursePaginated(courseId, params),\n queryFn: () => getEnrollments(courseId, params),\n enabled: !!courseId,\n })\n);\n\nexport const useEnrollmentByUserId = (courseId: string, userIdentifier: string) => (\n useQuery({\n queryKey: enrollmentsQueryKeys.byUserId(courseId, userIdentifier),\n queryFn: () => getEnrollmentStatus(courseId, userIdentifier),\n enabled: false,\n })\n);\n\nexport const useUpdateEnrollments = (courseId: string) => {\n const queryClient = useQueryClient();\n return (useMutation({\n mutationFn: (params: UpdateEnrollmentsParams) => updateEnrollments(courseId, params),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: enrollmentsQueryKeys.byCourse(courseId) });\n },\n }));\n};\n\nexport const useUpdateBetaTesters = (courseId: string) => {\n const queryClient = useQueryClient();\n return (useMutation({\n mutationFn: (params: UpdateBetaTestersParams) => updateBetaTesters(courseId, params),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: enrollmentsQueryKeys.byCourse(courseId) });\n },\n }));\n};\n"]}
|
|
@@ -89,6 +89,16 @@ declare const messages: {
|
|
|
89
89
|
defaultMessage: string;
|
|
90
90
|
description: string;
|
|
91
91
|
};
|
|
92
|
+
grantBetaTester: {
|
|
93
|
+
id: string;
|
|
94
|
+
defaultMessage: string;
|
|
95
|
+
description: string;
|
|
96
|
+
};
|
|
97
|
+
revokeBetaTester: {
|
|
98
|
+
id: string;
|
|
99
|
+
defaultMessage: string;
|
|
100
|
+
description: string;
|
|
101
|
+
};
|
|
92
102
|
allEnrollees: {
|
|
93
103
|
id: string;
|
|
94
104
|
defaultMessage: string;
|
|
@@ -169,5 +179,50 @@ declare const messages: {
|
|
|
169
179
|
defaultMessage: string;
|
|
170
180
|
description: string;
|
|
171
181
|
};
|
|
182
|
+
addBetaTestersInstructions: {
|
|
183
|
+
id: string;
|
|
184
|
+
defaultMessage: string;
|
|
185
|
+
description: string;
|
|
186
|
+
};
|
|
187
|
+
failedEnrollLearners: {
|
|
188
|
+
id: string;
|
|
189
|
+
defaultMessage: string;
|
|
190
|
+
description: string;
|
|
191
|
+
};
|
|
192
|
+
unknownLearner: {
|
|
193
|
+
id: string;
|
|
194
|
+
defaultMessage: string;
|
|
195
|
+
description: string;
|
|
196
|
+
};
|
|
197
|
+
removeBetaTesterError: {
|
|
198
|
+
id: string;
|
|
199
|
+
defaultMessage: string;
|
|
200
|
+
description: string;
|
|
201
|
+
};
|
|
202
|
+
failedBetaTesters: {
|
|
203
|
+
id: string;
|
|
204
|
+
defaultMessage: string;
|
|
205
|
+
description: string;
|
|
206
|
+
};
|
|
207
|
+
addBetaTesterError: {
|
|
208
|
+
id: string;
|
|
209
|
+
defaultMessage: string;
|
|
210
|
+
description: string;
|
|
211
|
+
};
|
|
212
|
+
removeBetaTesterTitle: {
|
|
213
|
+
id: string;
|
|
214
|
+
defaultMessage: string;
|
|
215
|
+
description: string;
|
|
216
|
+
};
|
|
217
|
+
removeBetaTesterDescription: {
|
|
218
|
+
id: string;
|
|
219
|
+
defaultMessage: string;
|
|
220
|
+
description: string;
|
|
221
|
+
};
|
|
222
|
+
revoke: {
|
|
223
|
+
id: string;
|
|
224
|
+
defaultMessage: string;
|
|
225
|
+
description: string;
|
|
226
|
+
};
|
|
172
227
|
};
|
|
173
228
|
export default messages;
|
|
@@ -62,7 +62,7 @@ const messages = defineMessages({
|
|
|
62
62
|
},
|
|
63
63
|
addLearnerInstructions: {
|
|
64
64
|
id: 'instruct.enrollments.modals.checkEnrollmentStatus.addLearnerInstructions',
|
|
65
|
-
defaultMessage: '
|
|
65
|
+
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.',
|
|
66
66
|
description: 'Instructions for enroll learners to the course',
|
|
67
67
|
},
|
|
68
68
|
enrollmentStatusPlaceholder: {
|
|
@@ -90,6 +90,16 @@ const messages = defineMessages({
|
|
|
90
90
|
defaultMessage: 'Change Beta Tester Status',
|
|
91
91
|
description: 'Alt text for change beta tester status icon button',
|
|
92
92
|
},
|
|
93
|
+
grantBetaTester: {
|
|
94
|
+
id: 'instruct.enrollments.grantBetaTester',
|
|
95
|
+
defaultMessage: 'Grant Beta Tester Role',
|
|
96
|
+
description: 'Menu option to grant beta tester status',
|
|
97
|
+
},
|
|
98
|
+
revokeBetaTester: {
|
|
99
|
+
id: 'instruct.enrollments.revokeBetaTester',
|
|
100
|
+
defaultMessage: 'Remove Beta Tester Role',
|
|
101
|
+
description: 'Menu option to revoke beta tester status',
|
|
102
|
+
},
|
|
93
103
|
allEnrollees: {
|
|
94
104
|
id: 'instruct.enrollments.allEnrollees',
|
|
95
105
|
defaultMessage: 'All Enrollees',
|
|
@@ -169,6 +179,51 @@ const messages = defineMessages({
|
|
|
169
179
|
id: 'instruct.enrollments.modals.enrollLearnerNotFoundError',
|
|
170
180
|
defaultMessage: 'One or more learners were not found. Please check the email addresses or usernames and try again.',
|
|
171
181
|
description: 'Error message displayed when enrolling learners fails due to learner not found',
|
|
182
|
+
},
|
|
183
|
+
addBetaTestersInstructions: {
|
|
184
|
+
id: 'instruct.enrollments.modals.addBetaTesters.addBetaTestersInstructions',
|
|
185
|
+
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.',
|
|
186
|
+
description: 'Instructions for adding beta testers to the course',
|
|
187
|
+
},
|
|
188
|
+
failedEnrollLearners: {
|
|
189
|
+
id: 'instruct.enrollments.modals.enrollLearners.failedEnrollLearners',
|
|
190
|
+
defaultMessage: 'The following usernames and/or email addresses are invalid. All other learners have been enrolled.',
|
|
191
|
+
description: 'Message displaying the learners that could not be enrolled',
|
|
192
|
+
},
|
|
193
|
+
unknownLearner: {
|
|
194
|
+
id: 'instruct.enrollments.unknownLearner',
|
|
195
|
+
defaultMessage: 'Unknown learner: {learner}',
|
|
196
|
+
description: 'Displayed when a learner does not have a full name or username available',
|
|
197
|
+
},
|
|
198
|
+
removeBetaTesterError: {
|
|
199
|
+
id: 'instruct.enrollments.modals.removeBetaTesters.removeBetaTesterError',
|
|
200
|
+
defaultMessage: 'Error removing user as beta tester.',
|
|
201
|
+
description: 'Error message displayed when removing beta testers fails',
|
|
202
|
+
},
|
|
203
|
+
failedBetaTesters: {
|
|
204
|
+
id: 'instruct.enrollments.modals.addBetaTesters.failedBetaTesters',
|
|
205
|
+
defaultMessage: 'The following usernames and/or email addresses are invalid. All other beta testers have been added.',
|
|
206
|
+
description: 'Message displaying the learners that could not be added as beta testers',
|
|
207
|
+
},
|
|
208
|
+
addBetaTesterError: {
|
|
209
|
+
id: 'instruct.enrollments.modals.addBetaTesters.addBetaTesterError',
|
|
210
|
+
defaultMessage: 'Error adding users as beta testers.',
|
|
211
|
+
description: 'Error message displayed when adding beta testers fails',
|
|
212
|
+
},
|
|
213
|
+
removeBetaTesterTitle: {
|
|
214
|
+
id: 'instruct.enrollments.modals.removeBetaTester',
|
|
215
|
+
defaultMessage: 'Revoke access?',
|
|
216
|
+
description: 'Title for remove beta tester modal',
|
|
217
|
+
},
|
|
218
|
+
removeBetaTesterDescription: {
|
|
219
|
+
id: 'instruct.enrollments.modals.removeBetaTesterDescription',
|
|
220
|
+
defaultMessage: 'Revoke Beta Tester access?',
|
|
221
|
+
description: 'Description for remove beta tester modal',
|
|
222
|
+
},
|
|
223
|
+
revoke: {
|
|
224
|
+
id: 'instruct.enrollments.revoke',
|
|
225
|
+
defaultMessage: 'Revoke',
|
|
226
|
+
description: 'Button label for revoking access',
|
|
172
227
|
}
|
|
173
228
|
});
|
|
174
229
|
export default messages;
|
|
@@ -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: 'Learner\\'s My Open edX email address or username',\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 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});\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 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"]}
|
|
@@ -16,3 +16,21 @@ export interface UpdateEnrollmentsParams {
|
|
|
16
16
|
autoEnroll?: boolean;
|
|
17
17
|
emailStudents?: boolean;
|
|
18
18
|
}
|
|
19
|
+
export interface UpdateBetaTestersParams {
|
|
20
|
+
identifier: string[];
|
|
21
|
+
action: 'add' | 'remove';
|
|
22
|
+
autoEnroll?: boolean;
|
|
23
|
+
emailStudents?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface UpdateEnrollmentsResponse {
|
|
26
|
+
results: {
|
|
27
|
+
identifier: string;
|
|
28
|
+
invalidIdentifier: boolean;
|
|
29
|
+
}[];
|
|
30
|
+
}
|
|
31
|
+
export interface UpdateBetaTestersResponse {
|
|
32
|
+
results: {
|
|
33
|
+
identifier: string;
|
|
34
|
+
userDoesNotExist: boolean;
|
|
35
|
+
}[];
|
|
36
|
+
}
|
|
@@ -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"]}
|
|
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"]}
|