diff --git a/edx_proctoring/static/proctoring/js/exam_action_handler.js b/edx_proctoring/static/proctoring/js/exam_action_handler.js index 5555213ceb9..c6b3391e58d 100644 --- a/edx_proctoring/static/proctoring/js/exam_action_handler.js +++ b/edx_proctoring/static/proctoring/js/exam_action_handler.js @@ -24,6 +24,32 @@ var edx = edx || {}; } }; + /** + * Launch modals, handling a11y focus behavior + * + * Note: don't try to leverage this for the heartbeat; the DOM + * structure this depends on doesn't live everywhere that handler + * needs to live + */ + function accessibleError(title, message) { + accessible_modal( + "#accessible-error-modal #confirm_open_button", + "#accessible-error-modal .close-modal", + "#accessible-error-modal", + ".content-wrapper" + ); + $("#accessible-error-modal #confirm_open_button").click(); + $("#accessible-error-modal .message-title").html(message); + $('#accessible-error-modal #acessible-error-title').html(title); + $("#accessible-error-modal .ok-button") + .html(gettext("OK")) + .off('click.closeModal') + .on('click.closeModal', function(){ + $("#accessible-error-modal .close-modal").click(); + }); + }; + + function workerPromiseForEventNames(eventNames) { return function() { var proctoringBackendWorker = new Worker(edx.courseware.proctored_exam.configuredWorkerURL); @@ -66,6 +92,23 @@ var edx = edx || {}; location.reload(); } + function setActionButtonLoadingState($button) { + $button.prop('disabled', true); + $button.html($button.data('loading-text')); + } + + function setActionButtonSteadyState($button) { + $button.prop('disabled', false); + $button.html($button.data('cta-text')); + } + + function errorHandlerGivenMessage($button, title, message) { + setActionButtonSteadyState($button); + return function() { + accessibleError(title, message); + }; + } + edx.courseware = edx.courseware || {}; edx.courseware.proctored_exam = edx.courseware.proctored_exam || {}; @@ -77,14 +120,33 @@ var edx = edx || {}; var actionUrl = $this.data('change-state-url'); var action = $this.data('action'); + setActionButtonLoadingState($this); + var shouldUseWorker = window.Worker && edx.courseware.proctored_exam.configuredWorkerURL; if(shouldUseWorker) { workerPromiseForEventNames(actionToMessageTypesMap[action])() .then(updateExamAttemptStatusPromise(actionUrl, action)) - .then(reloadPage); + .then(reloadPage) + .catch(errorHandlerGivenMessage( + $this, + gettext('Error Starting Exam'), + gettext( + 'Something has gone wrong starting your exam. ' + + 'Please double-check that the application is running.' + ), + )); } else { updateExamAttemptStatusPromise(actionUrl, action)() - .then(reloadPage); + .then(reloadPage) + .catch(errorHandlerGivenMessage( + $this, + gettext('Error Starting Exam'), + gettext( + 'Something has gone wrong starting your exam. ' + + 'Please reload the page and start again.' + ), + )); + } }; edx.courseware.proctored_exam.examEndHandler = function() { @@ -95,6 +157,8 @@ var edx = edx || {}; var actionUrl = $this.data('change-state-url'); var action = $this.data('action'); + setActionButtonLoadingState($this); + var shouldUseWorker = window.Worker && edx.courseware.proctored_exam.configuredWorkerURL && action === "submit"; @@ -102,10 +166,26 @@ var edx = edx || {}; updateExamAttemptStatusPromise(actionUrl, action)() .then(workerPromiseForEventNames(actionToMessageTypesMap[action])) - .then(reloadPage); + .then(reloadPage) + .catch(errorHandlerGivenMessage( + $this, + gettext('Error Ending Exam'), + gettext( + 'Something has gone wrong ending your exam. ' + + 'Please double-check that the application is running.' + ) + )); } else { updateExamAttemptStatusPromise(actionUrl, action)() - .then(reloadPage); + .then(reloadPage) + .catch(errorHandlerGivenMessage( + $this, + gettext('Error Ending Exam'), + gettext( + 'Something has gone wrong ending your exam. ' + + 'Please reload the page and start again.' + ) + )); } } edx.courseware.proctored_exam.pingApplication = function() { @@ -114,6 +194,5 @@ var edx = edx || {}; timeoutPromise(ONE_MINUTE_MS) ]); } - - + edx.courseware.proctored_exam.accessibleError = accessibleError; }).call(this, $); diff --git a/edx_proctoring/templates/proctored_exam/error_modal.html b/edx_proctoring/templates/proctored_exam/error_modal.html new file mode 100644 index 00000000000..0f0e710fda4 --- /dev/null +++ b/edx_proctoring/templates/proctored_exam/error_modal.html @@ -0,0 +1,26 @@ +{% load i18n %} +
diff --git a/edx_proctoring/templates/proctored_exam/instructions.html b/edx_proctoring/templates/proctored_exam/instructions.html index d934e45ae05..ccaa9904e08 100644 --- a/edx_proctoring/templates/proctored_exam/instructions.html +++ b/edx_proctoring/templates/proctored_exam/instructions.html @@ -62,31 +62,8 @@