@openedx/frontend-app-instructor-dashboard 1.0.0-alpha.0 → 1.0.0-alpha.10
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/Main.js +3 -6
- package/dist/Main.js.map +1 -1
- package/dist/app.js +2 -8
- package/dist/app.js.map +1 -1
- package/dist/app.scss +4 -0
- package/dist/cohorts/CohortsPage.js +1 -1
- package/dist/cohorts/CohortsPage.js.map +1 -1
- package/dist/cohorts/data/queryKeys.d.ts +4 -4
- package/dist/components/SpecifyLearnerField.d.ts +4 -2
- package/dist/components/SpecifyLearnerField.js +38 -4
- package/dist/components/SpecifyLearnerField.js.map +1 -1
- package/dist/components/SpecifyProblem.d.ts +2 -0
- package/dist/components/SpecifyProblem.js +6 -0
- package/dist/components/SpecifyProblem.js.map +1 -0
- package/dist/components/UsernameFilter.d.ts +7 -0
- package/dist/components/UsernameFilter.js +19 -0
- package/dist/components/UsernameFilter.js.map +1 -0
- package/dist/components/messages.d.ts +15 -0
- package/dist/components/messages.js +15 -0
- package/dist/components/messages.js.map +1 -1
- package/dist/constants.d.ts +2 -1
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/courseInfo/types.d.ts +7 -0
- package/dist/courseInfo/types.js.map +1 -1
- package/dist/courseTeam/CourseTeamPage.js +9 -2
- package/dist/courseTeam/CourseTeamPage.js.map +1 -1
- package/dist/courseTeam/components/MembersContent.d.ts +2 -0
- package/dist/courseTeam/components/MembersContent.js +60 -0
- package/dist/courseTeam/components/MembersContent.js.map +1 -0
- package/dist/courseTeam/components/RolesContent.d.ts +3 -0
- package/dist/courseTeam/components/RolesContent.js +25 -0
- package/dist/courseTeam/components/RolesContent.js.map +1 -0
- package/dist/courseTeam/data/api.d.ts +4 -0
- package/dist/courseTeam/data/api.js +30 -0
- package/dist/courseTeam/data/api.js.map +1 -0
- package/dist/courseTeam/data/apiHook.d.ts +3 -0
- package/dist/courseTeam/data/apiHook.js +14 -0
- package/dist/courseTeam/data/apiHook.js.map +1 -0
- package/dist/courseTeam/data/queryKeys.d.ts +7 -0
- package/dist/courseTeam/data/queryKeys.js +14 -0
- package/dist/courseTeam/data/queryKeys.js.map +1 -0
- package/dist/courseTeam/messages.d.ts +158 -0
- package/dist/courseTeam/messages.js +160 -0
- package/dist/courseTeam/messages.js.map +1 -0
- package/dist/courseTeam/types.d.ts +15 -0
- package/dist/courseTeam/types.js +2 -0
- package/dist/courseTeam/types.js.map +1 -0
- package/dist/data/api.d.ts +9 -1
- package/dist/data/api.js +13 -3
- package/dist/data/api.js.map +1 -1
- package/dist/data/apiHook.d.ts +1 -0
- package/dist/data/apiHook.js +10 -2
- package/dist/data/apiHook.js.map +1 -1
- package/dist/data/queryKeys.d.ts +8 -4
- package/dist/data/queryKeys.js +4 -0
- package/dist/data/queryKeys.js.map +1 -1
- package/dist/dataDownloads/data/queryKeys.d.ts +3 -3
- package/dist/dateExtensions/components/AddExtensionModal.d.ts +2 -6
- package/dist/dateExtensions/components/AddExtensionModal.js +22 -8
- package/dist/dateExtensions/components/AddExtensionModal.js.map +1 -1
- package/dist/dateExtensions/components/DateExtensionsList.js +2 -13
- package/dist/dateExtensions/components/DateExtensionsList.js.map +1 -1
- package/dist/dateExtensions/data/queryKeys.d.ts +5 -5
- package/dist/dateExtensions/messages.d.ts +0 -5
- package/dist/dateExtensions/messages.js +0 -5
- package/dist/dateExtensions/messages.js.map +1 -1
- package/dist/dateExtensions/types.d.ts +6 -2
- package/dist/dateExtensions/types.js.map +1 -1
- package/dist/enrollments/EnrollmentsPage.js +13 -5
- package/dist/enrollments/EnrollmentsPage.js.map +1 -1
- package/dist/enrollments/components/EnrollLearnersModal.d.ts +7 -0
- package/dist/enrollments/components/EnrollLearnersModal.js +44 -0
- package/dist/enrollments/components/EnrollLearnersModal.js.map +1 -0
- package/dist/enrollments/components/EnrollmentStatusModal.js +3 -3
- package/dist/enrollments/components/EnrollmentStatusModal.js.map +1 -1
- package/dist/enrollments/components/EnrollmentsList.d.ts +2 -2
- package/dist/enrollments/components/EnrollmentsList.js +5 -5
- package/dist/enrollments/components/EnrollmentsList.js.map +1 -1
- package/dist/enrollments/components/UnenrollModal.d.ts +4 -3
- package/dist/enrollments/components/UnenrollModal.js +31 -4
- package/dist/enrollments/components/UnenrollModal.js.map +1 -1
- package/dist/enrollments/data/api.d.ts +3 -2
- package/dist/enrollments/data/api.js +5 -1
- package/dist/enrollments/data/api.js.map +1 -1
- package/dist/enrollments/data/apiHook.d.ts +4 -3
- package/dist/enrollments/data/apiHook.js +12 -3
- package/dist/enrollments/data/apiHook.js.map +1 -1
- package/dist/enrollments/data/queryKeys.d.ts +5 -5
- package/dist/enrollments/data/queryKeys.js.map +1 -1
- package/dist/enrollments/messages.d.ts +66 -1
- package/dist/enrollments/messages.js +71 -6
- package/dist/enrollments/messages.js.map +1 -1
- package/dist/enrollments/types.d.ts +8 -5
- package/dist/enrollments/types.js.map +1 -1
- package/dist/grading/GradingPage.js +11 -2
- package/dist/grading/GradingPage.js.map +1 -1
- package/dist/grading/components/GradingActionRow.d.ts +2 -0
- package/dist/grading/components/GradingActionRow.js +28 -0
- package/dist/grading/components/GradingActionRow.js.map +1 -0
- package/dist/grading/components/GradingConfigurationModal.d.ts +6 -0
- package/dist/grading/components/GradingConfigurationModal.js +14 -0
- package/dist/grading/components/GradingConfigurationModal.js.map +1 -0
- package/dist/grading/components/GradingLearnerContent.d.ts +6 -0
- package/dist/grading/components/GradingLearnerContent.js +12 -0
- package/dist/grading/components/GradingLearnerContent.js.map +1 -0
- package/dist/grading/data/api.d.ts +1 -0
- package/dist/grading/data/api.js +17 -0
- package/dist/grading/data/api.js.map +1 -0
- package/dist/grading/data/apiHook.d.ts +1 -0
- package/dist/grading/data/apiHook.js +9 -0
- package/dist/grading/data/apiHook.js.map +1 -0
- package/dist/grading/data/queryKeys.d.ts +5 -0
- package/dist/grading/data/queryKeys.js +7 -0
- package/dist/grading/data/queryKeys.js.map +1 -0
- package/dist/grading/messages.d.ts +63 -0
- package/dist/grading/messages.js +65 -0
- package/dist/grading/messages.js.map +1 -0
- package/dist/grading/types.d.ts +1 -0
- package/dist/grading/types.js +2 -0
- package/dist/grading/types.js.map +1 -0
- package/dist/i18n/index.d.ts +1 -25
- package/dist/i18n/index.js +1 -25
- package/dist/i18n/index.js.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/instructorNav/InstructorNav.js +1 -1
- package/dist/instructorNav/InstructorNav.js.map +1 -1
- package/dist/provides.d.ts +4 -0
- package/dist/provides.js +7 -0
- package/dist/provides.js.map +1 -0
- package/dist/routes.d.ts +1 -1
- package/dist/routes.js +4 -3
- package/dist/routes.js.map +1 -1
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/package.json +8 -2
- package/dist/providers/QueryProvider.d.ts +0 -6
- package/dist/providers/QueryProvider.js +0 -16
- package/dist/providers/QueryProvider.js.map +0 -1
- package/dist/providers.d.ts +0 -3
- package/dist/providers.js +0 -8
- package/dist/providers.js.map +0 -1
|
@@ -5,15 +5,25 @@ import { useIntl } from '@openedx/frontend-base';
|
|
|
5
5
|
import SpecifyLearnerField from '../../components/SpecifyLearnerField';
|
|
6
6
|
import messages from '../messages';
|
|
7
7
|
import SelectGradedSubsection from './SelectGradedSubsection';
|
|
8
|
+
const initialFormData = {
|
|
9
|
+
emailOrUsername: '',
|
|
10
|
+
blockId: '',
|
|
11
|
+
dueDate: '',
|
|
12
|
+
dueTime: '',
|
|
13
|
+
reason: '',
|
|
14
|
+
};
|
|
8
15
|
const AddExtensionModal = ({ isOpen, title, onClose, onSubmit }) => {
|
|
9
16
|
const intl = useIntl();
|
|
10
|
-
const [formData, setFormData] = useState(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
+
const [formData, setFormData] = useState(initialFormData);
|
|
18
|
+
const isFormFilled = (formData) => {
|
|
19
|
+
return (formData.emailOrUsername.trim() !== ''
|
|
20
|
+
&& formData.blockId.trim() !== ''
|
|
21
|
+
&& formData.dueDate.trim() !== ''
|
|
22
|
+
&& formData.dueTime.trim() !== '');
|
|
23
|
+
};
|
|
24
|
+
const resetForm = () => {
|
|
25
|
+
setFormData(initialFormData);
|
|
26
|
+
};
|
|
17
27
|
const handleSubmit = (event) => {
|
|
18
28
|
event.preventDefault();
|
|
19
29
|
const { emailOrUsername, blockId, dueDate, dueTime, reason } = formData;
|
|
@@ -24,11 +34,15 @@ const AddExtensionModal = ({ isOpen, title, onClose, onSubmit }) => {
|
|
|
24
34
|
reason
|
|
25
35
|
});
|
|
26
36
|
};
|
|
37
|
+
const handleCancel = () => {
|
|
38
|
+
resetForm();
|
|
39
|
+
onClose();
|
|
40
|
+
};
|
|
27
41
|
const onChange = (event) => {
|
|
28
42
|
const { name, value } = event.target;
|
|
29
43
|
setFormData((prevData) => (Object.assign(Object.assign({}, prevData), { [name]: value })));
|
|
30
44
|
};
|
|
31
|
-
return (_jsxs(ModalDialog, { isOpen: isOpen, onClose: onClose, title: title, isOverflowVisible: false, size: "xl", children: [_jsx(ModalDialog.Header, { className: "p-3 pl-4 border-bottom", children: _jsx(ModalDialog.Title, { as: "h3", className: "m-0", children: title }) }), _jsxs(Form, { onSubmit: handleSubmit, className: "position-relative overflow-auto", children: [_jsx(ModalDialog.Body, { children: _jsxs("div", { className: "pt-3", children: [_jsx("p", { children: intl.formatMessage(messages.extensionInstructions) }), _jsx("div", { className: "container-fluid border-bottom mb-4.5 pb-3", children: _jsxs("div", { className: "row", children: [_jsx("div", { className: "col-sm-12 col-md-6", children: _jsx(SpecifyLearnerField, {
|
|
45
|
+
return (_jsxs(ModalDialog, { isOpen: isOpen, onClose: onClose, title: title, isOverflowVisible: false, size: "xl", children: [_jsx(ModalDialog.Header, { className: "p-3 pl-4 border-bottom", children: _jsx(ModalDialog.Title, { as: "h3", className: "m-0", children: title }) }), _jsxs(Form, { onSubmit: handleSubmit, className: "position-relative overflow-auto", children: [_jsx(ModalDialog.Body, { children: _jsxs("div", { className: "pt-3", children: [_jsx("p", { children: intl.formatMessage(messages.extensionInstructions) }), _jsx("div", { className: "container-fluid border-bottom mb-4.5 pb-3", children: _jsxs("div", { className: "row", children: [_jsx("div", { className: "col-sm-12 col-md-6", children: _jsx(SpecifyLearnerField, { onClickSelect: (emailOrUsername) => setFormData((prevData) => (Object.assign(Object.assign({}, prevData), { emailOrUsername }))) }) }), _jsx("div", { className: "col-sm-12 col-md-4", children: _jsx(SelectGradedSubsection, { label: intl.formatMessage(messages.selectGradedSubsection), placeholder: intl.formatMessage(messages.selectGradedSubsection), onChange: onChange }) })] }) }), _jsxs("div", { children: [_jsx("h4", { children: intl.formatMessage(messages.defineExtension) }), _jsxs(FormGroup, { size: "sm", children: [_jsxs(FormLabel, { children: [intl.formatMessage(messages.extensionDate), ":"] }), _jsxs("div", { className: "d-md-flex w-md-50 align-items-center", children: [_jsx(FormControl, { name: "dueDate", type: "date", size: "md", onChange: onChange }), _jsx(FormControl, { name: "dueTime", type: "time", size: "md", className: "mt-sm-3 mt-md-0", onChange: onChange })] })] }), _jsxs(FormGroup, { className: "mt-3", size: "sm", children: [_jsxs(FormLabel, { children: [intl.formatMessage(messages.reasonForExtension), ":"] }), _jsx(FormControl, { name: "reason", placeholder: intl.formatMessage(messages.reasonForExtension), size: "md", onChange: onChange })] })] })] }) }), _jsx(ModalDialog.Footer, { className: "p-4 border-top", children: _jsxs(ActionRow, { children: [_jsx(Button, { variant: "tertiary", onClick: handleCancel, children: intl.formatMessage(messages.cancel) }), _jsx(Button, { type: "submit", disabled: !isFormFilled(formData), children: intl.formatMessage(messages.addExtension) })] }) })] })] }));
|
|
32
46
|
};
|
|
33
47
|
export default AddExtensionModal;
|
|
34
48
|
//# sourceMappingURL=AddExtensionModal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AddExtensionModal.js","sourceRoot":"","sources":["../../../src/dateExtensions/components/AddExtensionModal.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC3G,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,mBAAmB,MAAM,
|
|
1
|
+
{"version":3,"file":"AddExtensionModal.js","sourceRoot":"","sources":["../../../src/dateExtensions/components/AddExtensionModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from 'react';\nimport { ActionRow, Button, Form, FormControl, FormGroup, FormLabel, ModalDialog } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport SpecifyLearnerField from '@src/components/SpecifyLearnerField';\nimport messages from '../messages';\nimport SelectGradedSubsection from './SelectGradedSubsection';\nimport { AddDateExtensionFormData, AddDateExtensionParams } from '../types';\n\ninterface AddExtensionModalProps {\n isOpen: boolean,\n title: string,\n onClose: () => void,\n onSubmit: ({ emailOrUsername, blockId, dueDatetime, reason }: AddDateExtensionParams) => void,\n}\n\nconst initialFormData: AddDateExtensionFormData = {\n emailOrUsername: '',\n blockId: '',\n dueDate: '',\n dueTime: '',\n reason: '',\n};\n\nconst AddExtensionModal = ({ isOpen, title, onClose, onSubmit }: AddExtensionModalProps) => {\n const intl = useIntl();\n const [formData, setFormData] = useState(initialFormData);\n\n const isFormFilled = (formData: AddDateExtensionFormData) => {\n return (\n formData.emailOrUsername.trim() !== ''\n && formData.blockId.trim() !== ''\n && formData.dueDate.trim() !== ''\n && formData.dueTime.trim() !== ''\n );\n };\n\n const resetForm = () => {\n setFormData(initialFormData);\n };\n\n const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const { emailOrUsername, blockId, dueDate, dueTime, reason } = formData;\n onSubmit({\n emailOrUsername,\n blockId,\n dueDatetime: new Date(`${dueDate}T${dueTime}`).toISOString(),\n reason\n });\n };\n\n const handleCancel = () => {\n resetForm();\n onClose();\n };\n\n const onChange = (event: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {\n const { name, value } = event.target;\n setFormData((prevData) => ({\n ...prevData,\n [name]: value,\n }));\n };\n\n return (\n <ModalDialog isOpen={isOpen} onClose={onClose} title={title} isOverflowVisible={false} size=\"xl\">\n <ModalDialog.Header className=\"p-3 pl-4 border-bottom\">\n <ModalDialog.Title as=\"h3\" className=\"m-0\">\n {title}\n </ModalDialog.Title>\n </ModalDialog.Header>\n <Form onSubmit={handleSubmit} className=\"position-relative overflow-auto\">\n <ModalDialog.Body>\n <div className=\"pt-3\">\n <p>{intl.formatMessage(messages.extensionInstructions)}</p>\n <div className=\"container-fluid border-bottom mb-4.5 pb-3\">\n <div className=\"row\">\n <div className=\"col-sm-12 col-md-6\">\n <SpecifyLearnerField onClickSelect={(emailOrUsername) => setFormData((prevData) => ({ ...prevData, emailOrUsername }))} />\n </div>\n <div className=\"col-sm-12 col-md-4\">\n <SelectGradedSubsection\n label={intl.formatMessage(messages.selectGradedSubsection)}\n placeholder={intl.formatMessage(messages.selectGradedSubsection)}\n onChange={onChange}\n />\n </div>\n </div>\n </div>\n <div>\n <h4>{intl.formatMessage(messages.defineExtension)}</h4>\n <FormGroup size=\"sm\">\n <FormLabel>\n {intl.formatMessage(messages.extensionDate)}:\n </FormLabel>\n <div className=\"d-md-flex w-md-50 align-items-center\">\n <FormControl name=\"dueDate\" type=\"date\" size=\"md\" onChange={onChange} />\n <FormControl name=\"dueTime\" type=\"time\" size=\"md\" className=\"mt-sm-3 mt-md-0\" onChange={onChange} />\n </div>\n </FormGroup>\n <FormGroup className=\"mt-3\" size=\"sm\">\n <FormLabel>\n {intl.formatMessage(messages.reasonForExtension)}:\n </FormLabel>\n <FormControl name=\"reason\" placeholder={intl.formatMessage(messages.reasonForExtension)} size=\"md\" onChange={onChange} />\n </FormGroup>\n </div>\n </div>\n </ModalDialog.Body>\n <ModalDialog.Footer className=\"p-4 border-top\">\n <ActionRow>\n <Button variant=\"tertiary\" onClick={handleCancel}>{intl.formatMessage(messages.cancel)}</Button>\n <Button type=\"submit\" disabled={!isFormFilled(formData)}>\n {intl.formatMessage(messages.addExtension)}\n </Button>\n </ActionRow>\n </ModalDialog.Footer>\n </Form>\n </ModalDialog>\n );\n};\n\nexport default AddExtensionModal;\n"]}
|
|
@@ -2,24 +2,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { useParams } from 'react-router-dom';
|
|
4
4
|
import { useIntl } from '@openedx/frontend-base';
|
|
5
|
-
import { Button, DataTable
|
|
5
|
+
import { Button, DataTable } from '@openedx/paragon';
|
|
6
6
|
import messages from '../messages';
|
|
7
7
|
import { useDateExtensions } from '../data/apiHook';
|
|
8
|
-
import { Search } from '@openedx/paragon/icons';
|
|
9
8
|
import SelectGradedSubsection from './SelectGradedSubsection';
|
|
10
9
|
import { useDebouncedFilter } from '../../hooks/useDebouncedFilter';
|
|
10
|
+
import UsernameFilter from '../../components/UsernameFilter';
|
|
11
11
|
const DATE_EXTENSIONS_PAGE_SIZE = 25;
|
|
12
|
-
const UsernameFilter = ({ column: { filterValue, setFilter } }) => {
|
|
13
|
-
const intl = useIntl();
|
|
14
|
-
const { inputValue, handleChange } = useDebouncedFilter({
|
|
15
|
-
filterValue,
|
|
16
|
-
setFilter,
|
|
17
|
-
});
|
|
18
|
-
const handleInputChange = (e) => {
|
|
19
|
-
handleChange(e.target.value);
|
|
20
|
-
};
|
|
21
|
-
return (_jsx(FormControl, { className: "mb-0", onChange: handleInputChange, placeholder: intl.formatMessage(messages.searchLearnerPlaceholder), trailingElement: _jsx(Icon, { src: Search }), value: inputValue }));
|
|
22
|
-
};
|
|
23
12
|
const GradedSubsectionFilter = ({ column: { filterValue, setFilter } }) => {
|
|
24
13
|
const intl = useIntl();
|
|
25
14
|
const { inputValue, handleChange } = useDebouncedFilter({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateExtensionsList.js","sourceRoot":"","sources":["../../../src/dateExtensions/components/DateExtensionsList.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, DataTable, FormControl, Icon } from '@openedx/paragon';\nimport messages from '../messages';\nimport { LearnerDateExtension } from '../types';\nimport { useDateExtensions } from '../data/apiHook';\nimport { Search } from '@openedx/paragon/icons';\nimport SelectGradedSubsection from './SelectGradedSubsection';\nimport { useDebouncedFilter } from '../../hooks/useDebouncedFilter';\nimport { DataTableFetchDataProps } from '@src/types';\n\nconst DATE_EXTENSIONS_PAGE_SIZE = 25;\n\nexport interface DateExtensionListProps {\n onResetExtensions?: (user: LearnerDateExtension) => void,\n onClickAdd?: () => 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.searchLearnerPlaceholder)}\n trailingElement={<Icon src={Search} />}\n value={inputValue}\n />\n );\n};\n\nconst GradedSubsectionFilter = ({ 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 handleSelectChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n handleChange(e.target.value);\n };\n\n return (\n <SelectGradedSubsection\n placeholder={intl.formatMessage(messages.allGradedSubsections)}\n onChange={handleSelectChange}\n value={inputValue}\n />\n );\n};\n\nconst DateExtensionsList = ({\n onResetExtensions = () => {},\n onClickAdd = () => {},\n}: DateExtensionListProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [filters, setFilters] = useState<{ page: number, emailOrUsername: string, blockId: string }>({\n page: 0,\n emailOrUsername: '',\n blockId: '',\n });\n\n const { data = { count: 0, results: [], numPages: 0 }, isLoading } = useDateExtensions(courseId ?? '', {\n blockId: filters.blockId,\n emailOrUsername: filters.emailOrUsername,\n page: filters.page,\n pageSize: DATE_EXTENSIONS_PAGE_SIZE,\n });\n\n const tableColumns = [\n { accessor: 'username',\n Header: intl.formatMessage(messages.username),\n Filter: UsernameFilter,\n },\n { accessor: 'fullName', Header: intl.formatMessage(messages.fullname), disableFilters: true, },\n { accessor: 'email', Header: intl.formatMessage(messages.email), disableFilters: true, },\n { accessor: 'unitTitle',\n Header: intl.formatMessage(messages.gradedSubsection),\n Filter: GradedSubsectionFilter,\n },\n {\n accessor: 'extendedDueDate',\n Header: intl.formatMessage(messages.extendedDueDate),\n Cell: ({ value }: { value: string }) => (\n intl.formatDate(value, { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', timeZone: 'UTC' })\n ),\n disableFilters: true,\n },\n ];\n\n const additionalColumns = [{\n id: 'reset',\n Header: intl.formatMessage(messages.reset),\n Cell: ({ row }: { row: { original: LearnerDateExtension } }) => (\n <Button\n variant=\"link\"\n size=\"inline\"\n onClick={() => onResetExtensions(row.original)}\n >\n {intl.formatMessage(messages.resetExtensions)}\n </Button>\n )\n }];\n\n const handleFetchData = (data: DataTableFetchDataProps) => {\n const emailOrUsernameFilter = data.filters.find((filter) => filter.id === 'username');\n const newEmailOrUsername = emailOrUsernameFilter ? emailOrUsernameFilter.value : '';\n const blockIdFilter = data.filters.find((filter) => filter.id === 'unitTitle');\n const newBlockId = blockIdFilter ? blockIdFilter.value : '';\n\n const filterChanged = newEmailOrUsername !== filters.emailOrUsername || newBlockId !== filters.blockId;\n const pageChanged = data.pageIndex !== filters.page;\n\n // If filters changed, reset to page 0\n if (filterChanged) {\n setFilters({ page: 0, emailOrUsername: newEmailOrUsername, blockId: newBlockId });\n } else if (pageChanged) {\n // If only page changed (filters didn't change), update page\n setFilters({ page: data.pageIndex, emailOrUsername: newEmailOrUsername, blockId: newBlockId });\n }\n };\n\n return (\n <DataTable\n columns={tableColumns}\n additionalColumns={additionalColumns}\n data={data.results}\n fetchData={handleFetchData}\n state={{\n pageIndex: filters.page,\n pageSize: DATE_EXTENSIONS_PAGE_SIZE,\n filters: [\n {\n id: 'username',\n value: filters.emailOrUsername,\n },\n {\n id: 'unitTitle',\n value: filters.blockId,\n }\n ]\n }}\n isFilterable\n numBreakoutFilters={2}\n isLoading={isLoading}\n isPaginated\n itemCount={data.count}\n manualFilters\n manualPagination\n pageSize={DATE_EXTENSIONS_PAGE_SIZE}\n pageCount={data.numPages}\n FilterStatusComponent={DataTable.RowStatus}\n >\n <div className=\"d-flex justify-content-between align-items-start pt-1 mx-3 mb-3\">\n <DataTable.TableControlBar />\n <Button className=\"mt-2.5\" onClick={onClickAdd}>+ {intl.formatMessage(messages.addIndividualExtension)}</Button>\n </div>\n <DataTable.Table />\n <DataTable.EmptyTable content={intl.formatMessage(messages.noDateExtensions)} />\n <DataTable.TableFooter />\n </DataTable>\n );\n};\n\nexport default DateExtensionsList;\n"]}
|
|
1
|
+
{"version":3,"file":"DateExtensionsList.js","sourceRoot":"","sources":["../../../src/dateExtensions/components/DateExtensionsList.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, DataTable } from '@openedx/paragon';\nimport messages from '../messages';\nimport { LearnerDateExtension } from '../types';\nimport { useDateExtensions } from '../data/apiHook';\nimport SelectGradedSubsection from './SelectGradedSubsection';\nimport { useDebouncedFilter } from '../../hooks/useDebouncedFilter';\nimport { DataTableFetchDataProps } from '@src/types';\nimport UsernameFilter from '@src/components/UsernameFilter';\n\nconst DATE_EXTENSIONS_PAGE_SIZE = 25;\n\nexport interface DateExtensionListProps {\n onResetExtensions?: (user: LearnerDateExtension) => void,\n onClickAdd?: () => void,\n}\n\nconst GradedSubsectionFilter = ({ 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 handleSelectChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n handleChange(e.target.value);\n };\n\n return (\n <SelectGradedSubsection\n placeholder={intl.formatMessage(messages.allGradedSubsections)}\n onChange={handleSelectChange}\n value={inputValue}\n />\n );\n};\n\nconst DateExtensionsList = ({\n onResetExtensions = () => {},\n onClickAdd = () => {},\n}: DateExtensionListProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [filters, setFilters] = useState<{ page: number, emailOrUsername: string, blockId: string }>({\n page: 0,\n emailOrUsername: '',\n blockId: '',\n });\n\n const { data = { count: 0, results: [], numPages: 0 }, isLoading } = useDateExtensions(courseId ?? '', {\n blockId: filters.blockId,\n emailOrUsername: filters.emailOrUsername,\n page: filters.page,\n pageSize: DATE_EXTENSIONS_PAGE_SIZE,\n });\n\n const tableColumns = [\n { accessor: 'username',\n Header: intl.formatMessage(messages.username),\n Filter: UsernameFilter,\n },\n { accessor: 'fullName', Header: intl.formatMessage(messages.fullname), disableFilters: true, },\n { accessor: 'email', Header: intl.formatMessage(messages.email), disableFilters: true, },\n { accessor: 'unitTitle',\n Header: intl.formatMessage(messages.gradedSubsection),\n Filter: GradedSubsectionFilter,\n },\n {\n accessor: 'extendedDueDate',\n Header: intl.formatMessage(messages.extendedDueDate),\n Cell: ({ value }: { value: string }) => (\n intl.formatDate(value, { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', timeZone: 'UTC' })\n ),\n disableFilters: true,\n },\n ];\n\n const additionalColumns = [{\n id: 'reset',\n Header: intl.formatMessage(messages.reset),\n Cell: ({ row }: { row: { original: LearnerDateExtension } }) => (\n <Button\n variant=\"link\"\n size=\"inline\"\n onClick={() => onResetExtensions(row.original)}\n >\n {intl.formatMessage(messages.resetExtensions)}\n </Button>\n )\n }];\n\n const handleFetchData = (data: DataTableFetchDataProps) => {\n const emailOrUsernameFilter = data.filters.find((filter) => filter.id === 'username');\n const newEmailOrUsername = emailOrUsernameFilter ? emailOrUsernameFilter.value : '';\n const blockIdFilter = data.filters.find((filter) => filter.id === 'unitTitle');\n const newBlockId = blockIdFilter ? blockIdFilter.value : '';\n\n const filterChanged = newEmailOrUsername !== filters.emailOrUsername || newBlockId !== filters.blockId;\n const pageChanged = data.pageIndex !== filters.page;\n\n // If filters changed, reset to page 0\n if (filterChanged) {\n setFilters({ page: 0, emailOrUsername: newEmailOrUsername, blockId: newBlockId });\n } else if (pageChanged) {\n // If only page changed (filters didn't change), update page\n setFilters({ page: data.pageIndex, emailOrUsername: newEmailOrUsername, blockId: newBlockId });\n }\n };\n\n return (\n <DataTable\n columns={tableColumns}\n additionalColumns={additionalColumns}\n data={data.results}\n fetchData={handleFetchData}\n state={{\n pageIndex: filters.page,\n pageSize: DATE_EXTENSIONS_PAGE_SIZE,\n filters: [\n {\n id: 'username',\n value: filters.emailOrUsername,\n },\n {\n id: 'unitTitle',\n value: filters.blockId,\n }\n ]\n }}\n isFilterable\n numBreakoutFilters={2}\n isLoading={isLoading}\n isPaginated\n itemCount={data.count}\n manualFilters\n manualPagination\n pageSize={DATE_EXTENSIONS_PAGE_SIZE}\n pageCount={data.numPages}\n FilterStatusComponent={DataTable.RowStatus}\n >\n <div className=\"d-flex justify-content-between align-items-start pt-1 mx-3 mb-3\">\n <DataTable.TableControlBar />\n <Button className=\"mt-2.5\" onClick={onClickAdd}>+ {intl.formatMessage(messages.addIndividualExtension)}</Button>\n </div>\n <DataTable.Table />\n <DataTable.EmptyTable content={intl.formatMessage(messages.noDateExtensions)} />\n <DataTable.TableFooter />\n </DataTable>\n );\n};\n\nexport default DateExtensionsList;\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { DateExtensionQueryParams } from '../types';
|
|
2
2
|
export declare const dateExtensionsQueryKeys: {
|
|
3
|
-
all: readonly ["org.openedx.frontend.app.
|
|
4
|
-
byCourse: (courseId: string) => readonly ["org.openedx.frontend.app.
|
|
5
|
-
byCoursePaginated: (courseId: string, params: DateExtensionQueryParams) => readonly ["org.openedx.frontend.app.
|
|
3
|
+
all: readonly ["org.openedx.frontend.app.instructorDashboard", "dateExtensions"];
|
|
4
|
+
byCourse: (courseId: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "dateExtensions", string];
|
|
5
|
+
byCoursePaginated: (courseId: string, params: DateExtensionQueryParams) => readonly ["org.openedx.frontend.app.instructorDashboard", "dateExtensions", string, number, number, string, string];
|
|
6
6
|
};
|
|
7
7
|
export declare const gradedSubsectionsQueryKeys: {
|
|
8
|
-
all: readonly ["org.openedx.frontend.app.
|
|
9
|
-
byCourse: (courseId: string) => readonly ["org.openedx.frontend.app.
|
|
8
|
+
all: readonly ["org.openedx.frontend.app.instructorDashboard", "gradedSubsections"];
|
|
9
|
+
byCourse: (courseId: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "gradedSubsections", string];
|
|
10
10
|
};
|
|
@@ -114,11 +114,6 @@ declare const messages: {
|
|
|
114
114
|
defaultMessage: string;
|
|
115
115
|
description: string;
|
|
116
116
|
};
|
|
117
|
-
searchLearnerPlaceholder: {
|
|
118
|
-
id: string;
|
|
119
|
-
defaultMessage: string;
|
|
120
|
-
description: string;
|
|
121
|
-
};
|
|
122
117
|
noDateExtensions: {
|
|
123
118
|
id: string;
|
|
124
119
|
defaultMessage: string;
|
|
@@ -115,11 +115,6 @@ const messages = defineMessages({
|
|
|
115
115
|
defaultMessage: 'All Graded Subsections',
|
|
116
116
|
description: 'Label for the all graded subsections option in filters',
|
|
117
117
|
},
|
|
118
|
-
searchLearnerPlaceholder: {
|
|
119
|
-
id: 'instruct.dateExtensions.page.filters.searchLearnerPlaceholder',
|
|
120
|
-
defaultMessage: 'Search for a Learner',
|
|
121
|
-
description: 'Placeholder text for the search learner input field',
|
|
122
|
-
},
|
|
123
118
|
noDateExtensions: {
|
|
124
119
|
id: 'instruct.dateExtensions.page.noDateExtensions',
|
|
125
120
|
defaultMessage: 'No results found',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/dateExtensions/messages.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/dateExtensions/messages.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n dateExtensionsTitle: {\n id: 'instruct.dateExtensions.page.title',\n defaultMessage: 'Viewing Granted Extensions',\n description: 'Title for date extensions page',\n },\n addIndividualExtension: {\n id: 'instruct.dateExtensions.page.addIndividualExtension',\n defaultMessage: 'Add Individual Extension',\n description: 'Button text for adding an individual date extension',\n },\n username: {\n id: 'instruct.dateExtensions.page.tableHeader.username',\n defaultMessage: 'User Name',\n description: 'Label for the user name column in the date extensions table',\n },\n fullname: {\n id: 'instruct.dateExtensions.page.tableHeader.fullname',\n defaultMessage: 'Full Name',\n description: 'Label for the full name column in the date extensions table',\n },\n email: {\n id: 'instruct.dateExtensions.page.tableHeader.email',\n defaultMessage: 'Email',\n description: 'Label for the email column in the date extensions table',\n },\n gradedSubsection: {\n id: 'instruct.dateExtensions.page.tableHeader.gradedSubsection',\n defaultMessage: 'Graded Subsection',\n description: 'Label for the graded subsection column in the date extensions table',\n },\n extendedDueDate: {\n id: 'instruct.dateExtensions.page.tableHeader.extendedDueDate',\n defaultMessage: 'Extended Due Date',\n description: 'Label for the extended due date column in the date extensions table',\n },\n reset: {\n id: 'instruct.dateExtensions.page.tableHeader.reset',\n defaultMessage: 'Reset',\n description: 'Label for the reset column in the date extensions table',\n },\n resetExtensions: {\n id: 'instruct.dateExtensions.page.button.resetExtensions',\n defaultMessage: 'Reset Extensions',\n description: 'Button text for resetting date extensions for a user',\n },\n resetConfirmationHeader: {\n id: 'instruct.dateExtensions.page.resetModal.confirmationHeader',\n defaultMessage: 'Reset extensions for {username}?',\n description: 'Header for the reset confirmation modal',\n },\n resetConfirmationMessage: {\n id: 'instruct.dateExtensions.page.resetModal.confirmationMessage',\n defaultMessage: 'Resetting a problem\\'s due date rescinds a due date extension for a student on a particular subsection. This will revert the due date for the student back to the problem\\'s original due date.',\n description: 'Confirmation message for resetting extensions in the reset modal',\n },\n cancel: {\n id: 'instruct.dateExtensions.page.resetModal.cancel',\n defaultMessage: 'Cancel',\n description: 'Label for the cancel button in the reset modal',\n },\n confirm: {\n id: 'instruct.dateExtensions.page.resetModal.confirm',\n defaultMessage: 'Reset Due Date for Student',\n description: 'Label for the confirm button in the reset modal',\n },\n close: {\n id: 'instruct.dateExtensions.page.resetModal.close',\n defaultMessage: 'Close',\n description: 'Label for the close button in the reset modal',\n },\n missingUserOrCourseIdError: {\n id: 'instruct.dateExtensions.page.error.missingUserOrCourseId',\n defaultMessage: 'Unable to reset extension: missing user or course ID.',\n description: 'Error message shown when user or course ID is missing during reset',\n },\n addIndividualDueDateExtension: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.title',\n defaultMessage: 'Add Individual Due Date Extension',\n description: 'Title for the add individual due date extension modal',\n },\n addExtension: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.addExtension',\n defaultMessage: 'Add Extension',\n description: 'Label for the add extension button',\n },\n extensionInstructions: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.extensionInstructions',\n defaultMessage: 'To grant an extension, select a student, graded subsection, and define the extension due date and time.',\n description: 'Instructions for adding an individual due date extension',\n },\n defineExtension: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.defineExtension',\n defaultMessage: 'Define Extension',\n description: 'Label for the define extension section',\n },\n extensionDate: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.extensionDate',\n defaultMessage: 'Extension Date',\n description: 'Label for the extension date field',\n },\n reasonForExtension: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.reasonForExtension',\n defaultMessage: 'Reason for Extension',\n description: 'Label for the reason for extension field',\n },\n selectGradedSubsection: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.selectGradedSubsection',\n defaultMessage: 'Select Graded Subsection',\n description: 'Label for the select graded subsection field',\n },\n allGradedSubsections: {\n id: 'instruct.dateExtensions.page.filters.allGradedSubsections',\n defaultMessage: 'All Graded Subsections',\n description: 'Label for the all graded subsections option in filters',\n },\n noDateExtensions: {\n id: 'instruct.dateExtensions.page.noDateExtensions',\n defaultMessage: 'No results found',\n description: 'Message shown when there are no date extensions to display in the table',\n },\n});\n\nexport default messages;\n"]}
|
|
@@ -12,12 +12,16 @@ export interface ResetDueDateParams {
|
|
|
12
12
|
url: string;
|
|
13
13
|
reason?: string;
|
|
14
14
|
}
|
|
15
|
-
export interface
|
|
15
|
+
export interface AddDateExtensionFormData {
|
|
16
16
|
emailOrUsername: string;
|
|
17
17
|
blockId: string;
|
|
18
|
-
|
|
18
|
+
dueDate: string;
|
|
19
|
+
dueTime: string;
|
|
19
20
|
reason: string;
|
|
20
21
|
}
|
|
22
|
+
export interface AddDateExtensionParams extends Omit<AddDateExtensionFormData, 'dueDate' | 'dueTime'> {
|
|
23
|
+
dueDatetime: string;
|
|
24
|
+
}
|
|
21
25
|
export interface DateExtensionQueryParams extends PaginationParams {
|
|
22
26
|
emailOrUsername?: string;
|
|
23
27
|
blockId?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/dateExtensions/types.ts"],"names":[],"mappings":"","sourcesContent":["import { PaginationParams } from '@src/types';\n\nexport interface LearnerDateExtension {\n username: string,\n fullName: string,\n email: string,\n unitTitle: string,\n extendedDueDate: string,\n unitLocation: string,\n}\n\nexport interface ResetDueDateParams {\n student: string,\n url: string,\n reason?: string,\n}\n\nexport interface
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/dateExtensions/types.ts"],"names":[],"mappings":"","sourcesContent":["import { PaginationParams } from '@src/types';\n\nexport interface LearnerDateExtension {\n username: string,\n fullName: string,\n email: string,\n unitTitle: string,\n extendedDueDate: string,\n unitLocation: string,\n}\n\nexport interface ResetDueDateParams {\n student: string,\n url: string,\n reason?: string,\n}\n\nexport interface AddDateExtensionFormData {\n emailOrUsername: string,\n blockId: string,\n dueDate: string,\n dueTime: string,\n reason: string,\n}\n\nexport interface AddDateExtensionParams extends Omit<AddDateExtensionFormData, 'dueDate' | 'dueTime'> {\n dueDatetime: string,\n}\n\nexport interface DateExtensionQueryParams extends PaginationParams {\n emailOrUsername?: string,\n blockId?: string,\n}\n"]}
|
|
@@ -3,13 +3,15 @@ import { useState } from 'react';
|
|
|
3
3
|
import { useIntl } from '@openedx/frontend-base';
|
|
4
4
|
import { ActionRow, Button, IconButton } from '@openedx/paragon';
|
|
5
5
|
import { MoreVert } from '@openedx/paragon/icons';
|
|
6
|
-
import messages from '
|
|
7
|
-
import EnrollmentsList from '
|
|
8
|
-
import EnrollmentStatusModal from '
|
|
9
|
-
import UnenrollModal from '
|
|
6
|
+
import messages from '../enrollments/messages';
|
|
7
|
+
import EnrollmentsList from '../enrollments/components/EnrollmentsList';
|
|
8
|
+
import EnrollmentStatusModal from '../enrollments/components/EnrollmentStatusModal';
|
|
9
|
+
import UnenrollModal from '../enrollments/components/UnenrollModal';
|
|
10
|
+
import EnrollLearnersModal from '../enrollments/components/EnrollLearnersModal';
|
|
10
11
|
const EnrollmentsPage = () => {
|
|
11
12
|
const intl = useIntl();
|
|
12
13
|
const [isEnrollmentStatusModalOpen, setIsEnrollmentStatusModalOpen] = useState(false);
|
|
14
|
+
const [isEnrollLearnersModalOpen, setIsEnrollLearnersModalOpen] = useState(false);
|
|
13
15
|
const [isUnenrollModalOpen, setIsUnenrollModalOpen] = useState(false);
|
|
14
16
|
const [selectedLearner, setSelectedLearner] = useState(null);
|
|
15
17
|
const handleMoreButton = () => {
|
|
@@ -26,7 +28,13 @@ const EnrollmentsPage = () => {
|
|
|
26
28
|
const handleCloseEnrollmentStatusModal = () => {
|
|
27
29
|
setIsEnrollmentStatusModalOpen(false);
|
|
28
30
|
};
|
|
29
|
-
|
|
31
|
+
const handleEnrollLearners = () => {
|
|
32
|
+
setIsEnrollLearnersModalOpen(true);
|
|
33
|
+
};
|
|
34
|
+
const handleCloseEnrollLearnersModal = () => {
|
|
35
|
+
setIsEnrollLearnersModalOpen(false);
|
|
36
|
+
};
|
|
37
|
+
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", children: ["+ ", intl.formatMessage(messages.addBetaTesters)] }), _jsxs(Button, { onClick: handleEnrollLearners, children: ["+ ", intl.formatMessage(messages.enrollLearners)] })] })] }), _jsx(EnrollmentsList, { onUnenroll: handleUnenroll }), _jsx(EnrollmentStatusModal, { isOpen: isEnrollmentStatusModalOpen, onClose: handleCloseEnrollmentStatusModal }), selectedLearner && _jsx(UnenrollModal, { isOpen: isUnenrollModalOpen, learner: selectedLearner, onClose: handleUnenrollModalClose, onSuccess: handleUnenrollModalClose }), _jsx(EnrollLearnersModal, { isOpen: isEnrollLearnersModalOpen, onClose: handleCloseEnrollLearnersModal, onSuccess: handleCloseEnrollLearnersModal })] }));
|
|
30
38
|
};
|
|
31
39
|
export default EnrollmentsPage;
|
|
32
40
|
//# 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,
|
|
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 EnrollmentsList from '@src/enrollments/components/EnrollmentsList';\nimport EnrollmentStatusModal from '@src/enrollments/components/EnrollmentStatusModal';\nimport UnenrollModal from '@src/enrollments/components/UnenrollModal';\nimport EnrollLearnersModal from '@src/enrollments/components/EnrollLearnersModal';\nimport { EnrolledLearner } from '@src/enrollments/types';\n\nconst EnrollmentsPage = () => {\n const intl = useIntl();\n const [isEnrollmentStatusModalOpen, setIsEnrollmentStatusModalOpen] = useState(false);\n const [isEnrollLearnersModalOpen, setIsEnrollLearnersModalOpen] = useState(false);\n const [isUnenrollModalOpen, setIsUnenrollModalOpen] = useState(false);\n const [selectedLearner, setSelectedLearner] = useState<EnrolledLearner | null>(null);\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 };\n\n const handleCloseEnrollLearnersModal = () => {\n setIsEnrollLearnersModalOpen(false);\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\">+ {intl.formatMessage(messages.addBetaTesters)}</Button>\n <Button onClick={handleEnrollLearners}>+ {intl.formatMessage(messages.enrollLearners)}</Button>\n </ActionRow>\n </div>\n <EnrollmentsList onUnenroll={handleUnenroll} />\n <EnrollmentStatusModal isOpen={isEnrollmentStatusModalOpen} onClose={handleCloseEnrollmentStatusModal} />\n {selectedLearner && <UnenrollModal isOpen={isUnenrollModalOpen} learner={selectedLearner} onClose={handleUnenrollModalClose} onSuccess={handleUnenrollModalClose} />}\n <EnrollLearnersModal isOpen={isEnrollLearnersModalOpen} onClose={handleCloseEnrollLearnersModal} onSuccess={handleCloseEnrollLearnersModal} />\n </>\n );\n};\n\nexport default EnrollmentsPage;\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface EnrollLearnersModalProps {
|
|
2
|
+
isOpen: boolean;
|
|
3
|
+
onClose: () => void;
|
|
4
|
+
onSuccess: () => void;
|
|
5
|
+
}
|
|
6
|
+
declare const EnrollLearnersModal: ({ isOpen, onClose, onSuccess }: EnrollLearnersModalProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default EnrollLearnersModal;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } 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 { useUpdateEnrollments } from '../../enrollments/data/apiHook';
|
|
8
|
+
import messages from '../../enrollments/messages';
|
|
9
|
+
import { useAlert } from '../../providers/AlertProvider';
|
|
10
|
+
const EnrollLearnersModal = ({ isOpen, onClose, onSuccess }) => {
|
|
11
|
+
const intl = useIntl();
|
|
12
|
+
const { courseId = '' } = useParams();
|
|
13
|
+
const [emails, setEmails] = useState('');
|
|
14
|
+
const [autoEnroll, setAutoEnroll] = useState(true);
|
|
15
|
+
const [emailStudents, setEmailStudents] = useState(true);
|
|
16
|
+
const { mutate: enrollLearners } = useUpdateEnrollments(courseId);
|
|
17
|
+
const { showModal } = useAlert();
|
|
18
|
+
const handleSave = () => {
|
|
19
|
+
const identifier = emails.split(',').map(email => email.trim()).filter(email => email);
|
|
20
|
+
enrollLearners({ identifier, action: 'enroll', autoEnroll, emailStudents }, {
|
|
21
|
+
onSuccess: () => {
|
|
22
|
+
setEmails('');
|
|
23
|
+
setAutoEnroll(true);
|
|
24
|
+
setEmailStudents(true);
|
|
25
|
+
onSuccess();
|
|
26
|
+
},
|
|
27
|
+
onError: (error) => {
|
|
28
|
+
var _a;
|
|
29
|
+
const notFound = isAxiosError(error) && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404;
|
|
30
|
+
const errorMessage = notFound
|
|
31
|
+
? intl.formatMessage(messages.enrollLearnerNotFoundError)
|
|
32
|
+
: error.message || intl.formatMessage(messages.enrollLearnerError);
|
|
33
|
+
showModal({
|
|
34
|
+
message: errorMessage,
|
|
35
|
+
variant: 'danger',
|
|
36
|
+
confirmText: intl.formatMessage(messages.closeButton),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
return (_jsxs(ModalDialog, { isOpen: isOpen, onClose: onClose, isOverflowVisible: false, title: intl.formatMessage(messages.enrollLearners), children: [_jsx(ModalDialog.Header, { className: "border-light-700 border-bottom", children: _jsx("h3", { className: "text-primary-500", children: intl.formatMessage(messages.enrollLearners) }) }), _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.addLearnerInstructions) }), _jsx(FormControl, { name: "identifier", as: "textarea", rows: 4, placeholder: intl.formatMessage(messages.userIdentifierPlaceholder), onChange: (e) => setEmails(e.target.value) }), _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: emails.trim().length === 0, children: intl.formatMessage(messages.saveButton) })] })] }));
|
|
42
|
+
};
|
|
43
|
+
export default EnrollLearnersModal;
|
|
44
|
+
//# sourceMappingURL=EnrollLearnersModal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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 onSuccess: () => void,\n}\n\nconst EnrollLearnersModal = ({\n isOpen,\n onClose,\n onSuccess\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 } = 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: () => {\n setEmails('');\n setAutoEnroll(true);\n setEmailStudents(true);\n onSuccess();\n },\n onError: (error) => {\n const notFound = isAxiosError(error) && error.response?.status === 404;\n const errorMessage = notFound\n ? intl.formatMessage(messages.enrollLearnerNotFoundError)\n : error.message || 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"]}
|
|
@@ -3,8 +3,8 @@ import { useState } from 'react';
|
|
|
3
3
|
import { useParams } from 'react-router-dom';
|
|
4
4
|
import { useIntl } from '@openedx/frontend-base';
|
|
5
5
|
import { Button, FormControl, ModalDialog } from '@openedx/paragon';
|
|
6
|
-
import { useEnrollmentByUserId } from '
|
|
7
|
-
import messages from '
|
|
6
|
+
import { useEnrollmentByUserId } from '../../enrollments/data/apiHook';
|
|
7
|
+
import messages from '../../enrollments/messages';
|
|
8
8
|
const EnrollmentStatusModal = ({ isOpen, onClose }) => {
|
|
9
9
|
const intl = useIntl();
|
|
10
10
|
const { courseId = '' } = useParams();
|
|
@@ -17,7 +17,7 @@ const EnrollmentStatusModal = ({ isOpen, onClose }) => {
|
|
|
17
17
|
setLearnerIdentifier('');
|
|
18
18
|
onClose();
|
|
19
19
|
};
|
|
20
|
-
return (_jsxs(ModalDialog, { title: intl.formatMessage(messages.checkEnrollmentStatus), isOpen: isOpen, onClose: handleClose, isOverflowVisible: false, children: [_jsx(ModalDialog.Header, { children: _jsx(ModalDialog.Title, { className: "text-primary-700", children: intl.formatMessage(messages.checkEnrollmentStatus) }) }), _jsx(ModalDialog.Body, { className: "border-bottom border-top border-light-700", children: _jsxs("div", { className: "my-2", children: [_jsx("p", { children: intl.formatMessage(messages.addLearnerInstructions) }), _jsx(FormControl, { placeholder: intl.formatMessage(messages.
|
|
20
|
+
return (_jsxs(ModalDialog, { title: intl.formatMessage(messages.checkEnrollmentStatus), isOpen: isOpen, onClose: handleClose, isOverflowVisible: false, children: [_jsx(ModalDialog.Header, { children: _jsx(ModalDialog.Title, { className: "text-primary-700", children: intl.formatMessage(messages.checkEnrollmentStatus) }) }), _jsx(ModalDialog.Body, { className: "border-bottom border-top border-light-700", children: _jsxs("div", { className: "my-2", children: [_jsx("p", { children: intl.formatMessage(messages.addLearnerInstructions) }), _jsx(FormControl, { placeholder: intl.formatMessage(messages.enrollmentStatusPlaceholder), value: learnerIdentifier, onChange: (e) => setLearnerIdentifier(e.target.value) }), _jsx(Button, { className: "mt-3", onClick: handleSearch, disabled: !learnerIdentifier.trim(), children: intl.formatMessage(messages.checkEnrollmentStatus) }), data.enrollmentStatus && (_jsx("p", { className: "mt-3 mb-0", children: data.enrollmentStatus }))] }) }), _jsx(ModalDialog.Footer, { children: _jsx(Button, { onClick: handleClose, children: intl.formatMessage(messages.closeButton) }) })] }));
|
|
21
21
|
};
|
|
22
22
|
export default EnrollmentStatusModal;
|
|
23
23
|
//# sourceMappingURL=EnrollmentStatusModal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnrollmentStatusModal.js","sourceRoot":"","sources":["../../../src/enrollments/components/EnrollmentStatusModal.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"EnrollmentStatusModal.js","sourceRoot":"","sources":["../../../src/enrollments/components/EnrollmentStatusModal.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAe,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,QAAQ,MAAM,2BAA2B,CAAC;AAOjD,MAAM,qBAAqB,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,EAA8B,EAAE,EAAE;IAChF,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,EAAE,QAAQ,GAAG,EAAE,EAAE,GAAG,SAAS,EAAwB,CAAC;IAC5D,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CAAS,EAAE,CAAC,CAAC;IACvE,MAAM,EAAE,IAAI,GAAG,EAAE,gBAAgB,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,qBAAqB,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;IAExG,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,oBAAoB,CAAC,EAAE,CAAC,CAAC;QACzB,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IAEF,OAAO,CACL,MAAC,WAAW,IAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,KAAK,aACpI,KAAC,WAAW,CAAC,MAAM,cACjB,KAAC,WAAW,CAAC,KAAK,IAAC,SAAS,EAAC,kBAAkB,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,qBAAqB,CAAC,GAAqB,GACrG,EACrB,KAAC,WAAW,CAAC,IAAI,IAAC,SAAS,EAAC,2CAA2C,YACrE,eAAK,SAAS,EAAC,MAAM,aACnB,sBAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,sBAAsB,CAAC,GAAK,EAC5D,KAAC,WAAW,IACV,WAAW,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,2BAA2B,CAAC,EACrE,KAAK,EAAE,iBAAiB,EACxB,QAAQ,EAAE,CAAC,CAAgC,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GACpF,EACF,KAAC,MAAM,IACL,SAAS,EAAC,MAAM,EAChB,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,YAElC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,qBAAqB,CAAC,GAC5C,EAER,IAAI,CAAC,gBAAgB,IAAI,CACxB,YAAG,SAAS,EAAC,WAAW,YAAE,IAAI,CAAC,gBAAgB,GAAK,CACrD,IACG,GACW,EACnB,KAAC,WAAW,CAAC,MAAM,cACjB,KAAC,MAAM,IAAC,OAAO,EAAE,WAAW,YAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAU,GAC9D,IACT,CACf,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,qBAAqB,CAAC","sourcesContent":["import { useState, ChangeEvent } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, FormControl, ModalDialog } from '@openedx/paragon';\nimport { useEnrollmentByUserId } from '@src/enrollments/data/apiHook';\nimport messages from '@src/enrollments/messages';\n\ninterface EnrollmentStatusModalProps {\n isOpen: boolean,\n onClose: () => void,\n}\n\nconst EnrollmentStatusModal = ({ isOpen, onClose }: EnrollmentStatusModalProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [learnerIdentifier, setLearnerIdentifier] = useState<string>('');\n const { data = { enrollmentStatus: '' }, refetch } = useEnrollmentByUserId(courseId, learnerIdentifier);\n\n const handleSearch = () => {\n refetch();\n };\n\n const handleClose = () => {\n setLearnerIdentifier('');\n onClose();\n };\n\n return (\n <ModalDialog title={intl.formatMessage(messages.checkEnrollmentStatus)} isOpen={isOpen} onClose={handleClose} isOverflowVisible={false}>\n <ModalDialog.Header>\n <ModalDialog.Title className=\"text-primary-700\">{intl.formatMessage(messages.checkEnrollmentStatus)}</ModalDialog.Title>\n </ModalDialog.Header>\n <ModalDialog.Body className=\"border-bottom border-top border-light-700\">\n <div className=\"my-2\">\n <p>{intl.formatMessage(messages.addLearnerInstructions)}</p>\n <FormControl\n placeholder={intl.formatMessage(messages.enrollmentStatusPlaceholder)}\n value={learnerIdentifier}\n onChange={(e: ChangeEvent<HTMLInputElement>) => setLearnerIdentifier(e.target.value)}\n />\n <Button\n className=\"mt-3\"\n onClick={handleSearch}\n disabled={!learnerIdentifier.trim()}\n >\n {intl.formatMessage(messages.checkEnrollmentStatus)}\n </Button>\n\n {data.enrollmentStatus && (\n <p className=\"mt-3 mb-0\">{data.enrollmentStatus}</p>\n )}\n </div>\n </ModalDialog.Body>\n <ModalDialog.Footer>\n <Button onClick={handleClose}>{intl.formatMessage(messages.closeButton)}</Button>\n </ModalDialog.Footer>\n </ModalDialog>\n );\n};\n\nexport default EnrollmentStatusModal;\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EnrolledLearner } from '../../enrollments/types';
|
|
2
2
|
interface EnrollmentsListProps {
|
|
3
|
-
onUnenroll: (learner:
|
|
3
|
+
onUnenroll: (learner: EnrolledLearner) => void;
|
|
4
4
|
}
|
|
5
5
|
declare const EnrollmentsList: ({ onUnenroll }: EnrollmentsListProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
6
|
export default EnrollmentsList;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
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
|
-
import { ActionRow, Button, DataTable, FormControl, Icon, IconButton } from '@openedx/paragon';
|
|
5
4
|
import { useIntl } from '@openedx/frontend-base';
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import
|
|
5
|
+
import { ActionRow, Button, DataTable, FormControl, Icon, IconButton } from '@openedx/paragon';
|
|
6
|
+
import { FilterList, MoreVert, Search } from '@openedx/paragon/icons';
|
|
7
|
+
import messages from '../../enrollments/messages';
|
|
8
|
+
import { useEnrollments } from '../../enrollments/data/apiHook';
|
|
9
9
|
import { useDebouncedFilter } from '../../hooks/useDebouncedFilter';
|
|
10
10
|
const ENROLLMENTS_PAGE_SIZE = 25;
|
|
11
11
|
const betaTesterOptions = [
|
|
@@ -29,7 +29,7 @@ const BetaTesterFilter = ({ column: { filterValue, setFilter } }) => {
|
|
|
29
29
|
const handleSelectChange = (e) => {
|
|
30
30
|
setFilter(e.target.value);
|
|
31
31
|
};
|
|
32
|
-
return (_jsx(FormControl, { as: "select", className: "mb-0", name: "isBetaTester", size: "md", value: filterValue, onChange: handleSelectChange, children: betaTesterOptions.map((option) => (_jsx("option", { value: option.value, children: intl.formatMessage(option.label) }, option.value))) }));
|
|
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
34
|
const EnrollmentsList = ({ onUnenroll }) => {
|
|
35
35
|
const intl = useIntl();
|
|
@@ -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 { ActionRow, Button, DataTable, FormControl, Icon, IconButton } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport { MoreVert, Search } from '@openedx/paragon/icons';\nimport messages from '../messages';\nimport { useEnrollments } from '../data/apiHook';\nimport { Learner } from '../types';\nimport { DataTableFetchDataProps, TableCellValue } from '@src/types';\nimport { useDebouncedFilter } from '@src/hooks/useDebouncedFilter';\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: Learner) => 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 >\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<Learner>) => {\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 } 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"]}
|