@openedx/frontend-app-instructor-dashboard 1.0.0-alpha.41 → 1.0.0-alpha.43
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/routes.d.ts +2 -0
- package/dist/routes.js +2 -0
- package/dist/routes.js.map +1 -1
- package/dist/specialExams/SpecialExamsPage.js +2 -2
- package/dist/specialExams/SpecialExamsPage.js.map +1 -1
- package/dist/specialExams/components/Attempts.d.ts +2 -0
- package/dist/specialExams/components/Attempts.js +60 -0
- package/dist/specialExams/components/Attempts.js.map +1 -0
- package/dist/specialExams/components/AttemptsList.d.ts +6 -1
- package/dist/specialExams/components/AttemptsList.js +69 -9
- package/dist/specialExams/components/AttemptsList.js.map +1 -1
- package/dist/specialExams/data/api.d.ts +3 -1
- package/dist/specialExams/data/api.js +12 -0
- package/dist/specialExams/data/api.js.map +1 -1
- package/dist/specialExams/data/apiHook.d.ts +7 -5
- package/dist/specialExams/data/apiHook.js +20 -2
- package/dist/specialExams/data/apiHook.js.map +1 -1
- package/dist/specialExams/data/queryKeys.d.ts +1 -1
- package/dist/specialExams/data/queryKeys.js +1 -1
- package/dist/specialExams/data/queryKeys.js.map +1 -1
- package/dist/specialExams/messages.d.ts +60 -0
- package/dist/specialExams/messages.js +60 -0
- package/dist/specialExams/messages.js.map +1 -1
- package/dist/specialExams/types.d.ts +13 -2
- package/dist/specialExams/types.js.map +1 -1
- package/package.json +1 -1
package/dist/routes.d.ts
CHANGED
package/dist/routes.js
CHANGED
|
@@ -22,6 +22,7 @@ import SpecialExamsPage from './specialExams/SpecialExamsPage';
|
|
|
22
22
|
import PageNotFound from './components/PageNotFound';
|
|
23
23
|
import { useWidgetProps } from './slots/SlotUtils';
|
|
24
24
|
import { instructorDashboardRole } from './constants';
|
|
25
|
+
import { authenticatedLoader } from '@openedx/frontend-base';
|
|
25
26
|
const defaultTabs = [
|
|
26
27
|
{ tabId: 'course_info', content: _jsx(CourseInfoPage, {}) },
|
|
27
28
|
{ tabId: 'enrollments', content: _jsx(EnrollmentsPage, {}) },
|
|
@@ -48,6 +49,7 @@ const routes = [
|
|
|
48
49
|
{
|
|
49
50
|
id: 'org.openedx.frontend.route.instructorDashboard.main',
|
|
50
51
|
path: 'instructor-dashboard/:courseId',
|
|
52
|
+
loader: authenticatedLoader,
|
|
51
53
|
handle: {
|
|
52
54
|
roles: [instructorDashboardRole]
|
|
53
55
|
},
|
package/dist/routes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.tsx"],"names":[],"mappings":";;;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,WAAW,MAAM,0BAA0B,CAAC;AACnD,OAAO,cAAc,MAAM,gCAAgC,CAAC;AAC5D,OAAO,gBAAgB,MAAM,oCAAoC,CAAC;AAClE,OAAO,cAAc,MAAM,gCAAgC,CAAC;AAC5D,OAAO,iBAAiB,MAAM,sCAAsC,CAAC;AACrE,OAAO,kBAAkB,MAAM,wCAAwC,CAAC;AACxE,OAAO,eAAe,MAAM,kCAAkC,CAAC;AAC/D,OAAO,WAAW,MAAM,0BAA0B,CAAC;AACnD,OAAO,iBAAiB,MAAM,sCAAsC,CAAC;AACrE,OAAO,gBAAgB,MAAM,oCAAoC,CAAC;AAClE,OAAO,YAAY,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useParams, Navigate } from 'react-router-dom';\nimport CohortsPage from '@src/cohorts/CohortsPage';\nimport CourseInfoPage from '@src/courseInfo/CourseInfoPage';\nimport CertificatesPage from '@src/certificates/CertificatesPage';\nimport CourseTeamPage from '@src/courseTeam/CourseTeamPage';\nimport DataDownloadsPage from '@src/dataDownloads/DataDownloadsPage';\nimport DateExtensionsPage from '@src/dateExtensions/DateExtensionsPage';\nimport EnrollmentsPage from '@src/enrollments/EnrollmentsPage';\nimport GradingPage from '@src/grading/GradingPage';\nimport OpenResponsesPage from '@src/openResponses/OpenResponsesPage';\nimport SpecialExamsPage from '@src/specialExams/SpecialExamsPage';\nimport PageNotFound from '@src/components/PageNotFound';\nimport { useWidgetProps } from './slots/SlotUtils';\nimport { instructorDashboardRole } from './constants';\nimport { authenticatedLoader } from '@openedx/frontend-base';\n\ninterface InstructorRouteProps {\n tabId: string,\n content: React.ReactNode,\n}\n\nconst defaultTabs: InstructorRouteProps[] = [\n { tabId: 'course_info', content: <CourseInfoPage /> },\n { tabId: 'enrollments', content: <EnrollmentsPage /> },\n { tabId: 'course_team', content: <CourseTeamPage /> },\n { tabId: 'cohorts', content: <CohortsPage /> },\n { tabId: 'date_extensions', content: <DateExtensionsPage /> },\n { tabId: 'grading', content: <GradingPage /> },\n { tabId: 'data_downloads', content: <DataDownloadsPage /> },\n { tabId: 'special_exams', content: <SpecialExamsPage /> },\n { tabId: 'certificates', content: <CertificatesPage /> },\n { tabId: 'open_responses', content: <OpenResponsesPage /> },\n];\n\nconst TabContent = () => {\n const { tabId } = useParams<{ tabId: string }>();\n const routeWidgets = useWidgetProps('org.openedx.frontend.slot.instructorDashboard.routes.v1') as InstructorRouteProps[];\n\n const tabRoutes = [\n ...defaultTabs.filter(\n defaultTab => !routeWidgets.some(slotTab => slotTab.tabId === defaultTab.tabId)\n ),\n ...routeWidgets\n ];\n\n const foundTab = tabRoutes.find(tab => tab.tabId === tabId);\n\n return foundTab ? foundTab.content : <PageNotFound />;\n};\n\nconst routes = [\n {\n id: 'org.openedx.frontend.route.instructorDashboard.main',\n path: 'instructor-dashboard/:courseId',\n loader: authenticatedLoader,\n handle: {\n roles: [instructorDashboardRole]\n },\n async lazy() {\n const module = await import(/* webpackChunkName: \"instructor-dashboard-main\" */ './Main');\n return { Component: module.default };\n },\n children: [\n {\n index: true,\n element: <Navigate to=\"course_info\" replace />\n },\n {\n path: ':tabId',\n element: <TabContent />\n },\n ]\n }\n];\n\nexport default routes;\n"]}
|
|
@@ -4,7 +4,7 @@ import { useIntl } from '@openedx/frontend-base';
|
|
|
4
4
|
import { Button, ButtonGroup, Card } from '@openedx/paragon';
|
|
5
5
|
import messages from './messages';
|
|
6
6
|
import Allowances from './components/Allowances';
|
|
7
|
-
import
|
|
7
|
+
import Attempts from './components/Attempts';
|
|
8
8
|
const SPECIAL_EXAMS_TAB = {
|
|
9
9
|
ATTEMPTS: 'attempts',
|
|
10
10
|
ALLOWANCES: 'allowances',
|
|
@@ -12,7 +12,7 @@ const SPECIAL_EXAMS_TAB = {
|
|
|
12
12
|
const SpecialExamsPage = () => {
|
|
13
13
|
const intl = useIntl();
|
|
14
14
|
const [selectedTab, setSelectedTab] = useState(SPECIAL_EXAMS_TAB.ATTEMPTS);
|
|
15
|
-
return (_jsxs(_Fragment, { children: [_jsx("h3", { className: "text-primary-700", children: intl.formatMessage(messages.specialExamsTitle) }), _jsxs(Card, { className: "bg-light-200 mt-4.5", children: [_jsxs(ButtonGroup, { className: "d-block mx-4 mt-4", children: [_jsx(Button, { variant: selectedTab === SPECIAL_EXAMS_TAB.ATTEMPTS ? 'primary' : 'outline-primary', onClick: () => setSelectedTab(SPECIAL_EXAMS_TAB.ATTEMPTS), children: intl.formatMessage(messages.examAttempts) }), _jsx(Button, { variant: selectedTab === SPECIAL_EXAMS_TAB.ALLOWANCES ? 'primary' : 'outline-primary', onClick: () => setSelectedTab(SPECIAL_EXAMS_TAB.ALLOWANCES), children: intl.formatMessage(messages.allowances) })] }), selectedTab === SPECIAL_EXAMS_TAB.ATTEMPTS ? _jsx(
|
|
15
|
+
return (_jsxs(_Fragment, { children: [_jsx("h3", { className: "text-primary-700", children: intl.formatMessage(messages.specialExamsTitle) }), _jsxs(Card, { className: "bg-light-200 mt-4.5", children: [_jsxs(ButtonGroup, { className: "d-block mx-4 mt-4", children: [_jsx(Button, { variant: selectedTab === SPECIAL_EXAMS_TAB.ATTEMPTS ? 'primary' : 'outline-primary', onClick: () => setSelectedTab(SPECIAL_EXAMS_TAB.ATTEMPTS), children: intl.formatMessage(messages.examAttempts) }), _jsx(Button, { variant: selectedTab === SPECIAL_EXAMS_TAB.ALLOWANCES ? 'primary' : 'outline-primary', onClick: () => setSelectedTab(SPECIAL_EXAMS_TAB.ALLOWANCES), children: intl.formatMessage(messages.allowances) })] }), selectedTab === SPECIAL_EXAMS_TAB.ATTEMPTS ? _jsx(Attempts, {}) : _jsx(Allowances, {})] })] }));
|
|
16
16
|
};
|
|
17
17
|
export default SpecialExamsPage;
|
|
18
18
|
//# sourceMappingURL=SpecialExamsPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpecialExamsPage.js","sourceRoot":"","sources":["../../src/specialExams/SpecialExamsPage.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,UAAU,MAAM,yBAAyB,CAAC;AACjD,OAAO,
|
|
1
|
+
{"version":3,"file":"SpecialExamsPage.js","sourceRoot":"","sources":["../../src/specialExams/SpecialExamsPage.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,UAAU,MAAM,yBAAyB,CAAC;AACjD,OAAO,QAAQ,MAAM,uBAAuB,CAAC;AAE7C,MAAM,iBAAiB,GAAG;IACxB,QAAQ,EAAE,UAAU;IACpB,UAAU,EAAE,YAAY;CACzB,CAAC;AAEF,MAAM,gBAAgB,GAAG,GAAG,EAAE;IAC5B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAA6D,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAEvI,OAAO,CACL,8BACE,aAAI,SAAS,EAAC,kBAAkB,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,iBAAiB,CAAC,GAAM,EACtF,MAAC,IAAI,IAAC,SAAS,EAAC,qBAAqB,aACnC,MAAC,WAAW,IAAC,SAAS,EAAC,mBAAmB,aACxC,KAAC,MAAM,IACL,OAAO,EAAE,WAAW,KAAK,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,EACnF,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,iBAAiB,CAAC,QAAQ,CAAC,YACzD,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,YAAY,CAAC,GAClC,EACT,KAAC,MAAM,IACL,OAAO,EAAE,WAAW,KAAK,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,EACrF,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,iBAAiB,CAAC,UAAU,CAAC,YAC3D,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,GAChC,IACG,EAEZ,WAAW,KAAK,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAC,QAAQ,KAAG,CAAC,CAAC,CAAC,KAAC,UAAU,KAAG,IAEvE,IACN,CACJ,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,gBAAgB,CAAC","sourcesContent":["import { useState } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, ButtonGroup, Card } from '@openedx/paragon';\nimport messages from './messages';\nimport Allowances from './components/Allowances';\nimport Attempts from './components/Attempts';\n\nconst SPECIAL_EXAMS_TAB = {\n ATTEMPTS: 'attempts',\n ALLOWANCES: 'allowances',\n};\n\nconst SpecialExamsPage = () => {\n const intl = useIntl();\n const [selectedTab, setSelectedTab] = useState<(typeof SPECIAL_EXAMS_TAB)[keyof typeof SPECIAL_EXAMS_TAB]>(SPECIAL_EXAMS_TAB.ATTEMPTS);\n\n return (\n <>\n <h3 className=\"text-primary-700\">{intl.formatMessage(messages.specialExamsTitle)}</h3>\n <Card className=\"bg-light-200 mt-4.5\">\n <ButtonGroup className=\"d-block mx-4 mt-4\">\n <Button\n variant={selectedTab === SPECIAL_EXAMS_TAB.ATTEMPTS ? 'primary' : 'outline-primary'}\n onClick={() => setSelectedTab(SPECIAL_EXAMS_TAB.ATTEMPTS)}\n >{intl.formatMessage(messages.examAttempts)}\n </Button>\n <Button\n variant={selectedTab === SPECIAL_EXAMS_TAB.ALLOWANCES ? 'primary' : 'outline-primary'}\n onClick={() => setSelectedTab(SPECIAL_EXAMS_TAB.ALLOWANCES)}\n >{intl.formatMessage(messages.allowances)}\n </Button>\n </ButtonGroup>\n {\n selectedTab === SPECIAL_EXAMS_TAB.ATTEMPTS ? <Attempts /> : <Allowances />\n }\n </Card>\n </>\n );\n};\n\nexport default SpecialExamsPage;\n"]}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } 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 { ActionRow, Button, ModalDialog, useToggle } from '@openedx/paragon';
|
|
7
|
+
import AttemptsList from '../../specialExams/components/AttemptsList';
|
|
8
|
+
import { useResetAttempt, useResumeAttempt } from '../../specialExams/data/apiHook';
|
|
9
|
+
import messages from '../../specialExams/messages';
|
|
10
|
+
import { useAlert } from '../../providers/AlertProvider';
|
|
11
|
+
const Attempts = () => {
|
|
12
|
+
const { courseId = '' } = useParams();
|
|
13
|
+
const intl = useIntl();
|
|
14
|
+
const { mutate: resetAttempt } = useResetAttempt(courseId);
|
|
15
|
+
const { mutate: resumeAttempt } = useResumeAttempt(courseId);
|
|
16
|
+
const { showModal, showToast } = useAlert();
|
|
17
|
+
const [isOpenConfirmationModal, openConfirmationModal, closeConfirmationModal] = useToggle(false);
|
|
18
|
+
const [attemptAction, setAttemptAction] = useState('reset');
|
|
19
|
+
const [attempt, setAttempt] = useState(null);
|
|
20
|
+
const handleResume = () => {
|
|
21
|
+
if (!attempt)
|
|
22
|
+
return;
|
|
23
|
+
const { user, id } = attempt;
|
|
24
|
+
resumeAttempt({ attemptId: id, userId: user.id }, {
|
|
25
|
+
onSuccess: () => {
|
|
26
|
+
showToast(intl.formatMessage(messages.successOnResume, { student: attempt.user.username }));
|
|
27
|
+
},
|
|
28
|
+
onError: (error) => {
|
|
29
|
+
var _a, _b;
|
|
30
|
+
const errorMessage = (isAxiosError(error) && ((_b = (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.detail)) || intl.formatMessage(messages.errorOnResume);
|
|
31
|
+
showModal({ variant: 'danger', message: errorMessage, confirmText: intl.formatMessage(messages.close) });
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
closeConfirmationModal();
|
|
35
|
+
};
|
|
36
|
+
const handleReset = () => {
|
|
37
|
+
if (!attempt)
|
|
38
|
+
return;
|
|
39
|
+
const { user, examId, examName } = attempt;
|
|
40
|
+
resetAttempt({ username: user.username, examId }, {
|
|
41
|
+
onSuccess: () => {
|
|
42
|
+
showToast(intl.formatMessage(messages.successOnReset, { examName, student: user.username }));
|
|
43
|
+
},
|
|
44
|
+
onError: (error) => {
|
|
45
|
+
var _a, _b;
|
|
46
|
+
const errorMessage = (isAxiosError(error) && ((_b = (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.detail)) || intl.formatMessage(messages.errorOnReset, { examName, student: user.username });
|
|
47
|
+
showModal({ variant: 'danger', message: errorMessage, confirmText: intl.formatMessage(messages.close) });
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
closeConfirmationModal();
|
|
51
|
+
};
|
|
52
|
+
const openAndSetConfirmationModal = (action, attempt) => {
|
|
53
|
+
openConfirmationModal();
|
|
54
|
+
setAttemptAction(action);
|
|
55
|
+
setAttempt(attempt);
|
|
56
|
+
};
|
|
57
|
+
return (_jsxs(_Fragment, { children: [_jsx(AttemptsList, { onResume: (attempt) => openAndSetConfirmationModal('resume', attempt), onReset: (attempt) => openAndSetConfirmationModal('reset', attempt) }), attempt && (_jsxs(ModalDialog, { title: intl.formatMessage(messages.confirmationModal), isOpen: isOpenConfirmationModal, onClose: closeConfirmationModal, isOverflowVisible: false, hasCloseButton: false, children: [_jsx(ModalDialog.Body, { children: attemptAction === 'reset' ? intl.formatMessage(messages.confirmationMessageReset) : intl.formatMessage(messages.confirmationMessageResume) }), _jsx(ModalDialog.Footer, { children: _jsxs(ActionRow, { children: [_jsx(Button, { variant: "tertiary", onClick: closeConfirmationModal, children: intl.formatMessage(messages.cancel) }), _jsx(Button, { variant: "primary", onClick: () => attemptAction === 'reset' ? handleReset() : handleResume(), children: attemptAction === 'reset' ? intl.formatMessage(messages.reset) : intl.formatMessage(messages.resume) })] }) })] }))] }));
|
|
58
|
+
};
|
|
59
|
+
export default Attempts;
|
|
60
|
+
//# sourceMappingURL=Attempts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Attempts.js","sourceRoot":"","sources":["../../../src/specialExams/components/Attempts.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 { ActionRow, Button, ModalDialog, useToggle } from '@openedx/paragon';\nimport AttemptsList from '@src/specialExams/components/AttemptsList';\nimport { useResetAttempt, useResumeAttempt } from '@src/specialExams/data/apiHook';\nimport messages from '@src/specialExams/messages';\nimport { Attempt, AttemptAction } from '@src/specialExams/types';\nimport { useAlert } from '@src/providers/AlertProvider';\n\nconst Attempts = () => {\n const { courseId = '' } = useParams<{ courseId: string }>();\n const intl = useIntl();\n const { mutate: resetAttempt } = useResetAttempt(courseId);\n const { mutate: resumeAttempt } = useResumeAttempt(courseId);\n const { showModal, showToast } = useAlert();\n const [isOpenConfirmationModal, openConfirmationModal, closeConfirmationModal] = useToggle(false);\n const [attemptAction, setAttemptAction] = useState<AttemptAction>('reset');\n const [attempt, setAttempt] = useState<Attempt | null>(null);\n\n const handleResume = () => {\n if (!attempt) return;\n const { user, id } = attempt;\n resumeAttempt({ attemptId: id, userId: user.id }, {\n onSuccess: () => {\n showToast(intl.formatMessage(messages.successOnResume, { student: attempt.user.username }));\n },\n onError: (error) => {\n const errorMessage = (isAxiosError(error) && error?.response?.data?.detail) || intl.formatMessage(messages.errorOnResume);\n showModal({ variant: 'danger', message: errorMessage, confirmText: intl.formatMessage(messages.close) });\n }\n });\n closeConfirmationModal();\n };\n\n const handleReset = () => {\n if (!attempt) return;\n const { user, examId, examName } = attempt;\n resetAttempt({ username: user.username, examId }, {\n onSuccess: () => {\n showToast(intl.formatMessage(messages.successOnReset, { examName, student: user.username }));\n },\n onError: (error) => {\n const errorMessage = (isAxiosError(error) && error?.response?.data?.detail) || intl.formatMessage(messages.errorOnReset, { examName, student: user.username });\n showModal({ variant: 'danger', message: errorMessage, confirmText: intl.formatMessage(messages.close) });\n }\n });\n closeConfirmationModal();\n };\n\n const openAndSetConfirmationModal = (action: AttemptAction, attempt: Attempt) => {\n openConfirmationModal();\n setAttemptAction(action);\n setAttempt(attempt);\n };\n\n return (\n <>\n <AttemptsList\n onResume={(attempt: Attempt) => openAndSetConfirmationModal('resume', attempt)}\n onReset={(attempt: Attempt) => openAndSetConfirmationModal('reset', attempt)}\n />\n { attempt && (\n <ModalDialog\n title={intl.formatMessage(messages.confirmationModal)}\n isOpen={isOpenConfirmationModal}\n onClose={closeConfirmationModal}\n isOverflowVisible={false}\n hasCloseButton={false}\n >\n <ModalDialog.Body>\n {attemptAction === 'reset' ? intl.formatMessage(messages.confirmationMessageReset) : intl.formatMessage(messages.confirmationMessageResume)}\n </ModalDialog.Body>\n <ModalDialog.Footer>\n <ActionRow>\n <Button variant=\"tertiary\" onClick={closeConfirmationModal}>\n {intl.formatMessage(messages.cancel)}\n </Button>\n <Button\n variant=\"primary\"\n onClick={() => attemptAction === 'reset' ? handleReset() : handleResume()}\n >\n {attemptAction === 'reset' ? intl.formatMessage(messages.reset) : intl.formatMessage(messages.resume)}\n </Button>\n </ActionRow>\n </ModalDialog.Footer>\n </ModalDialog>\n )}\n </>\n );\n};\n\nexport default Attempts;\n"]}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import { Attempt } from '../../specialExams/types';
|
|
1
2
|
export declare const ATTEMPTS_PAGE_SIZE = 25;
|
|
2
|
-
|
|
3
|
+
interface AttemptsListProps {
|
|
4
|
+
onResume: (attempt: Attempt) => void;
|
|
5
|
+
onReset: (attempt: Attempt) => void;
|
|
6
|
+
}
|
|
7
|
+
declare const AttemptsList: ({ onResume, onReset }: AttemptsListProps) => import("react/jsx-runtime").JSX.Element;
|
|
3
8
|
export default AttemptsList;
|
|
@@ -1,26 +1,86 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo, useState } from 'react';
|
|
3
3
|
import { useParams } from 'react-router-dom';
|
|
4
4
|
import { useIntl } from '@openedx/frontend-base';
|
|
5
|
-
import { DataTable } from '@openedx/paragon';
|
|
5
|
+
import { DataTable, IconButton, OverlayTrigger, Popover } from '@openedx/paragon';
|
|
6
|
+
import { MoreVert } from '@openedx/paragon/icons';
|
|
6
7
|
import UsernameFilter from '../../components/UsernameFilter';
|
|
7
|
-
import messages from '../../specialExams/messages';
|
|
8
8
|
import { useAttempts } from '../../specialExams/data/apiHook';
|
|
9
|
+
import messages from '../../specialExams/messages';
|
|
9
10
|
export const ATTEMPTS_PAGE_SIZE = 25;
|
|
10
|
-
const AttemptsList = () => {
|
|
11
|
+
const AttemptsList = ({ onResume, onReset }) => {
|
|
11
12
|
const intl = useIntl();
|
|
12
13
|
const { courseId = '' } = useParams();
|
|
13
14
|
const [filters, setFilters] = useState({ page: 0, emailOrUsername: '', ordering: '' });
|
|
14
15
|
const { data = { results: [], count: 0, numPages: 0 }, isLoading = false } = useAttempts(courseId, Object.assign(Object.assign({}, filters), { pageSize: ATTEMPTS_PAGE_SIZE }));
|
|
16
|
+
const ActionCustomCell = ({ row: { original } }) => {
|
|
17
|
+
const [showPopover, setShowPopover] = useState(false);
|
|
18
|
+
const handleAction = (action) => {
|
|
19
|
+
setShowPopover(false);
|
|
20
|
+
if (action === 'resume') {
|
|
21
|
+
onResume(original);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
onReset(original);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const popoverContent = (_jsx(Popover, { id: `popover-${original.user.username}-${original.examName}`, className: "border-0 shadow-sm", children: _jsx(Popover.Content, { className: "p-0 border-0", children: _jsxs("div", { className: "dropdown-menu show position-static border shadow-sm", children: [_jsx("button", { type: "button", className: "dropdown-item", onClick: () => handleAction('reset'), children: intl.formatMessage(messages.reset) }), !original.readyToResume && original.status === 'error' && (_jsx("button", { type: "button", className: "dropdown-item", onClick: () => handleAction('resume'), children: intl.formatMessage(messages.resume) }))] }) }) }));
|
|
28
|
+
return (_jsx(_Fragment, { children: _jsx(OverlayTrigger, { trigger: "click", placement: "bottom-end", overlay: popoverContent, rootClose: true, show: showPopover, onToggle: setShowPopover, children: _jsx(IconButton, { alt: intl.formatMessage(messages.actions), className: "lead", iconAs: MoreVert }) }) }));
|
|
29
|
+
};
|
|
15
30
|
const columns = useMemo(() => [
|
|
16
31
|
{ accessor: 'user.username', Header: intl.formatMessage(messages.username), Filter: UsernameFilter, },
|
|
17
32
|
{ accessor: 'examName', Header: intl.formatMessage(messages.examName), disableFilters: true, },
|
|
18
33
|
{ accessor: 'allowedTimeLimitMins', Header: intl.formatMessage(messages.timeLimit), disableFilters: true, },
|
|
19
|
-
{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
34
|
+
{
|
|
35
|
+
accessor: 'examType',
|
|
36
|
+
Cell: ({ row }) => _jsx("span", { className: "text-capitalize", children: row.original.examType }),
|
|
37
|
+
disableFilters: true,
|
|
38
|
+
Header: intl.formatMessage(messages.type),
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
accessor: 'startTime',
|
|
42
|
+
Cell: ({ row }) => (_jsx("span", { children: row.original.startTime ? `${intl.formatDate(new Date(row.original.startTime), {
|
|
43
|
+
year: 'numeric',
|
|
44
|
+
month: '2-digit',
|
|
45
|
+
day: '2-digit',
|
|
46
|
+
hour: '2-digit',
|
|
47
|
+
minute: '2-digit',
|
|
48
|
+
timeZone: 'UTC',
|
|
49
|
+
})} UTC` : '' })),
|
|
50
|
+
disableFilters: true,
|
|
51
|
+
Header: intl.formatMessage(messages.startedAt),
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
accessor: 'endTime',
|
|
55
|
+
Cell: ({ row }) => (_jsx("span", { children: row.original.endTime ? `${intl.formatDate(new Date(row.original.endTime), {
|
|
56
|
+
year: 'numeric',
|
|
57
|
+
month: '2-digit',
|
|
58
|
+
day: '2-digit',
|
|
59
|
+
hour: '2-digit',
|
|
60
|
+
minute: '2-digit',
|
|
61
|
+
timeZone: 'UTC',
|
|
62
|
+
})} UTC` : '' })),
|
|
63
|
+
disableFilters: true,
|
|
64
|
+
Header: intl.formatMessage(messages.completedAt),
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
accessor: 'status',
|
|
68
|
+
Cell: ({ row }) => _jsx("span", { className: "text-capitalize", children: row.original.status }),
|
|
69
|
+
disableFilters: true,
|
|
70
|
+
Header: intl.formatMessage(messages.status),
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
accessor: 'readyToResume',
|
|
74
|
+
Cell: ({ row }) => (_jsx("span", { className: "text-capitalize", children: row.original.readyToResume ? intl.formatMessage(messages.true) : '' })),
|
|
75
|
+
disableFilters: true,
|
|
76
|
+
Header: intl.formatMessage(messages.readyForResume),
|
|
77
|
+
}
|
|
23
78
|
], [intl]);
|
|
79
|
+
const additionalColumns = [{
|
|
80
|
+
id: 'actions',
|
|
81
|
+
Header: '',
|
|
82
|
+
Cell: ActionCustomCell,
|
|
83
|
+
}];
|
|
24
84
|
const handleFetchData = (data) => {
|
|
25
85
|
var _a, _b;
|
|
26
86
|
const emailOrUsernameFilter = (_a = data.filters) === null || _a === void 0 ? void 0 : _a.find((f) => f.id === 'user.username');
|
|
@@ -35,7 +95,7 @@ const AttemptsList = () => {
|
|
|
35
95
|
setFilters((prevFilters) => (Object.assign(Object.assign({}, prevFilters), { page: data.pageIndex })));
|
|
36
96
|
}
|
|
37
97
|
};
|
|
38
|
-
return (_jsxs(DataTable, { className: "mt-3", columns: columns, data: data.results, state: {
|
|
98
|
+
return (_jsxs(DataTable, { additionalColumns: additionalColumns, className: "mt-3", columns: columns, data: data.results, state: {
|
|
39
99
|
pageIndex: filters.page,
|
|
40
100
|
pageSize: ATTEMPTS_PAGE_SIZE,
|
|
41
101
|
filters: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AttemptsList.js","sourceRoot":"","sources":["../../../src/specialExams/components/AttemptsList.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { DataTable } from '@openedx/paragon';\nimport UsernameFilter from '@src/components/UsernameFilter';\nimport messages from '@src/specialExams/messages';\nimport { useAttempts } from '@src/specialExams/data/apiHook';\nimport { DataTableFetchDataProps } from '@src/types';\n\nexport const ATTEMPTS_PAGE_SIZE = 25;\n\nconst AttemptsList = () => {\n const intl = useIntl();\n const { courseId = '' } = useParams();\n const [filters, setFilters] = useState({ page: 0, emailOrUsername: '', ordering: '' });\n const { data = { results: [], count: 0, numPages: 0 }, isLoading = false } = useAttempts(courseId, {\n ...filters,\n pageSize: ATTEMPTS_PAGE_SIZE\n });\n\n const columns = useMemo(() => [\n { accessor: 'user.username', Header: intl.formatMessage(messages.username), Filter: UsernameFilter, },\n { accessor: 'examName', Header: intl.formatMessage(messages.examName), disableFilters: true, },\n { accessor: 'allowedTimeLimitMins', Header: intl.formatMessage(messages.timeLimit), disableFilters: true, },\n { accessor: 'type', Header: intl.formatMessage(messages.type), disableFilters: true, },\n { accessor: 'startTime', Header: intl.formatMessage(messages.startedAt), disableFilters: true, },\n { accessor: 'endTime', Header: intl.formatMessage(messages.completedAt), disableFilters: true, },\n { accessor: 'status', Header: intl.formatMessage(messages.status), disableFilters: true, },\n ], [intl]);\n\n const handleFetchData = (data: DataTableFetchDataProps) => {\n const emailOrUsernameFilter = data.filters?.find((f) => f.id === 'user.username');\n const newEmailOrUsername = emailOrUsernameFilter ? emailOrUsernameFilter.value : '';\n const newOrdering = data.sortBy?.[0] ? `${data.sortBy[0].desc ? '-' : ''}${data.sortBy[0].id}` : '';\n const filtersChanged = newEmailOrUsername !== filters.emailOrUsername || newOrdering !== filters.ordering;\n if (filtersChanged) {\n setFilters((prevFilters) => ({ ...prevFilters, emailOrUsername: newEmailOrUsername, ordering: newOrdering, page: 0 }));\n return;\n }\n if (data.pageIndex !== filters.page) {\n setFilters((prevFilters) => ({ ...prevFilters, page: data.pageIndex }));\n }\n };\n\n return (\n <DataTable\n className=\"mt-3\"\n columns={columns}\n data={data.results}\n state={{\n pageIndex: filters.page,\n pageSize: ATTEMPTS_PAGE_SIZE,\n filters: [\n { id: 'emailOrUsername', value: filters.emailOrUsername }\n ],\n sortBy: [\n { id: filters.ordering.replace(/^-/, ''), desc: filters.ordering.startsWith('-') }\n ]\n }}\n fetchData={handleFetchData}\n isFilterable\n isLoading={isLoading}\n isPaginated\n isSortable\n itemCount={data.count}\n manualFilters\n manualPagination\n manualSortBy\n pageSize={ATTEMPTS_PAGE_SIZE}\n pageCount={data.numPages}\n FilterStatusComponent={() => null}\n >\n <DataTable.TableControlBar className=\"bg-light-200 py-3 px-4\" />\n <DataTable.Table />\n <DataTable.EmptyTable content={intl.formatMessage(messages.noAttempts)} />\n <DataTable.TableFooter />\n </DataTable>\n );\n};\n\nexport default AttemptsList;\n"]}
|
|
1
|
+
{"version":3,"file":"AttemptsList.js","sourceRoot":"","sources":["../../../src/specialExams/components/AttemptsList.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { DataTable, IconButton, OverlayTrigger, Popover } from '@openedx/paragon';\nimport { MoreVert } from '@openedx/paragon/icons';\nimport UsernameFilter from '@src/components/UsernameFilter';\nimport { useAttempts } from '@src/specialExams/data/apiHook';\nimport messages from '@src/specialExams/messages';\nimport { Attempt, AttemptAction } from '@src/specialExams/types';\nimport { DataTableFetchDataProps, TableCellValue } from '@src/types';\n\nexport const ATTEMPTS_PAGE_SIZE = 25;\n\ninterface AttemptsListProps {\n onResume: (attempt: Attempt) => void,\n onReset: (attempt: Attempt) => void,\n}\n\nconst AttemptsList = ({ onResume, onReset }: AttemptsListProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams();\n const [filters, setFilters] = useState({ page: 0, emailOrUsername: '', ordering: '' });\n const { data = { results: [], count: 0, numPages: 0 }, isLoading = false } = useAttempts(courseId, {\n ...filters,\n pageSize: ATTEMPTS_PAGE_SIZE\n });\n\n const ActionCustomCell = ({ row: { original } }: TableCellValue<Attempt>) => {\n const [showPopover, setShowPopover] = useState(false);\n\n const handleAction = (action: AttemptAction) => {\n setShowPopover(false);\n if (action === 'resume') {\n onResume(original);\n } else {\n onReset(original);\n }\n };\n\n const popoverContent = (\n <Popover\n id={`popover-${original.user.username}-${original.examName}`}\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={() => handleAction('reset')}\n >\n {intl.formatMessage(messages.reset)}\n </button>\n {!original.readyToResume && original.status === 'error' && (\n <button\n type=\"button\"\n className=\"dropdown-item\"\n onClick={() => handleAction('resume')}\n >\n {intl.formatMessage(messages.resume)}\n </button>\n )}\n </div>\n </Popover.Content>\n </Popover>\n );\n return (\n <>\n <OverlayTrigger\n trigger=\"click\"\n placement=\"bottom-end\"\n overlay={popoverContent}\n rootClose\n show={showPopover}\n onToggle={setShowPopover}\n >\n <IconButton\n alt={intl.formatMessage(messages.actions)}\n className=\"lead\"\n iconAs={MoreVert}\n />\n </OverlayTrigger>\n </>\n );\n };\n\n const columns = useMemo(() => [\n { accessor: 'user.username', Header: intl.formatMessage(messages.username), Filter: UsernameFilter, },\n { accessor: 'examName', Header: intl.formatMessage(messages.examName), disableFilters: true, },\n { accessor: 'allowedTimeLimitMins', Header: intl.formatMessage(messages.timeLimit), disableFilters: true, },\n {\n accessor: 'examType',\n Cell: ({ row }: TableCellValue<Attempt>) => <span className=\"text-capitalize\">{row.original.examType}</span>,\n disableFilters: true,\n Header: intl.formatMessage(messages.type),\n },\n {\n accessor: 'startTime',\n Cell: ({ row }: TableCellValue<Attempt>) => (\n <span>{ row.original.startTime ? `${intl.formatDate(new Date(row.original.startTime), {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n timeZone: 'UTC',\n })} UTC` : ''}\n </span>\n ),\n disableFilters: true,\n Header: intl.formatMessage(messages.startedAt),\n },\n {\n accessor: 'endTime',\n Cell: ({ row }: TableCellValue<Attempt>) => (\n <span>{row.original.endTime ? `${intl.formatDate(new Date(row.original.endTime), {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n timeZone: 'UTC',\n })} UTC` : ''}\n </span>\n ),\n disableFilters: true,\n Header: intl.formatMessage(messages.completedAt),\n },\n {\n accessor: 'status',\n Cell: ({ row }: TableCellValue<Attempt>) => <span className=\"text-capitalize\">{row.original.status}</span>,\n disableFilters: true,\n Header: intl.formatMessage(messages.status),\n },\n {\n accessor: 'readyToResume',\n Cell: ({ row }: TableCellValue<Attempt>) => (\n <span className=\"text-capitalize\">{row.original.readyToResume ? intl.formatMessage(messages.true) : ''}</span>\n ),\n disableFilters: true,\n Header: intl.formatMessage(messages.readyForResume),\n }\n ], [intl]);\n\n const additionalColumns = [{\n id: 'actions',\n Header: '',\n Cell: ActionCustomCell,\n }];\n\n const handleFetchData = (data: DataTableFetchDataProps) => {\n const emailOrUsernameFilter = data.filters?.find((f) => f.id === 'user.username');\n const newEmailOrUsername = emailOrUsernameFilter ? emailOrUsernameFilter.value : '';\n const newOrdering = data.sortBy?.[0] ? `${data.sortBy[0].desc ? '-' : ''}${data.sortBy[0].id}` : '';\n const filtersChanged = newEmailOrUsername !== filters.emailOrUsername || newOrdering !== filters.ordering;\n if (filtersChanged) {\n setFilters((prevFilters) => ({ ...prevFilters, emailOrUsername: newEmailOrUsername, ordering: newOrdering, page: 0 }));\n return;\n }\n if (data.pageIndex !== filters.page) {\n setFilters((prevFilters) => ({ ...prevFilters, page: data.pageIndex }));\n }\n };\n\n return (\n <DataTable\n additionalColumns={additionalColumns}\n className=\"mt-3\"\n columns={columns}\n data={data.results}\n state={{\n pageIndex: filters.page,\n pageSize: ATTEMPTS_PAGE_SIZE,\n filters: [\n { id: 'emailOrUsername', value: filters.emailOrUsername }\n ],\n sortBy: [\n { id: filters.ordering.replace(/^-/, ''), desc: filters.ordering.startsWith('-') }\n ]\n }}\n fetchData={handleFetchData}\n isFilterable\n isLoading={isLoading}\n isPaginated\n isSortable\n itemCount={data.count}\n manualFilters\n manualPagination\n manualSortBy\n pageSize={ATTEMPTS_PAGE_SIZE}\n pageCount={data.numPages}\n FilterStatusComponent={() => null}\n >\n <DataTable.TableControlBar className=\"bg-light-200 py-3 px-4\" />\n <DataTable.Table />\n <DataTable.EmptyTable content={intl.formatMessage(messages.noAttempts)} />\n <DataTable.TableFooter />\n </DataTable>\n );\n};\n\nexport default AttemptsList;\n"]}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { DataList } from '../../types';
|
|
2
|
-
import { AddAllowanceParams, Allowance, Attempt, AttemptsParams, DeleteAllowanceParams, SpecialExam } from '
|
|
2
|
+
import { AddAllowanceParams, Allowance, Attempt, AttemptsParams, DeleteAllowanceParams, ResetAttemptParams, ResumeAttemptParams, SpecialExam } from '../../specialExams/types';
|
|
3
3
|
export declare const getAttempts: (courseId: string, params: AttemptsParams) => Promise<DataList<Attempt>>;
|
|
4
4
|
export declare const getAllowances: (courseId: string, params: AttemptsParams) => Promise<DataList<Allowance>>;
|
|
5
5
|
export declare const addAllowance: (courseId: string, newAllowance: AddAllowanceParams) => Promise<Allowance[]>;
|
|
6
6
|
export declare const deleteAllowance: (courseId: string, params: DeleteAllowanceParams) => Promise<void>;
|
|
7
7
|
export declare const getSpecialExams: (courseId: string, examType: string) => Promise<SpecialExam[]>;
|
|
8
|
+
export declare const resetAttempt: (courseId: string, params: ResetAttemptParams) => Promise<any>;
|
|
9
|
+
export declare const resumeAttempt: (params: ResumeAttemptParams) => Promise<any>;
|
|
@@ -52,4 +52,16 @@ export const getSpecialExams = (courseId, examType) => __awaiter(void 0, void 0,
|
|
|
52
52
|
});
|
|
53
53
|
return camelCaseObject(data);
|
|
54
54
|
});
|
|
55
|
+
export const resetAttempt = (courseId, params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
56
|
+
const { data } = yield getAuthenticatedHttpClient().post(`${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/special_exams/${params.examId}/reset/${params.username}`);
|
|
57
|
+
return camelCaseObject(data);
|
|
58
|
+
});
|
|
59
|
+
export const resumeAttempt = (params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
60
|
+
const { userId, attemptId } = params;
|
|
61
|
+
const formData = new FormData();
|
|
62
|
+
formData.append('user_id', userId.toString());
|
|
63
|
+
formData.append('action', 'mark_ready_to_resume');
|
|
64
|
+
const { data } = yield getAuthenticatedHttpClient().put(`${getApiBaseUrl()}/api/edx_proctoring/v1/proctored_exam/attempt/${attemptId}`, formData);
|
|
65
|
+
return camelCaseObject(data);
|
|
66
|
+
});
|
|
55
67
|
//# sourceMappingURL=api.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/specialExams/data/api.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACtG,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAI9C,MAAM,cAAc,GAAG,CAAC,MAAsB,EAAE,EAAE;IAChD,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,QAAQ,EAAE,CAAC;QACpB,MAAM,iBAAiB,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAE1D,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE1F,WAAW,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,aAAa,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAO,QAAgB,EAAE,MAAsB,EAA8B,EAAE;IACxG,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAE3C,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CACrD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,2BAA2B,WAAW,CAAC,QAAQ,EAAE,EAAE,CAC5G,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAO,QAAgB,EAAE,MAAsB,EAAgC,EAAE;IAC5G,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAE3C,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CACrD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,6BAA6B,WAAW,CAAC,QAAQ,EAAE,EAAE,CAC9G,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAO,QAAgB,EAAE,YAAgC,EAAwB,EAAE;IAC7G,MAAM,qBAAqB,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;IAC5D,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,IAAI,CACtD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,2BAA2B,EACnF,qBAAqB,CACtB,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAO,QAAgB,EAAE,MAA6B,EAAiB,EAAE;IACtG,MAAM,eAAe,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,0BAA0B,EAAE,CAAC,MAAM,CACvC,GAAG,aAAa,EAAE,8BAA8B,QAAQ,kBAAkB,MAAM,CAAC,MAAM,YAAY,EAAE;QACnG,IAAI,EAAE,eAAe;KACtB,CACF,CAAC;AACJ,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAO,QAAgB,EAAE,QAAgB,EAA0B,EAAE;IAClG,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CACrD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,gBAAgB,EAAE;QACxE,MAAM,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE;KAChC,CACF,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC","sourcesContent":["import { getAuthenticatedHttpClient, camelCaseObject, snakeCaseObject } from '@openedx/frontend-base';\nimport { snakeCase } from 'lodash';\nimport { getApiBaseUrl } from '@src/data/api';\nimport { DataList } from '@src/types';\nimport { AddAllowanceParams, Allowance, Attempt, AttemptsParams, DeleteAllowanceParams, SpecialExam } from '
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/specialExams/data/api.ts"],"names":[],"mappings":"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","sourcesContent":["import { getAuthenticatedHttpClient, camelCaseObject, snakeCaseObject } from '@openedx/frontend-base';\nimport { snakeCase } from 'lodash';\nimport { getApiBaseUrl } from '@src/data/api';\nimport { DataList } from '@src/types';\nimport { AddAllowanceParams, Allowance, Attempt, AttemptsParams, DeleteAllowanceParams, ResetAttemptParams, ResumeAttemptParams, SpecialExam } from '@src/specialExams/types';\n\nconst getQueryParams = (params: AttemptsParams) => {\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.ordering) {\n const hasNegativePrefix = params.ordering.startsWith('-');\n\n const orderingParam = params.ordering.split('.').map((part) => snakeCase(part)).join('.');\n\n queryParams.append('ordering', `${hasNegativePrefix ? '-' : ''}${orderingParam}`);\n }\n\n return queryParams;\n};\n\nexport const getAttempts = async (courseId: string, params: AttemptsParams): Promise<DataList<Attempt>> => {\n const queryParams = getQueryParams(params);\n\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/special_exams/attempts?${queryParams.toString()}`\n );\n return camelCaseObject(data);\n};\n\nexport const getAllowances = async (courseId: string, params: AttemptsParams): Promise<DataList<Allowance>> => {\n const queryParams = getQueryParams(params);\n\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/special_exams/allowances?${queryParams.toString()}`\n );\n return camelCaseObject(data);\n};\n\nexport const addAllowance = async (courseId: string, newAllowance: AddAllowanceParams): Promise<Allowance[]> => {\n const newAllowanceSnakeCase = snakeCaseObject(newAllowance);\n const { data } = await getAuthenticatedHttpClient().post(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/special_exams/allowances`,\n newAllowanceSnakeCase\n );\n return camelCaseObject(data);\n};\n\nexport const deleteAllowance = async (courseId: string, params: DeleteAllowanceParams): Promise<void> => {\n const snakeCaseParams = snakeCaseObject(params);\n await getAuthenticatedHttpClient().delete(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/special_exams/${params.examId}/allowance`, {\n data: snakeCaseParams\n }\n );\n};\n\nexport const getSpecialExams = async (courseId: string, examType: string): Promise<SpecialExam[]> => {\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/special_exams`, {\n params: { exam_type: examType }\n }\n );\n return camelCaseObject(data);\n};\n\nexport const resetAttempt = async (courseId: string, params: ResetAttemptParams) => {\n const { data } = await getAuthenticatedHttpClient().post(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/special_exams/${params.examId}/reset/${params.username}`\n );\n return camelCaseObject(data);\n};\n\nexport const resumeAttempt = async (params: ResumeAttemptParams) => {\n const { userId, attemptId } = params;\n const formData = new FormData();\n formData.append('user_id', userId.toString());\n formData.append('action', 'mark_ready_to_resume');\n const { data } = await getAuthenticatedHttpClient().put(\n `${getApiBaseUrl()}/api/edx_proctoring/v1/proctored_exam/attempt/${attemptId}`,\n formData\n );\n return camelCaseObject(data);\n};\n"]}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { AddAllowanceParams, AttemptsParams, DeleteAllowanceParams } from '
|
|
2
|
-
export declare const useAttempts: (courseId: string, params: AttemptsParams, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<import("../../types").DataList<import("
|
|
3
|
-
export declare const useAllowances: (courseId: string, params: AttemptsParams) => import("@tanstack/react-query").UseQueryResult<import("../../types").DataList<import("
|
|
4
|
-
export declare const useAddAllowance: (courseId: string) => import("@tanstack/react-query").UseMutationResult<import("
|
|
1
|
+
import { AddAllowanceParams, AttemptsParams, DeleteAllowanceParams, ResetAttemptParams, ResumeAttemptParams } from '../../specialExams/types';
|
|
2
|
+
export declare const useAttempts: (courseId: string, params: AttemptsParams, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<import("../../types").DataList<import("../../specialExams/types").Attempt>, Error>;
|
|
3
|
+
export declare const useAllowances: (courseId: string, params: AttemptsParams) => import("@tanstack/react-query").UseQueryResult<import("../../types").DataList<import("../../specialExams/types").Allowance>, Error>;
|
|
4
|
+
export declare const useAddAllowance: (courseId: string) => import("@tanstack/react-query").UseMutationResult<import("../../specialExams/types").Allowance[], Error, AddAllowanceParams, unknown>;
|
|
5
5
|
export declare const useDeleteAllowance: (courseId: string) => import("@tanstack/react-query").UseMutationResult<void, Error, DeleteAllowanceParams, unknown>;
|
|
6
|
-
export declare const useSpecialExams: (courseId: string, examType: string) => import("@tanstack/react-query").UseQueryResult<import("
|
|
6
|
+
export declare const useSpecialExams: (courseId: string, examType: string) => import("@tanstack/react-query").UseQueryResult<import("../../specialExams/types").SpecialExam[], Error>;
|
|
7
|
+
export declare const useResetAttempt: (courseId: string) => import("@tanstack/react-query").UseMutationResult<any, Error, ResetAttemptParams, unknown>;
|
|
8
|
+
export declare const useResumeAttempt: (courseId: string) => import("@tanstack/react-query").UseMutationResult<any, Error, ResumeAttemptParams, unknown>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
2
|
-
import { addAllowance, deleteAllowance, getAllowances, getAttempts, getSpecialExams } from '
|
|
3
|
-
import { specialExamsQueryKeys } from '
|
|
2
|
+
import { addAllowance, deleteAllowance, getAllowances, getAttempts, getSpecialExams, resetAttempt, resumeAttempt } from '../../specialExams/data/api';
|
|
3
|
+
import { specialExamsQueryKeys } from '../../specialExams/data/queryKeys';
|
|
4
4
|
export const useAttempts = (courseId, params, enabled = true) => (useQuery({
|
|
5
5
|
queryKey: specialExamsQueryKeys.attempts(courseId, params),
|
|
6
6
|
queryFn: () => getAttempts(courseId, params),
|
|
@@ -34,4 +34,22 @@ export const useSpecialExams = (courseId, examType) => (useQuery({
|
|
|
34
34
|
queryFn: () => getSpecialExams(courseId, examType),
|
|
35
35
|
enabled: !!courseId && !!examType,
|
|
36
36
|
}));
|
|
37
|
+
export const useResetAttempt = (courseId) => {
|
|
38
|
+
const queryClient = useQueryClient();
|
|
39
|
+
return useMutation({
|
|
40
|
+
mutationFn: (params) => resetAttempt(courseId, params),
|
|
41
|
+
onSuccess: () => {
|
|
42
|
+
queryClient.invalidateQueries({ queryKey: specialExamsQueryKeys.attempts(courseId), exact: false });
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
export const useResumeAttempt = (courseId) => {
|
|
47
|
+
const queryClient = useQueryClient();
|
|
48
|
+
return useMutation({
|
|
49
|
+
mutationFn: (params) => resumeAttempt(params),
|
|
50
|
+
onSuccess: () => {
|
|
51
|
+
queryClient.invalidateQueries({ queryKey: specialExamsQueryKeys.attempts(courseId), exact: false });
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
};
|
|
37
55
|
//# sourceMappingURL=apiHook.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiHook.js","sourceRoot":"","sources":["../../../src/specialExams/data/apiHook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"apiHook.js","sourceRoot":"","sources":["../../../src/specialExams/data/apiHook.ts"],"names":[],"mappings":"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","sourcesContent":["import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { addAllowance, deleteAllowance, getAllowances, getAttempts, getSpecialExams, resetAttempt, resumeAttempt } from '@src/specialExams/data/api';\nimport { specialExamsQueryKeys } from '@src/specialExams/data/queryKeys';\nimport { AddAllowanceParams, AttemptsParams, DeleteAllowanceParams, ResetAttemptParams, ResumeAttemptParams } from '@src/specialExams/types';\n\nexport const useAttempts = (courseId: string, params: AttemptsParams, enabled = true) => (\n useQuery({\n queryKey: specialExamsQueryKeys.attempts(courseId, params),\n queryFn: () => getAttempts(courseId, params),\n enabled: !!courseId && enabled,\n })\n);\n\nexport const useAllowances = (courseId: string, params: AttemptsParams) => (\n useQuery({\n queryKey: specialExamsQueryKeys.allowances(courseId, params),\n queryFn: () => getAllowances(courseId, params),\n enabled: !!courseId,\n })\n);\n\nexport const useAddAllowance = (courseId: string) => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (newAllowance: AddAllowanceParams) =>\n addAllowance(courseId, newAllowance),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: specialExamsQueryKeys.allowances(courseId), exact: false });\n },\n });\n};\n\nexport const useDeleteAllowance = (courseId: string) => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (params: DeleteAllowanceParams) => deleteAllowance(courseId, params),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: specialExamsQueryKeys.allowances(courseId), exact: false });\n },\n });\n};\n\nexport const useSpecialExams = (courseId: string, examType: string) => (\n useQuery({\n queryKey: specialExamsQueryKeys.specialExams(courseId, examType),\n queryFn: () => getSpecialExams(courseId, examType),\n enabled: !!courseId && !!examType,\n })\n);\n\nexport const useResetAttempt = (courseId: string) => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (params: ResetAttemptParams) => resetAttempt(courseId, params),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: specialExamsQueryKeys.attempts(courseId), exact: false });\n },\n });\n};\n\nexport const useResumeAttempt = (courseId: string) => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (params: ResumeAttemptParams) => resumeAttempt(params),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: specialExamsQueryKeys.attempts(courseId), exact: false });\n },\n });\n};\n"]}
|
|
@@ -2,7 +2,7 @@ import { AttemptsParams } from '../types';
|
|
|
2
2
|
export declare const specialExamsQueryKeys: {
|
|
3
3
|
all: readonly ["org.openedx.frontend.app.instructorDashboard", "specialExams"];
|
|
4
4
|
byCourse: (courseId: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "specialExams", string];
|
|
5
|
-
attempts: (courseId: string, params
|
|
5
|
+
attempts: (courseId: string, params?: AttemptsParams) => readonly ["org.openedx.frontend.app.instructorDashboard", "specialExams", string, "attempts", number, string, string];
|
|
6
6
|
allowances: (courseId: string, params?: AttemptsParams) => readonly ["org.openedx.frontend.app.instructorDashboard", "specialExams", string, "allowances", number, string, string];
|
|
7
7
|
specialExams: (courseId: string, examType: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "specialExams", string, "specialExams", string];
|
|
8
8
|
};
|
|
@@ -2,7 +2,7 @@ import { appId } from '../../constants';
|
|
|
2
2
|
export const specialExamsQueryKeys = {
|
|
3
3
|
all: [appId, 'specialExams'],
|
|
4
4
|
byCourse: (courseId) => [...specialExamsQueryKeys.all, courseId],
|
|
5
|
-
attempts: (courseId, params) => [...specialExamsQueryKeys.byCourse(courseId), 'attempts', params.page, params.emailOrUsername, params.ordering],
|
|
5
|
+
attempts: (courseId, params) => [...specialExamsQueryKeys.byCourse(courseId), 'attempts', (params === null || params === void 0 ? void 0 : params.page) || 1, (params === null || params === void 0 ? void 0 : params.emailOrUsername) || '', (params === null || params === void 0 ? void 0 : params.ordering) || ''],
|
|
6
6
|
allowances: (courseId, params) => [...specialExamsQueryKeys.byCourse(courseId), 'allowances', (params === null || params === void 0 ? void 0 : params.page) || 1, (params === null || params === void 0 ? void 0 : params.emailOrUsername) || '', (params === null || params === void 0 ? void 0 : params.ordering) || ''],
|
|
7
7
|
specialExams: (courseId, examType) => [...specialExamsQueryKeys.byCourse(courseId), 'specialExams', examType],
|
|
8
8
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryKeys.js","sourceRoot":"","sources":["../../../src/specialExams/data/queryKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,GAAG,EAAE,CAAC,KAAK,EAAE,cAAc,CAAU;IACrC,QAAQ,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC,GAAG,qBAAqB,CAAC,GAAG,EAAE,QAAQ,CAAU;IACjF,QAAQ,EAAE,CAAC,QAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"queryKeys.js","sourceRoot":"","sources":["../../../src/specialExams/data/queryKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,GAAG,EAAE,CAAC,KAAK,EAAE,cAAc,CAAU;IACrC,QAAQ,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC,GAAG,qBAAqB,CAAC,GAAG,EAAE,QAAQ,CAAU;IACjF,QAAQ,EAAE,CAAC,QAAgB,EAAE,MAAuB,EAAE,EAAE,CAAC,CAAC,GAAG,qBAAqB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,KAAI,CAAC,EAAE,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,eAAe,KAAI,EAAE,EAAE,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,KAAI,EAAE,CAAU;IACrM,UAAU,EAAE,CAAC,QAAgB,EAAE,MAAuB,EAAE,EAAE,CAAC,CAAC,GAAG,qBAAqB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,KAAI,CAAC,EAAE,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,eAAe,KAAI,EAAE,EAAE,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,KAAI,EAAE,CAAU;IACzM,YAAY,EAAE,CAAC,QAAgB,EAAE,QAAgB,EAAE,EAAE,CAAC,CAAC,GAAG,qBAAqB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,EAAE,QAAQ,CAAU;CACvI,CAAC","sourcesContent":["import { appId } from '@src/constants';\nimport { AttemptsParams } from '../types';\n\nexport const specialExamsQueryKeys = {\n all: [appId, 'specialExams'] as const,\n byCourse: (courseId: string) => [...specialExamsQueryKeys.all, courseId] as const,\n attempts: (courseId: string, params?: AttemptsParams) => [...specialExamsQueryKeys.byCourse(courseId), 'attempts', params?.page || 1, params?.emailOrUsername || '', params?.ordering || ''] as const,\n allowances: (courseId: string, params?: AttemptsParams) => [...specialExamsQueryKeys.byCourse(courseId), 'allowances', params?.page || 1, params?.emailOrUsername || '', params?.ordering || ''] as const,\n specialExams: (courseId: string, examType: string) => [...specialExamsQueryKeys.byCourse(courseId), 'specialExams', examType] as const,\n};\n"]}
|
|
@@ -224,5 +224,65 @@ declare const messages: {
|
|
|
224
224
|
defaultMessage: string;
|
|
225
225
|
description: string;
|
|
226
226
|
};
|
|
227
|
+
readyForResume: {
|
|
228
|
+
id: string;
|
|
229
|
+
defaultMessage: string;
|
|
230
|
+
description: string;
|
|
231
|
+
};
|
|
232
|
+
resume: {
|
|
233
|
+
id: string;
|
|
234
|
+
defaultMessage: string;
|
|
235
|
+
description: string;
|
|
236
|
+
};
|
|
237
|
+
reset: {
|
|
238
|
+
id: string;
|
|
239
|
+
defaultMessage: string;
|
|
240
|
+
description: string;
|
|
241
|
+
};
|
|
242
|
+
true: {
|
|
243
|
+
id: string;
|
|
244
|
+
defaultMessage: string;
|
|
245
|
+
description: string;
|
|
246
|
+
};
|
|
247
|
+
successOnReset: {
|
|
248
|
+
id: string;
|
|
249
|
+
defaultMessage: string;
|
|
250
|
+
description: string;
|
|
251
|
+
};
|
|
252
|
+
errorOnReset: {
|
|
253
|
+
id: string;
|
|
254
|
+
defaultMessage: string;
|
|
255
|
+
description: string;
|
|
256
|
+
};
|
|
257
|
+
close: {
|
|
258
|
+
id: string;
|
|
259
|
+
defaultMessage: string;
|
|
260
|
+
description: string;
|
|
261
|
+
};
|
|
262
|
+
confirmationModal: {
|
|
263
|
+
id: string;
|
|
264
|
+
defaultMessage: string;
|
|
265
|
+
description: string;
|
|
266
|
+
};
|
|
267
|
+
confirmationMessageReset: {
|
|
268
|
+
id: string;
|
|
269
|
+
defaultMessage: string;
|
|
270
|
+
description: string;
|
|
271
|
+
};
|
|
272
|
+
confirmationMessageResume: {
|
|
273
|
+
id: string;
|
|
274
|
+
defaultMessage: string;
|
|
275
|
+
description: string;
|
|
276
|
+
};
|
|
277
|
+
errorOnResume: {
|
|
278
|
+
id: string;
|
|
279
|
+
defaultMessage: string;
|
|
280
|
+
description: string;
|
|
281
|
+
};
|
|
282
|
+
successOnResume: {
|
|
283
|
+
id: string;
|
|
284
|
+
defaultMessage: string;
|
|
285
|
+
description: string;
|
|
286
|
+
};
|
|
227
287
|
};
|
|
228
288
|
export default messages;
|
|
@@ -224,6 +224,66 @@ const messages = defineMessages({
|
|
|
224
224
|
id: 'instruct.specialExams.cannotModifyAllowance',
|
|
225
225
|
defaultMessage: 'Cannot {action} allowance: {username} has already attempted the exam',
|
|
226
226
|
description: 'Warning message shown when trying to edit or delete an allowance for a student who has already attempted the exam'
|
|
227
|
+
},
|
|
228
|
+
readyForResume: {
|
|
229
|
+
id: 'instruct.specialExams.readyForResume',
|
|
230
|
+
defaultMessage: 'Ready to Resume?',
|
|
231
|
+
description: 'Label for whether the exam attempt is ready to be resumed in the exam attempts list',
|
|
232
|
+
},
|
|
233
|
+
resume: {
|
|
234
|
+
id: 'instruct.specialExams.resume',
|
|
235
|
+
defaultMessage: 'Resume',
|
|
236
|
+
description: 'Label for resume action in exam attempts list',
|
|
237
|
+
},
|
|
238
|
+
reset: {
|
|
239
|
+
id: 'instruct.specialExams.reset',
|
|
240
|
+
defaultMessage: 'Reset',
|
|
241
|
+
description: 'Label for reset action in exam attempts list',
|
|
242
|
+
},
|
|
243
|
+
true: {
|
|
244
|
+
id: 'instruct.specialExams.true',
|
|
245
|
+
defaultMessage: 'True',
|
|
246
|
+
description: 'Display value for a boolean true value'
|
|
247
|
+
},
|
|
248
|
+
successOnReset: {
|
|
249
|
+
id: 'instruct.specialExams.successOnReset',
|
|
250
|
+
defaultMessage: 'Successfully reset attempt on {examName} for {student}.',
|
|
251
|
+
description: 'Success message shown after resetting an exam attempt'
|
|
252
|
+
},
|
|
253
|
+
errorOnReset: {
|
|
254
|
+
id: 'instruct.specialExams.errorOnReset',
|
|
255
|
+
defaultMessage: 'An error occurred while resetting the attempt. Please try again.',
|
|
256
|
+
description: 'Error message shown when resetting an exam attempt fails'
|
|
257
|
+
},
|
|
258
|
+
close: {
|
|
259
|
+
id: 'instruct.specialExams.close',
|
|
260
|
+
defaultMessage: 'Close',
|
|
261
|
+
description: 'Label for close button'
|
|
262
|
+
},
|
|
263
|
+
confirmationModal: {
|
|
264
|
+
id: 'instruct.specialExams.confirmationModal',
|
|
265
|
+
defaultMessage: 'Confirmation Modal',
|
|
266
|
+
description: 'Confirmation modal title'
|
|
267
|
+
},
|
|
268
|
+
confirmationMessageReset: {
|
|
269
|
+
id: 'instruct.specialExams.confirmationMessageReset',
|
|
270
|
+
defaultMessage: 'Are you sure you want to remove this student\'s exam attempt?',
|
|
271
|
+
description: 'Confirmation message shown when resetting an exam attempt'
|
|
272
|
+
},
|
|
273
|
+
confirmationMessageResume: {
|
|
274
|
+
id: 'instruct.specialExams.confirmationMessageResume',
|
|
275
|
+
defaultMessage: 'Are you sure you want to resume this exam attempt?',
|
|
276
|
+
description: 'Confirmation message shown when resuming an exam attempt'
|
|
277
|
+
},
|
|
278
|
+
errorOnResume: {
|
|
279
|
+
id: 'instruct.specialExams.errorOnResume',
|
|
280
|
+
defaultMessage: 'An error occurred while resuming the attempt. Please try again.',
|
|
281
|
+
description: 'Error message shown when resuming an exam attempt fails'
|
|
282
|
+
},
|
|
283
|
+
successOnResume: {
|
|
284
|
+
id: 'instruct.specialExams.successOnResume',
|
|
285
|
+
defaultMessage: 'Successfully resumed attempt for {student}.',
|
|
286
|
+
description: 'Success message shown after resuming an exam attempt'
|
|
227
287
|
}
|
|
228
288
|
});
|
|
229
289
|
export default messages;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/specialExams/messages.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n specialExamsTitle: {\n id: 'instruct.specialExams.title',\n defaultMessage: 'Special Exams',\n description: 'Title for the special exams page'\n },\n examAttempts: {\n id: 'instruct.specialExams.examAttempts',\n defaultMessage: 'Exam Attempts',\n description: 'Label for the exam attempts tab'\n },\n allowances: {\n id: 'instruct.specialExams.allowances',\n defaultMessage: 'Allowances',\n description: 'Label for the allowances tab'\n },\n username: {\n id: 'instruct.specialExams.username',\n defaultMessage: 'Username',\n description: 'Column header for username in exam attempts list',\n },\n examName: {\n id: 'instruct.specialExams.examName',\n defaultMessage: 'Exam Name',\n description: 'Column header for exam name in exam attempts list',\n },\n timeLimit: {\n id: 'instruct.specialExams.timeLimit',\n defaultMessage: 'Time Limit',\n description: 'Column header for time limit in exam attempts list',\n },\n type: {\n id: 'instruct.specialExams.type',\n defaultMessage: 'Type',\n description: 'Column header for type in exam attempts list',\n },\n startedAt: {\n id: 'instruct.specialExams.startedAt',\n defaultMessage: 'Started At',\n description: 'Column header for started at in exam attempts list',\n },\n completedAt: {\n id: 'instruct.specialExams.completedAt',\n defaultMessage: 'Completed At',\n description: 'Column header for completed at in exam attempts list',\n },\n status: {\n id: 'instruct.specialExams.status',\n defaultMessage: 'Status',\n description: 'Column header for status in exam attempts list',\n },\n noAttempts: {\n id: 'instruct.specialExams.noAttempts',\n defaultMessage: 'No exam attempts found',\n description: 'Message displayed when there are no exam attempts to show',\n },\n noAllowances: {\n id: 'instruct.specialExams.noAllowances',\n defaultMessage: 'No allowances found',\n description: 'Message displayed when there are no allowances to show',\n },\n editAllowance: {\n id: 'instruct.specialExams.editAllowance',\n defaultMessage: 'Edit Allowance',\n description: 'ARIA label for actions button and modal title when editing an allowance',\n },\n email: {\n id: 'instruct.specialExams.email',\n defaultMessage: 'Email',\n description: 'Column header for email in allowances list',\n },\n allowanceType: {\n id: 'instruct.specialExams.allowanceType',\n defaultMessage: 'Allowance Type',\n description: 'Column header for allowance type in allowances list',\n },\n allowanceValue: {\n id: 'instruct.specialExams.allowanceValue',\n defaultMessage: 'Allowance Value',\n description: 'Column header for allowance value in allowances list',\n },\n addAllowance: {\n id: 'instruct.specialExams.addAllowance',\n defaultMessage: 'Add Allowance',\n description: 'Label for the button to add a new allowance',\n },\n cancel: {\n id: 'instruct.specialExams.cancel',\n defaultMessage: 'Cancel',\n description: 'Label for cancel button in add/edit allowance modal',\n },\n createAllowance: {\n id: 'instruct.specialExams.createAllowance',\n defaultMessage: 'Create Allowance',\n description: 'Label for the create button in add allowance modal',\n },\n specifyLearners: {\n id: 'instruct.specialExams.specifyLearners',\n defaultMessage: 'Specify Learners',\n description: 'Label for the field to specify learners in add allowance modal',\n },\n specifyLearnersPlaceholder: {\n id: 'instruct.specialExams.specifyLearnersPlaceholder',\n defaultMessage: 'Learner email addresses and/or usernames separated by commas',\n description: 'Placeholder for the field to specify learners in add allowance modal',\n },\n selectExamType: {\n id: 'instruct.specialExams.selectExamType',\n defaultMessage: 'Select Exam Type',\n description: 'Label for the field to select exam type in add allowance modal',\n },\n selectExams: {\n id: 'instruct.specialExams.selectExams',\n defaultMessage: 'Select Exam(s)',\n description: 'Label for the field to select exams in add allowance modal',\n },\n selectAllowanceType: {\n id: 'instruct.specialExams.selectAllowanceType',\n defaultMessage: 'Select Allowance Type',\n description: 'Label for the field to select allowance type in add allowance modal',\n },\n addTime: {\n id: 'instruct.specialExams.addTime',\n defaultMessage: 'Add Time',\n description: 'Label for the field to enter time value in add allowance modal',\n },\n addTimePlaceholder: {\n id: 'instruct.specialExams.addTimePlaceholder',\n defaultMessage: 'Time (minutes)',\n description: 'Placeholder for the field to enter time value in add allowance modal',\n },\n actions: {\n id: 'instruct.specialExams.actions',\n defaultMessage: 'Actions',\n description: 'ARIA label for actions button in allowances list',\n },\n proctored: {\n id: 'instruct.specialExams.proctored',\n defaultMessage: 'Proctored',\n description: 'Label for whether the special exam is proctored in the list of special exams',\n },\n timed: {\n id: 'instruct.specialExams.timed',\n defaultMessage: 'Timed',\n description: 'Label for whether the special exam is timed in the list of special exams',\n },\n timeMultiplier: {\n id: 'instruct.specialExams.timeMultiplier',\n defaultMessage: 'Time Multiplier',\n description: 'Label for the time multiplier value in the list of special exams',\n },\n additionalTime: {\n id: 'instruct.specialExams.additionalTime',\n defaultMessage: 'Additional Time',\n description: 'Label for the additional time value in the list of special exams',\n },\n reviewPolicy: {\n id: 'instruct.specialExams.reviewPolicy',\n defaultMessage: 'Review Policy Exception',\n description: 'Label for the review policy exception in the list of special exams',\n },\n exceptionPlaceholder: {\n id: 'instruct.specialExams.exceptionPlaceholder',\n defaultMessage: 'Exception',\n description: 'Placeholder for the review policy exception description in add allowance modal',\n },\n timeMultiplierPlaceholder: {\n id: 'instruct.specialExams.timeMultiplierPlaceholder',\n defaultMessage: 'Multiplier (number > 1)',\n description: 'Placeholder for the time multiplier value in add allowance modal',\n },\n edit: {\n id: 'instruct.specialExams.edit',\n defaultMessage: 'Edit',\n description: 'Label for edit action in allowance list',\n },\n delete: {\n id: 'instruct.specialExams.delete',\n defaultMessage: 'Delete',\n description: 'Label for delete action in allowance list',\n },\n deleteAllowance: {\n id: 'instruct.specialExams.deleteAllowance',\n defaultMessage: 'Delete Allowance',\n description: 'Title for delete allowance confirmation modal'\n },\n deleteConfirmation: {\n id: 'instruct.specialExams.deleteConfirmation',\n defaultMessage: 'Delete allowance for {user} for {examName}?',\n description: 'Delete confirmation message'\n },\n deleteError: {\n id: 'instruct.specialExams.deleteError',\n defaultMessage: 'An error occurred while deleting the allowance. Please try again.',\n description: 'Error message displayed when there is an issue deleting an allowance'\n },\n addAdditionalTimeGranted: {\n id: 'instruct.specialExams.addAdditionalTimeGranted',\n defaultMessage: 'Add Time',\n description: 'Label for additional time granted field in add allowance modal',\n },\n addReviewPolicyException: {\n id: 'instruct.specialExams.addReviewPolicyException',\n defaultMessage: 'Add Policy Exception',\n description: 'Label for review policy exception field in add allowance modal',\n },\n addTimeMultiplier: {\n id: 'instruct.specialExams.addTimeMultiplier',\n defaultMessage: 'Add Time Multiplier',\n description: 'Label for time multiplier field in add allowance modal',\n },\n addAllowanceError: {\n id: 'instruct.specialExams.addAllowanceError',\n defaultMessage: 'An error occurred while adding the allowance. Please try again.',\n description: 'Error message displayed when there is an issue adding a new allowance'\n },\n editAllowanceError: {\n id: 'instruct.specialExams.editAllowanceError',\n defaultMessage: 'An error occurred while editing the allowance. Please try again.',\n description: 'Error message displayed when there is an issue editing an allowance'\n },\n cannotModifyAllowance: {\n id: 'instruct.specialExams.cannotModifyAllowance',\n defaultMessage: 'Cannot {action} allowance: {username} has already attempted the exam',\n description: 'Warning message shown when trying to edit or delete an allowance for a student who has already attempted the exam'\n }\n});\n\nexport default messages;\n"]}
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/specialExams/messages.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n specialExamsTitle: {\n id: 'instruct.specialExams.title',\n defaultMessage: 'Special Exams',\n description: 'Title for the special exams page'\n },\n examAttempts: {\n id: 'instruct.specialExams.examAttempts',\n defaultMessage: 'Exam Attempts',\n description: 'Label for the exam attempts tab'\n },\n allowances: {\n id: 'instruct.specialExams.allowances',\n defaultMessage: 'Allowances',\n description: 'Label for the allowances tab'\n },\n username: {\n id: 'instruct.specialExams.username',\n defaultMessage: 'Username',\n description: 'Column header for username in exam attempts list',\n },\n examName: {\n id: 'instruct.specialExams.examName',\n defaultMessage: 'Exam Name',\n description: 'Column header for exam name in exam attempts list',\n },\n timeLimit: {\n id: 'instruct.specialExams.timeLimit',\n defaultMessage: 'Time Limit',\n description: 'Column header for time limit in exam attempts list',\n },\n type: {\n id: 'instruct.specialExams.type',\n defaultMessage: 'Type',\n description: 'Column header for type in exam attempts list',\n },\n startedAt: {\n id: 'instruct.specialExams.startedAt',\n defaultMessage: 'Started At',\n description: 'Column header for started at in exam attempts list',\n },\n completedAt: {\n id: 'instruct.specialExams.completedAt',\n defaultMessage: 'Completed At',\n description: 'Column header for completed at in exam attempts list',\n },\n status: {\n id: 'instruct.specialExams.status',\n defaultMessage: 'Status',\n description: 'Column header for status in exam attempts list',\n },\n noAttempts: {\n id: 'instruct.specialExams.noAttempts',\n defaultMessage: 'No exam attempts found',\n description: 'Message displayed when there are no exam attempts to show',\n },\n noAllowances: {\n id: 'instruct.specialExams.noAllowances',\n defaultMessage: 'No allowances found',\n description: 'Message displayed when there are no allowances to show',\n },\n editAllowance: {\n id: 'instruct.specialExams.editAllowance',\n defaultMessage: 'Edit Allowance',\n description: 'ARIA label for actions button and modal title when editing an allowance',\n },\n email: {\n id: 'instruct.specialExams.email',\n defaultMessage: 'Email',\n description: 'Column header for email in allowances list',\n },\n allowanceType: {\n id: 'instruct.specialExams.allowanceType',\n defaultMessage: 'Allowance Type',\n description: 'Column header for allowance type in allowances list',\n },\n allowanceValue: {\n id: 'instruct.specialExams.allowanceValue',\n defaultMessage: 'Allowance Value',\n description: 'Column header for allowance value in allowances list',\n },\n addAllowance: {\n id: 'instruct.specialExams.addAllowance',\n defaultMessage: 'Add Allowance',\n description: 'Label for the button to add a new allowance',\n },\n cancel: {\n id: 'instruct.specialExams.cancel',\n defaultMessage: 'Cancel',\n description: 'Label for cancel button in add/edit allowance modal',\n },\n createAllowance: {\n id: 'instruct.specialExams.createAllowance',\n defaultMessage: 'Create Allowance',\n description: 'Label for the create button in add allowance modal',\n },\n specifyLearners: {\n id: 'instruct.specialExams.specifyLearners',\n defaultMessage: 'Specify Learners',\n description: 'Label for the field to specify learners in add allowance modal',\n },\n specifyLearnersPlaceholder: {\n id: 'instruct.specialExams.specifyLearnersPlaceholder',\n defaultMessage: 'Learner email addresses and/or usernames separated by commas',\n description: 'Placeholder for the field to specify learners in add allowance modal',\n },\n selectExamType: {\n id: 'instruct.specialExams.selectExamType',\n defaultMessage: 'Select Exam Type',\n description: 'Label for the field to select exam type in add allowance modal',\n },\n selectExams: {\n id: 'instruct.specialExams.selectExams',\n defaultMessage: 'Select Exam(s)',\n description: 'Label for the field to select exams in add allowance modal',\n },\n selectAllowanceType: {\n id: 'instruct.specialExams.selectAllowanceType',\n defaultMessage: 'Select Allowance Type',\n description: 'Label for the field to select allowance type in add allowance modal',\n },\n addTime: {\n id: 'instruct.specialExams.addTime',\n defaultMessage: 'Add Time',\n description: 'Label for the field to enter time value in add allowance modal',\n },\n addTimePlaceholder: {\n id: 'instruct.specialExams.addTimePlaceholder',\n defaultMessage: 'Time (minutes)',\n description: 'Placeholder for the field to enter time value in add allowance modal',\n },\n actions: {\n id: 'instruct.specialExams.actions',\n defaultMessage: 'Actions',\n description: 'ARIA label for actions button in allowances list',\n },\n proctored: {\n id: 'instruct.specialExams.proctored',\n defaultMessage: 'Proctored',\n description: 'Label for whether the special exam is proctored in the list of special exams',\n },\n timed: {\n id: 'instruct.specialExams.timed',\n defaultMessage: 'Timed',\n description: 'Label for whether the special exam is timed in the list of special exams',\n },\n timeMultiplier: {\n id: 'instruct.specialExams.timeMultiplier',\n defaultMessage: 'Time Multiplier',\n description: 'Label for the time multiplier value in the list of special exams',\n },\n additionalTime: {\n id: 'instruct.specialExams.additionalTime',\n defaultMessage: 'Additional Time',\n description: 'Label for the additional time value in the list of special exams',\n },\n reviewPolicy: {\n id: 'instruct.specialExams.reviewPolicy',\n defaultMessage: 'Review Policy Exception',\n description: 'Label for the review policy exception in the list of special exams',\n },\n exceptionPlaceholder: {\n id: 'instruct.specialExams.exceptionPlaceholder',\n defaultMessage: 'Exception',\n description: 'Placeholder for the review policy exception description in add allowance modal',\n },\n timeMultiplierPlaceholder: {\n id: 'instruct.specialExams.timeMultiplierPlaceholder',\n defaultMessage: 'Multiplier (number > 1)',\n description: 'Placeholder for the time multiplier value in add allowance modal',\n },\n edit: {\n id: 'instruct.specialExams.edit',\n defaultMessage: 'Edit',\n description: 'Label for edit action in allowance list',\n },\n delete: {\n id: 'instruct.specialExams.delete',\n defaultMessage: 'Delete',\n description: 'Label for delete action in allowance list',\n },\n deleteAllowance: {\n id: 'instruct.specialExams.deleteAllowance',\n defaultMessage: 'Delete Allowance',\n description: 'Title for delete allowance confirmation modal'\n },\n deleteConfirmation: {\n id: 'instruct.specialExams.deleteConfirmation',\n defaultMessage: 'Delete allowance for {user} for {examName}?',\n description: 'Delete confirmation message'\n },\n deleteError: {\n id: 'instruct.specialExams.deleteError',\n defaultMessage: 'An error occurred while deleting the allowance. Please try again.',\n description: 'Error message displayed when there is an issue deleting an allowance'\n },\n addAdditionalTimeGranted: {\n id: 'instruct.specialExams.addAdditionalTimeGranted',\n defaultMessage: 'Add Time',\n description: 'Label for additional time granted field in add allowance modal',\n },\n addReviewPolicyException: {\n id: 'instruct.specialExams.addReviewPolicyException',\n defaultMessage: 'Add Policy Exception',\n description: 'Label for review policy exception field in add allowance modal',\n },\n addTimeMultiplier: {\n id: 'instruct.specialExams.addTimeMultiplier',\n defaultMessage: 'Add Time Multiplier',\n description: 'Label for time multiplier field in add allowance modal',\n },\n addAllowanceError: {\n id: 'instruct.specialExams.addAllowanceError',\n defaultMessage: 'An error occurred while adding the allowance. Please try again.',\n description: 'Error message displayed when there is an issue adding a new allowance'\n },\n editAllowanceError: {\n id: 'instruct.specialExams.editAllowanceError',\n defaultMessage: 'An error occurred while editing the allowance. Please try again.',\n description: 'Error message displayed when there is an issue editing an allowance'\n },\n cannotModifyAllowance: {\n id: 'instruct.specialExams.cannotModifyAllowance',\n defaultMessage: 'Cannot {action} allowance: {username} has already attempted the exam',\n description: 'Warning message shown when trying to edit or delete an allowance for a student who has already attempted the exam'\n },\n readyForResume: {\n id: 'instruct.specialExams.readyForResume',\n defaultMessage: 'Ready to Resume?',\n description: 'Label for whether the exam attempt is ready to be resumed in the exam attempts list',\n },\n resume: {\n id: 'instruct.specialExams.resume',\n defaultMessage: 'Resume',\n description: 'Label for resume action in exam attempts list',\n },\n reset: {\n id: 'instruct.specialExams.reset',\n defaultMessage: 'Reset',\n description: 'Label for reset action in exam attempts list',\n },\n true: {\n id: 'instruct.specialExams.true',\n defaultMessage: 'True',\n description: 'Display value for a boolean true value'\n },\n successOnReset: {\n id: 'instruct.specialExams.successOnReset',\n defaultMessage: 'Successfully reset attempt on {examName} for {student}.',\n description: 'Success message shown after resetting an exam attempt'\n },\n errorOnReset: {\n id: 'instruct.specialExams.errorOnReset',\n defaultMessage: 'An error occurred while resetting the attempt. Please try again.',\n description: 'Error message shown when resetting an exam attempt fails'\n },\n close: {\n id: 'instruct.specialExams.close',\n defaultMessage: 'Close',\n description: 'Label for close button'\n },\n confirmationModal: {\n id: 'instruct.specialExams.confirmationModal',\n defaultMessage: 'Confirmation Modal',\n description: 'Confirmation modal title'\n },\n confirmationMessageReset: {\n id: 'instruct.specialExams.confirmationMessageReset',\n defaultMessage: 'Are you sure you want to remove this student\\'s exam attempt?',\n description: 'Confirmation message shown when resetting an exam attempt'\n },\n confirmationMessageResume: {\n id: 'instruct.specialExams.confirmationMessageResume',\n defaultMessage: 'Are you sure you want to resume this exam attempt?',\n description: 'Confirmation message shown when resuming an exam attempt'\n },\n errorOnResume: {\n id: 'instruct.specialExams.errorOnResume',\n defaultMessage: 'An error occurred while resuming the attempt. Please try again.',\n description: 'Error message shown when resuming an exam attempt fails'\n },\n successOnResume: {\n id: 'instruct.specialExams.successOnResume',\n defaultMessage: 'Successfully resumed attempt for {student}.',\n description: 'Success message shown after resuming an exam attempt'\n }\n});\n\nexport default messages;\n"]}
|
|
@@ -3,19 +3,30 @@ export interface Attempt {
|
|
|
3
3
|
id: number;
|
|
4
4
|
user: {
|
|
5
5
|
username: string;
|
|
6
|
+
id: number;
|
|
6
7
|
};
|
|
7
8
|
examId: number;
|
|
8
9
|
examName: string;
|
|
9
10
|
allowedTimeLimitMins: number;
|
|
10
|
-
|
|
11
|
+
examType: string;
|
|
11
12
|
startTime: string;
|
|
12
|
-
endTime: string;
|
|
13
|
+
endTime: string | null;
|
|
13
14
|
status: string;
|
|
15
|
+
readyToResume: boolean;
|
|
14
16
|
}
|
|
15
17
|
export interface AttemptsParams extends PaginationParams {
|
|
16
18
|
emailOrUsername: string;
|
|
17
19
|
ordering: string;
|
|
18
20
|
}
|
|
21
|
+
export type AttemptAction = 'reset' | 'resume';
|
|
22
|
+
export interface ResetAttemptParams {
|
|
23
|
+
username: string;
|
|
24
|
+
examId: number;
|
|
25
|
+
}
|
|
26
|
+
export interface ResumeAttemptParams {
|
|
27
|
+
attemptId: number;
|
|
28
|
+
userId: number;
|
|
29
|
+
}
|
|
19
30
|
export interface Allowance {
|
|
20
31
|
value: string;
|
|
21
32
|
key: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/specialExams/types.ts"],"names":[],"mappings":"","sourcesContent":["import { PaginationParams } from '@src/types';\n\nexport interface Attempt {\n id: number,\n user: {\n username: string,\n },\n examId: number,\n examName: string,\n allowedTimeLimitMins: number,\n
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/specialExams/types.ts"],"names":[],"mappings":"","sourcesContent":["import { PaginationParams } from '@src/types';\n\nexport interface Attempt {\n id: number,\n user: {\n username: string,\n id: number,\n },\n examId: number,\n examName: string,\n allowedTimeLimitMins: number,\n examType: string,\n startTime: string,\n endTime: string | null,\n status: string,\n readyToResume: boolean,\n}\n\nexport interface AttemptsParams extends PaginationParams {\n emailOrUsername: string,\n ordering: string,\n}\n\nexport type AttemptAction = 'reset' | 'resume';\n\nexport interface ResetAttemptParams {\n username: string,\n examId: number,\n}\n\nexport interface ResumeAttemptParams {\n attemptId: number,\n userId: number,\n}\n\nexport interface Allowance {\n value: string,\n key: string,\n proctoredExam: {\n examName: string,\n examType: string,\n id: number,\n },\n user: {\n username: string,\n email: string,\n id: number,\n },\n id: number,\n}\n\nexport interface AddAllowanceParams {\n userIds: string[],\n examType: string,\n examIds: number[],\n allowanceType: string,\n value: string,\n}\n\nexport interface AddAllowanceForm {\n users: string,\n examType: string,\n examIds: number[],\n allowanceType: string,\n value: string,\n}\n\nexport interface SpecialExam {\n examName: string,\n examType: string,\n timeLimitMins: number,\n contentId: string,\n courseId: string,\n dueDate: string | null,\n isProctored: boolean,\n isActive: boolean,\n isPracticeExam: boolean,\n hideAfterDue: boolean,\n id: number,\n}\n\nexport interface DeleteAllowanceParams {\n examId: number,\n userIds: number[],\n allowanceType: string,\n}\n"]}
|