From 14086b819566fa58c0fa9246d8dda835629646ec Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Tue, 25 Jun 2024 00:54:53 +0530 Subject: [PATCH 01/13] adds mark for review button --- src/components/InstructionPage.vue | 8 +++- src/components/Omr/OmrModal.vue | 4 +- src/components/Questions/Footer.vue | 39 ++++++++++++++++- src/components/Questions/Palette/Item.vue | 7 +++ .../Questions/Palette/QuestionPalette.vue | 8 ++++ src/components/Questions/Palette/Review.vue | 29 +++++++++++++ src/components/Questions/Palette/Utils.ts | 4 +- src/components/Questions/QuestionModal.vue | 43 ++++++++++++++++++- src/services/API/Session.ts | 3 ++ src/types.ts | 7 ++- src/views/Player.vue | 40 +++++++++++++++++ tests/unit/components/Omr/OmrModal.spec.ts | 3 ++ .../Questions/QuestionModal.spec.ts | 5 +++ 13 files changed, 192 insertions(+), 8 deletions(-) create mode 100644 src/components/Questions/Palette/Review.vue diff --git a/src/components/InstructionPage.vue b/src/components/InstructionPage.vue index 4f5289a..7254320 100644 --- a/src/components/InstructionPage.vue +++ b/src/components/InstructionPage.vue @@ -70,6 +70,10 @@ You have not answered the question +
+ + You have marked the question for review +
  • You can click on the button again to collapse the Question Palette.
  • @@ -103,6 +107,7 @@ import BaseIcon from "./UI/Icons/BaseIcon.vue"; import Success from "./Questions/Palette/Success.vue"; import Error from "./Questions/Palette/Error.vue"; import Neutral from "./Questions/Palette/Neutral.vue"; +import Review from "./Questions/Palette/Review.vue"; import { quizTitleType, testFormat, questionSetPalette, TimeLimit } from "../types"; export default defineComponent({ name: "InstructionPage", @@ -110,7 +115,8 @@ export default defineComponent({ BaseIcon, Success, Error, - Neutral + Neutral, + Review }, props: { title: { diff --git a/src/components/Omr/OmrModal.vue b/src/components/Omr/OmrModal.vue index 35d04ce..33873d7 100644 --- a/src/components/Omr/OmrModal.vue +++ b/src/components/Omr/OmrModal.vue @@ -426,7 +426,9 @@ export default defineComponent({ _id: response._id, question_id: response.question_id, answer: response.answer, - visited: response.visited + visited: response.visited, + time_spent: response.time_spent, + marked_for_review: response.marked_for_review } ) }) diff --git a/src/components/Questions/Footer.vue b/src/components/Questions/Footer.vue index d5b0494..583085e 100644 --- a/src/components/Questions/Footer.vue +++ b/src/components/Questions/Footer.vue @@ -51,6 +51,18 @@ @click="clearAnswer" data-test="clearButton" > + + +
    @@ -108,6 +120,10 @@ export default defineComponent({ default: false, type: Boolean, }, + isMarkedForReview: { + default: false, + type: Boolean, + }, isPreviousButtonShown: { default: false, type: Boolean, @@ -183,6 +199,11 @@ export default defineComponent({ "bg-white hover:bg-gray-50", ]); + const markForReviewButtonClass = ref([ + state.assessmentTextButtonClass, + "bg-white hover:bg-gray-50", + ]); + const saveAndNextButtonClass = ref([ state.assessmentTextButtonClass, "bg-white hover:bg-gray-50", @@ -193,6 +214,11 @@ export default defineComponent({ class: [state.assessmentTextButtonTitleClass, "text-gray-600"], } as IconButtonTitleConfig); + const markForReviewButtonTitleConfig = computed(() => ({ + value: props.isMarkedForReview ? "Clear Review" : "Mark For Review", + class: [state.assessmentTextButtonTitleClass, "text-violet-500"], + } as IconButtonTitleConfig)); + const saveAndNextButtonTitleConfig = ref({ value: "Save & Next", class: [state.assessmentTextButtonTitleClass, "text-emerald-500"], @@ -216,6 +242,14 @@ export default defineComponent({ context.emit("clear"); } + function toggleMarkForReview() { + if (props.isMarkedForReview) { + context.emit("clear-review"); + } else { + context.emit("mark-for-review"); + } + } + function goToPreviousQuestion() { context.emit("previous"); } @@ -267,14 +301,17 @@ export default defineComponent({ previousQuestionButtonIconConfig, nextQuestionButtonIconConfig, clearButtonClass, + markForReviewButtonClass, saveAndNextButtonClass, clearButtonTitleConfig, + markForReviewButtonTitleConfig, saveAndNextButtonTitleConfig, saveAndNextButtonIconConfig, submitQuestion, goToPreviousQuestion, goToNextQuestion, clearAnswer, + toggleMarkForReview, saveQuestionAndProceed, submitButtonTitleConfig, submitButtonIconConfig, @@ -282,6 +319,6 @@ export default defineComponent({ isQuizAssessment, }; }, - emits: ["submit", "previous", "continue", "clear"], + emits: ["submit", "previous", "continue", "clear", "mark-for-review", "clear-review"], }); diff --git a/src/components/Questions/Palette/Item.vue b/src/components/Questions/Palette/Item.vue index 0daf89a..cc5ee7a 100644 --- a/src/components/Questions/Palette/Item.vue +++ b/src/components/Questions/Palette/Item.vue @@ -20,6 +20,11 @@ :hasQuizEnded="hasQuizEnded" data-test="neutral" > +

    +

    + +
    @@ -78,6 +84,7 @@ import Success from "./Success.vue"; import PartialSuccess from "./PartialSuccess.vue"; import Error from "./Error.vue"; import Neutral from "./Neutral.vue"; +import Review from "./Review.vue"; import PaletteItem from "./Item.vue"; import InstructionPage from "@/components/InstructionPage.vue"; import { TimeLimit, questionSetPalette, quizTitleType, testFormat } from "../../../types"; @@ -89,6 +96,7 @@ export default defineComponent({ PartialSuccess, Error, Neutral, + Review, PaletteItem, InstructionPage }, diff --git a/src/components/Questions/Palette/Review.vue b/src/components/Questions/Palette/Review.vue new file mode 100644 index 0000000..6a4d6d1 --- /dev/null +++ b/src/components/Questions/Palette/Review.vue @@ -0,0 +1,29 @@ + + + diff --git a/src/components/Questions/Palette/Utils.ts b/src/components/Questions/Palette/Utils.ts index 7a0db84..f355e81 100644 --- a/src/components/Questions/Palette/Utils.ts +++ b/src/components/Questions/Palette/Utils.ts @@ -1,8 +1,8 @@ // classes for the icon of each key in the legend of the question palette export const legendKeyIconClass = - "w-6 h-6 bp-420:w-10 bp-420:h-10 border-1 rounded-md place-self-center"; + "w-6 h-6 bp-420:w-10 bp-420:h-10 border-1 rounded-md place-self-center flex-shrink-0"; // classes for the text of each key in the legend of the question palette export const legendKeyTextClass = "place-self-center text-sm sm:text-base font-bold"; // classes for the container of each key in the legend of the question palette -export const legendKeyContainerClass = "flex space-x-2 lg:space-x-4"; +export const legendKeyContainerClass = "flex space-x-2 lg:space-x-4 items-centers"; diff --git a/src/components/Questions/QuestionModal.vue b/src/components/Questions/QuestionModal.vue index e9dbb3f..0bde054 100644 --- a/src/components/Questions/QuestionModal.vue +++ b/src/components/Questions/QuestionModal.vue @@ -72,6 +72,7 @@ >
    @@ -324,6 +327,10 @@ To attempt this question, unselect an answer to another question in this section state.localResponses[props.currentQuestionIndex].answer = state.draftResponses[props.currentQuestionIndex] context.emit("submit-question") + if (isQuizAssessment.value && state.localResponses[props.currentQuestionIndex].marked_for_review) { + state.localResponses[props.currentQuestionIndex].marked_for_review = false + context.emit("update-review-status") + } } function clearAnswer() { @@ -332,6 +339,25 @@ To attempt this question, unselect an answer to another question in this section state.isDraftAnswerCleared = true } + function markForReviewQuestion() { + state.previousLocalResponse = clonedeep(state.localResponses[props.currentQuestionIndex]); + state.localResponses[props.currentQuestionIndex].marked_for_review = true; + state.toast.info( + `Question ${props.currentQuestionIndex + 1} marked for review!`, + { + position: POSITION.TOP_LEFT, + timeout: 2000 + } + ) + context.emit("update-review-status") + } + + function clearReviewQuestion() { + state.previousLocalResponse = clonedeep(state.localResponses[props.currentQuestionIndex]); + state.localResponses[props.currentQuestionIndex].marked_for_review = false; + context.emit("update-review-status") + } + function showNextQuestion() { // It toggles the reRenderKey from 0 to 1 or 1 to 0. And changing the reRender key, re-renders the component. // we reRender the whole component as textarea is holding the details which is not getting updated @@ -393,13 +419,18 @@ To attempt this question, unselect an answer to another question in this section function endTest() { if (!props.hasQuizEnded && state.hasEndTestBeenClickedOnce) { let attemptedQuestions = 0; + let markedForReviewQuestions = 0; for (const response of props.responses) { if (response.answer != null) { attemptedQuestions += 1; } + if (response.marked_for_review == true) { + markedForReviewQuestions += 1 + } } state.toast.success( - `You have answered ${attemptedQuestions} out of ${props.numQuestions} questions. Click on the Question Palette to review unanswered questions before submitting the test. Click the End Test button again to make the final submission.`, + `You have answered ${attemptedQuestions} out of ${props.numQuestions} questions. Click on the Question Palette to review unanswered questions before submitting the test. Click the End Test button again to make the final submission. +ALERT: ${markedForReviewQuestions} questions which are marked for review are also unanswered.`, { position: POSITION.TOP_CENTER, timeout: 5000, @@ -483,6 +514,10 @@ To attempt this question, unselect an answer to another question in this section return true }) + const isMarkedForReview = computed(() => { + return currentQuestionResponse.value.marked_for_review; + }) + const isAttemptValid = computed(() => { if (optionalLimitReached.value && currentQuestionResponseAnswer.value == null) { // this cannot be answered @@ -546,6 +581,8 @@ To attempt this question, unselect an answer to another question in this section showPreviousQuestion, subjectiveAnswerUpdated, clearAnswer, + markForReviewQuestion, + clearReviewQuestion, endTest, endTestByTime, navigateToQuestion, @@ -556,6 +593,7 @@ To attempt this question, unselect an answer to another question in this section isGradedQuestion, currentQuestionResponseAnswer, isAnswerSubmitted, + isMarkedForReview, isAttemptValid, isQuizAssessment, optionalLimitReached, @@ -572,7 +610,8 @@ To attempt this question, unselect an answer to another question in this section "end-test", "fetch-question-bucket", "test-warning-shown", - "test-optional-warning-shown" + "test-optional-warning-shown", + "update-review-status" ], }); diff --git a/src/services/API/Session.ts b/src/services/API/Session.ts index 49455c0..33cc8dc 100644 --- a/src/services/API/Session.ts +++ b/src/services/API/Session.ts @@ -54,6 +54,7 @@ export default { total_correct: 0, total_wrong: 0, total_partially_correct: 0, + total_marked_for_review: 0, total_marks: 0, }; @@ -67,6 +68,7 @@ export default { num_correct: metric.correctlyAnswered, num_wrong: metric.wronglyAnswered, num_partially_correct: metric.partiallyAnswered, + num_marked_for_review: metric.numQuestionsMarkedForReview, attempt_rate: Math.round(metric.attemptRate * 100) / 100, accuracy_rate: Math.round(metric.accuracyRate * 100) / 100, }; @@ -77,6 +79,7 @@ export default { sessionMetrics.total_correct += metric.correctlyAnswered; sessionMetrics.total_wrong += metric.wronglyAnswered; sessionMetrics.total_partially_correct += metric.partiallyAnswered; + sessionMetrics.total_marked_for_review += metric.numQuestionsMarkedForReview; sessionMetrics.total_marks += metric.marksScored; }); diff --git a/src/types.ts b/src/types.ts index 1754888..c3d0e53 100644 --- a/src/types.ts +++ b/src/types.ts @@ -61,6 +61,7 @@ export interface SubmittedResponse { answer: submittedAnswer; visited: boolean; time_spent?: number; // time spent on question in seconds + marked_for_review: boolean; } interface ScorecardMetricIcon { @@ -83,6 +84,7 @@ export interface QuestionSetMetric { correctlyAnswered: number, partiallyAnswered: number, wronglyAnswered: number, + numQuestionsMarkedForReview: number, attemptRate: number, accuracyRate: number } @@ -223,6 +225,7 @@ export interface QuestionSetMetricPayload { num_correct: number; num_wrong: number; num_partially_correct: number; + num_marked_for_review: number; attempt_rate: number; accuracy_rate: number; } @@ -234,6 +237,7 @@ export interface SessionMetricsPayload { total_correct: number; total_wrong: number; total_partially_correct: number; + total_marked_for_review: number; total_marks: number; } export interface UpdateSessionAPIResponse { @@ -248,6 +252,7 @@ export interface UpdateSessionAnswerAPIPayload { answer?: submittedAnswer; visited?: boolean; time_spent?: number; // time spent on question in seconds + marked_for_review?: boolean; } export type TimeSpentEntry = { @@ -264,7 +269,7 @@ export interface answerEvaluation { isPartiallyCorrect?: boolean; // whether question has been partially answered for multi answer } -export type questionState = "success" | "error" | "neutral" | "partial-success"; +export type questionState = "success" | "error" | "neutral" | "partial-success" | "review"; export interface paletteItemState { index: number; // index of the corresponding question in the list of questions value: questionState; diff --git a/src/views/Player.vue b/src/views/Player.vue index 387ac17..813e96c 100644 --- a/src/views/Player.vue +++ b/src/views/Player.vue @@ -84,6 +84,7 @@ v-model:responses="responses" v-model:previousResponse="previousResponse" @submit-question="submitQuestion" + @update-review-status="updateQuestionResponse" @end-test="endTest" @fetch-question-bucket="fetchQuestionBucket" v-if="isQuestionShown && !isOmrMode" @@ -203,6 +204,7 @@ export default defineComponent({ numWrong: 0, // number of wrongly answered questions numPartiallyCorrect: 0, // number of partially correct questions numSkipped: 0, // number of skipped questions + numMarkedForReview: 0, // number of questions marked for review marksScored: 0, maxMarks: 0, // maximum marks that can be scored isScorecardShown: false, // to show the scorecard or not @@ -475,6 +477,36 @@ export default defineComponent({ await createSession(); } + /** updates the session answer once marked for review */ + async function updateQuestionResponse() { + state.isSessionAnswerRequestProcessing = true; + const itemResponse = state.responses[state.currentQuestionIndex]; + const payload: UpdateSessionAnswerAPIPayload = { + marked_for_review: itemResponse.marked_for_review + } + const response = await SessionAPIService.updateSessionAnswer( // response.data + state.sessionId, + state.currentQuestionIndex, + payload + ); + state.timeSpentOnQuestion[state.currentQuestionIndex].hasSynced = true; + if (response.status != 200) { + state.toast.error( + `Review Status for Q.${state.currentQuestionIndex + 1} not saved. Please try to mark for review again or refresh the page.`, + { + position: POSITION.TOP_LEFT, + timeout: 4000, + draggablePercent: 0.4 + } + ) + state.responses[state.currentQuestionIndex] = state.previousResponse; // previous value?! + } else { + // successful response + state.continueAfterAnswerSubmit = true; + } + state.isSessionAnswerRequestProcessing = false; + } + /** updates the session answer once a response is submitted */ async function submitQuestion() { state.isSessionAnswerRequestProcessing = true; @@ -690,6 +722,7 @@ export default defineComponent({ state.numCorrect = 0; state.numWrong = 0; state.numPartiallyCorrect = 0; + state.numMarkedForReview = 0; state.marksScored = 0; // Initialize metrics for each question set @@ -702,6 +735,7 @@ export default defineComponent({ correctlyAnswered: 0, wronglyAnswered: 0, partiallyAnswered: 0, + numQuestionsMarkedForReview: 0, attemptRate: 0, accuracyRate: 0 })); @@ -710,6 +744,10 @@ export default defineComponent({ const [currentQsetIndex] = getQsetLimits(questionIndex); const qsetMetricsObj = state.qsetMetrics[currentQsetIndex]; if (!questionDetail.graded) qsetMetricsObj.maxQuestionsAllowedToAttempt -= 1 + if (state.responses[index].marked_for_review === true) { + qsetMetricsObj.numQuestionsMarkedForReview += 1; + state.numMarkedForReview += 1; + } updateQuestionMetrics(questionDetail, state.responses[index].answer, qsetMetricsObj); if (qsetMetricsObj.numAnswered != 0) qsetMetricsObj.accuracyRate = (qsetMetricsObj.correctlyAnswered + 0.5 * qsetMetricsObj.partiallyAnswered) / qsetMetricsObj.numAnswered; state.qsetMetrics[currentQsetIndex].attemptRate = qsetMetricsObj.numAnswered / qsetMetricsObj.maxQuestionsAllowedToAttempt; @@ -846,6 +884,7 @@ export default defineComponent({ qstate = "neutral" } else { if (state.responses[qindex].answer != null) qstate = "success" + else if (state.responses[qindex].marked_for_review) qstate = "review" else qstate = "error" } } else qstate = "error" @@ -921,6 +960,7 @@ export default defineComponent({ startQuiz, getQsetLimits, submitQuestion, + updateQuestionResponse, submitOmrQuestion, goToPreviousQuestion, endTest, diff --git a/tests/unit/components/Omr/OmrModal.spec.ts b/tests/unit/components/Omr/OmrModal.spec.ts index 411e2e5..2884e19 100644 --- a/tests/unit/components/Omr/OmrModal.spec.ts +++ b/tests/unit/components/Omr/OmrModal.spec.ts @@ -236,6 +236,7 @@ describe("OmrModal.vue", () => { question_id: question._id, answer: null, visited: false, + marked_for_review: false, time_spent: 0 }) ); @@ -324,6 +325,7 @@ describe("OmrModal.vue", () => { question_id: questions[questionIndex]._id, answer: [0], visited: false, + marked_for_review: false, time_spent: 0 }); expect(wrapper.emitted()).toHaveProperty("submit-omr-question"); @@ -415,6 +417,7 @@ describe("OmrModal.vue", () => { question_id: questions[questionIndex]._id, answer: [0, 1], visited: false, + marked_for_review: false, time_spent: 0 }); expect(wrapper.emitted()).toHaveProperty("submit-omr-question"); diff --git a/tests/unit/components/Questions/QuestionModal.spec.ts b/tests/unit/components/Questions/QuestionModal.spec.ts index 4b4aabf..5e4040b 100644 --- a/tests/unit/components/Questions/QuestionModal.spec.ts +++ b/tests/unit/components/Questions/QuestionModal.spec.ts @@ -218,6 +218,7 @@ describe("QuestionModal.vue", () => { question_id: question._id, answer: null, visited: false, + marked_for_review: false, time_spent: 0 }) ); @@ -472,6 +473,7 @@ describe("QuestionModal.vue", () => { question_id: questions[questionIndex]._id, answer: [0], visited: false, + marked_for_review: false, time_spent: 0 }); expect(wrapper.emitted()).toHaveProperty("submit-question"); @@ -574,6 +576,7 @@ describe("QuestionModal.vue", () => { question_id: questions[questionIndex]._id, answer: [0, 1], visited: false, + marked_for_review: false, time_spent: 0 }); expect(wrapper.emitted()).toHaveProperty("submit-question"); @@ -656,6 +659,7 @@ describe("QuestionModal.vue", () => { question_id: questions[questionIndex]._id, answer, visited: false, + marked_for_review: false, time_spent: 0 }); expect(wrapper.emitted()).toHaveProperty("submit-question"); @@ -758,6 +762,7 @@ describe("QuestionModal.vue", () => { question_id: questions[questionIndex]._id, answer, visited: false, + marked_for_review: false, time_spent: 0 }); expect(wrapper.emitted()).toHaveProperty("submit-question"); From 8fc01208daba7151dbe70bb474376a49ffc79dbe Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Tue, 25 Jun 2024 01:04:22 +0530 Subject: [PATCH 02/13] updates e2e tests --- tests/e2e/specs/renders-player-to-check-timed.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/e2e/specs/renders-player-to-check-timed.js b/tests/e2e/specs/renders-player-to-check-timed.js index e7cd95c..15b0f5f 100644 --- a/tests/e2e/specs/renders-player-to-check-timed.js +++ b/tests/e2e/specs/renders-player-to-check-timed.js @@ -167,6 +167,7 @@ describe("Player for Assessment Timed quizzes", () => { num_correct: 0, num_wrong: 0, num_partially_correct: 0, + num_marked_for_review: 0, attempt_rate: 0, accuracy_rate: 0, }, @@ -176,6 +177,7 @@ describe("Player for Assessment Timed quizzes", () => { total_correct: 0, total_wrong: 0, total_partially_correct: 0, + total_marked_for_review: 0, total_marks: 0, }, }); From a4508f7be71f0d62066f636babe607e64857ceed Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Tue, 25 Jun 2024 01:46:25 +0530 Subject: [PATCH 03/13] footer font sizes for mobile --- src/components/Questions/Footer.vue | 6 +++--- tailwind.config.js | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/Questions/Footer.vue b/src/components/Questions/Footer.vue index 583085e..73df3aa 100644 --- a/src/components/Questions/Footer.vue +++ b/src/components/Questions/Footer.vue @@ -165,7 +165,7 @@ export default defineComponent({ "fill-current", ], assessmentTextButtonTitleClass: - "text-sm bp-500:text-md lg:text-lg xl:text-xl font-bold", + "text-xs bp-500:text-sm lg:text-base xl:text-lg font-bold", assessmentNavigationButtonClass: [ { "bg-yellow-500 hover:bg-yellow-600 ring-yellow-500 px-6 bp-500:px-8 rounded-2xl": @@ -216,11 +216,11 @@ export default defineComponent({ const markForReviewButtonTitleConfig = computed(() => ({ value: props.isMarkedForReview ? "Clear Review" : "Mark For Review", - class: [state.assessmentTextButtonTitleClass, "text-violet-500"], + class: ["text-xxs bp-500:text-sm lg:text-base xl:text-lg font-bold", "text-violet-500"], } as IconButtonTitleConfig)); const saveAndNextButtonTitleConfig = ref({ - value: "Save & Next", + value: "Save >", class: [state.assessmentTextButtonTitleClass, "text-emerald-500"], } as IconButtonTitleConfig); diff --git a/tailwind.config.js b/tailwind.config.js index cd2e87b..46fcfc6 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -13,6 +13,9 @@ module.exports = { borderWidth: { 1: "1px", }, + fontSize: { + xxs: "0.65rem", + }, }, screens: { "bp-320": "320px", From cf5869dedd3be9d0bf7a0d68aa2083434a88d081 Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Tue, 25 Jun 2024 01:52:10 +0530 Subject: [PATCH 04/13] instr update --- src/components/InstructionPage.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/InstructionPage.vue b/src/components/InstructionPage.vue index 7254320..3d663a8 100644 --- a/src/components/InstructionPage.vue +++ b/src/components/InstructionPage.vue @@ -88,7 +88,7 @@
  • To select you answer, click on the button of one of the options.
  • To deselect your chosen answer, click on the button of the chosen option again or click on the Clear button.
  • To change your chosen answer, click on the button of another option.
  • -
  • To save your answer, you MUST click on the Save & Next button.
  • +
  • To save your answer, you MUST click on the "Save >" button.
  • To change your answer to a question that has already been answered, first select that question for answering and then follow the procedure for answering that type of question.
  • @@ -96,7 +96,7 @@
    !
    -
    Note that selecting an option does NOT save your answer to the current question. Click on Save & Next to save your answer for the current question and then go to the next question.
    +
    Note that selecting an option does NOT save your answer to the current question. Click on "Save >" to save your answer for the current question and then go to the next question.
    From 521b47cad1aa12c1a23d729a9fdf52fad0d3de7c Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Tue, 25 Jun 2024 12:30:25 +0530 Subject: [PATCH 05/13] allow answered ques to also be set for review apriori --- src/components/Questions/QuestionModal.vue | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/components/Questions/QuestionModal.vue b/src/components/Questions/QuestionModal.vue index 0bde054..52491ed 100644 --- a/src/components/Questions/QuestionModal.vue +++ b/src/components/Questions/QuestionModal.vue @@ -327,10 +327,6 @@ To attempt this question, unselect an answer to another question in this section state.localResponses[props.currentQuestionIndex].answer = state.draftResponses[props.currentQuestionIndex] context.emit("submit-question") - if (isQuizAssessment.value && state.localResponses[props.currentQuestionIndex].marked_for_review) { - state.localResponses[props.currentQuestionIndex].marked_for_review = false - context.emit("update-review-status") - } } function clearAnswer() { @@ -419,18 +415,18 @@ To attempt this question, unselect an answer to another question in this section function endTest() { if (!props.hasQuizEnded && state.hasEndTestBeenClickedOnce) { let attemptedQuestions = 0; - let markedForReviewQuestions = 0; + let markedForReviewAndUnansweredQuestions = 0; for (const response of props.responses) { if (response.answer != null) { attemptedQuestions += 1; } - if (response.marked_for_review == true) { - markedForReviewQuestions += 1 + if (response.marked_for_review == true && response.answer == null) { + markedForReviewAndUnansweredQuestions += 1 } } state.toast.success( - `You have answered ${attemptedQuestions} out of ${props.numQuestions} questions. Click on the Question Palette to review unanswered questions before submitting the test. Click the End Test button again to make the final submission. -ALERT: ${markedForReviewQuestions} questions which are marked for review are also unanswered.`, + `You have answered ${attemptedQuestions} out of ${props.numQuestions} questions. ${markedForReviewAndUnansweredQuestions} questions which are marked for review are unanswered. +Click on the Question Palette to view unanswered questions before submitting the test. Click the End Test button again to make the final submission.`, { position: POSITION.TOP_CENTER, timeout: 5000, From 8420e9b9b6d08ac4f78bd3c43e31c5e56f260886 Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Sun, 14 Jul 2024 14:42:58 +0530 Subject: [PATCH 06/13] minor ui changes --- src/components/InstructionPage.vue | 4 +-- src/components/Questions/Footer.vue | 35 ++++++++++++++++----- src/components/Questions/Palette/Review.vue | 2 +- src/components/Questions/QuestionModal.vue | 14 ++------- tailwind.config.js | 2 +- 5 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/components/InstructionPage.vue b/src/components/InstructionPage.vue index 3d663a8..d7784bd 100644 --- a/src/components/InstructionPage.vue +++ b/src/components/InstructionPage.vue @@ -88,7 +88,7 @@
  • To select you answer, click on the button of one of the options.
  • To deselect your chosen answer, click on the button of the chosen option again or click on the Clear button.
  • To change your chosen answer, click on the button of another option.
  • -
  • To save your answer, you MUST click on the "Save >" button.
  • +
  • To save your answer, you MUST click on the "Save & Next" button.
  • To change your answer to a question that has already been answered, first select that question for answering and then follow the procedure for answering that type of question.
  • @@ -96,7 +96,7 @@
    !
    -
    Note that selecting an option does NOT save your answer to the current question. Click on "Save >" to save your answer for the current question and then go to the next question.
    +
    Note that selecting an option does NOT save your answer to the current question. Click on "Save & Next" to save your answer for the current question and then go to the next question.
    diff --git a/src/components/Questions/Footer.vue b/src/components/Questions/Footer.vue index 73df3aa..9b8db49 100644 --- a/src/components/Questions/Footer.vue +++ b/src/components/Questions/Footer.vue @@ -59,7 +59,7 @@ }" :titleConfig="markForReviewButtonTitleConfig" :buttonClass="markForReviewButtonClass" - :isDisabled="isAnswerSubmitted || isSessionAnswerRequestProcessing" + :isDisabled="isAnswerSubmitted || isSessionAnswerRequestProcessing || isMarkedForReview" @click="toggleMarkForReview" data-test="markForReviewButton" > @@ -107,6 +107,8 @@ import { toRefs, computed, PropType, + onMounted, + onBeforeUnmount } from "vue"; export default defineComponent({ @@ -155,6 +157,10 @@ export default defineComponent({ }, setup(props, context) { const isQuizAssessment = computed(() => props.quizType == "assessment" || props.quizType == "omr-assessment"); + const isSmallScreen = ref(false); + const updateScreenSize = () => { + isSmallScreen.value = window.matchMedia("(max-width: 500px)").matches; + }; const state = reactive({ assessmentNavigationButtonIconClass: [ { @@ -215,12 +221,12 @@ export default defineComponent({ } as IconButtonTitleConfig); const markForReviewButtonTitleConfig = computed(() => ({ - value: props.isMarkedForReview ? "Clear Review" : "Mark For Review", + value: isSmallScreen.value ? "Review >" : "Mark For Review & Next", class: ["text-xxs bp-500:text-sm lg:text-base xl:text-lg font-bold", "text-violet-500"], } as IconButtonTitleConfig)); const saveAndNextButtonTitleConfig = ref({ - value: "Save >", + value: "Save & Next", class: [state.assessmentTextButtonTitleClass, "text-emerald-500"], } as IconButtonTitleConfig); @@ -243,10 +249,15 @@ export default defineComponent({ } function toggleMarkForReview() { - if (props.isMarkedForReview) { - context.emit("clear-review"); - } else { + if (!props.isMarkedForReview) { context.emit("mark-for-review"); + // wait for processing to be done and answer to be submitted + const checkProcessingDone = setInterval(() => { + if (!props.isSessionAnswerRequestProcessing) { + if (props.continueAfterAnswerSubmit) context.emit("continue"); + clearInterval(checkProcessingDone); + } + }, 100); // check every 100ms } } @@ -296,6 +307,16 @@ export default defineComponent({ "p-4 px-8 bp-500:p-6 bp-500:px-12 rounded-2xl shadow-xl disabled:opacity-50 disabled:cursor-not-allowed", ]); + // Setup listeners for screen size changes + onMounted(() => { + updateScreenSize(); + window.addEventListener("resize", updateScreenSize); + }); + + onBeforeUnmount(() => { + window.removeEventListener("resize", updateScreenSize); + }); + return { ...toRefs(state), previousQuestionButtonIconConfig, @@ -319,6 +340,6 @@ export default defineComponent({ isQuizAssessment, }; }, - emits: ["submit", "previous", "continue", "clear", "mark-for-review", "clear-review"], + emits: ["submit", "previous", "continue", "clear", "mark-for-review"], }); diff --git a/src/components/Questions/Palette/Review.vue b/src/components/Questions/Palette/Review.vue index 6a4d6d1..7c55868 100644 --- a/src/components/Questions/Palette/Review.vue +++ b/src/components/Questions/Palette/Review.vue @@ -3,7 +3,7 @@ :title="title" :hasQuizEnded="hasQuizEnded" iconName="skip-rounded" - iconClass="bg-violet-100 border-violet-600" + iconClass="bg-violet-300 border-violet-600" > diff --git a/src/components/Questions/QuestionModal.vue b/src/components/Questions/QuestionModal.vue index 52491ed..39997d7 100644 --- a/src/components/Questions/QuestionModal.vue +++ b/src/components/Questions/QuestionModal.vue @@ -85,7 +85,6 @@ @previous="showPreviousQuestion" @clear="clearAnswer" @mark-for-review="markForReviewQuestion" - @clear-review="clearReviewQuestion" data-test="footer" > @@ -255,7 +254,7 @@ export default defineComponent({ state.toast.warning( `You have already attempted maximum allowed (${props.maxQuestionsAllowedToAttempt}) questions in current section (Q.${props.qsetIndexLimits.low + 1} - Q.${props.qsetIndexLimits.high}). -To attempt this question, unselect an answer to another question in this section. +To attempt Q.${props.currentQuestionIndex + 1}, unselect an answer to another question in this section. `, { position: POSITION.TOP_CENTER, @@ -339,7 +338,7 @@ To attempt this question, unselect an answer to another question in this section state.previousLocalResponse = clonedeep(state.localResponses[props.currentQuestionIndex]); state.localResponses[props.currentQuestionIndex].marked_for_review = true; state.toast.info( - `Question ${props.currentQuestionIndex + 1} marked for review!`, + `Question ${props.currentQuestionIndex + 1} is marked for review!`, { position: POSITION.TOP_LEFT, timeout: 2000 @@ -348,12 +347,6 @@ To attempt this question, unselect an answer to another question in this section context.emit("update-review-status") } - function clearReviewQuestion() { - state.previousLocalResponse = clonedeep(state.localResponses[props.currentQuestionIndex]); - state.localResponses[props.currentQuestionIndex].marked_for_review = false; - context.emit("update-review-status") - } - function showNextQuestion() { // It toggles the reRenderKey from 0 to 1 or 1 to 0. And changing the reRender key, re-renders the component. // we reRender the whole component as textarea is holding the details which is not getting updated @@ -400,7 +393,7 @@ To attempt this question, unselect an answer to another question in this section currentQuestionResponseAnswer.value } state.isDraftAnswerCleared = false - state.toast.clear() // if toast exists in current state, clear when you switch state + // state.toast.clear() // if toast exists in current state, clear when you switch state } function numericalAnswerUpdated(answer: number | null) { @@ -578,7 +571,6 @@ Click on the Question Palette to view unanswered questions before submitting the subjectiveAnswerUpdated, clearAnswer, markForReviewQuestion, - clearReviewQuestion, endTest, endTestByTime, navigateToQuestion, diff --git a/tailwind.config.js b/tailwind.config.js index 46fcfc6..05778c5 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -14,7 +14,7 @@ module.exports = { 1: "1px", }, fontSize: { - xxs: "0.65rem", + xxs: "0.80rem", }, }, screens: { From ab50a96393ab0c7fbfdf77c5e7a8216cf1c1fc3d Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Sun, 14 Jul 2024 14:44:27 +0530 Subject: [PATCH 07/13] updating instr --- src/components/InstructionPage.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/InstructionPage.vue b/src/components/InstructionPage.vue index d7784bd..2c49acb 100644 --- a/src/components/InstructionPage.vue +++ b/src/components/InstructionPage.vue @@ -89,6 +89,7 @@
  • To deselect your chosen answer, click on the button of the chosen option again or click on the Clear button.
  • To change your chosen answer, click on the button of another option.
  • To save your answer, you MUST click on the "Save & Next" button.
  • +
  • To review the question later, you can click on the "Mark For Review & Next" button.
  • To change your answer to a question that has already been answered, first select that question for answering and then follow the procedure for answering that type of question.
  • From e5d7a0103a597ce25a9e7bef6904a70bd12804b5 Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Wed, 17 Jul 2024 10:46:09 +0530 Subject: [PATCH 08/13] some instr changes --- src/components/InstructionPage.vue | 4 ++-- src/components/Questions/QuestionModal.vue | 14 ++++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/components/InstructionPage.vue b/src/components/InstructionPage.vue index 2c49acb..7683293 100644 --- a/src/components/InstructionPage.vue +++ b/src/components/InstructionPage.vue @@ -63,11 +63,11 @@ You have answered the question
    - + You have not visited the question yet
    - + You have not answered the question
    diff --git a/src/components/Questions/QuestionModal.vue b/src/components/Questions/QuestionModal.vue index 39997d7..21057fc 100644 --- a/src/components/Questions/QuestionModal.vue +++ b/src/components/Questions/QuestionModal.vue @@ -337,8 +337,12 @@ To attempt Q.${props.currentQuestionIndex + 1}, unselect an answer to another qu function markForReviewQuestion() { state.previousLocalResponse = clonedeep(state.localResponses[props.currentQuestionIndex]); state.localResponses[props.currentQuestionIndex].marked_for_review = true; + let markForReviewInfoText = `Question ${props.currentQuestionIndex + 1} is marked for review.` + if (state.draftResponses[props.currentQuestionIndex] != null) { + markForReviewInfoText += "This action does not save your answer!" + } state.toast.info( - `Question ${props.currentQuestionIndex + 1} is marked for review!`, + markForReviewInfoText, { position: POSITION.TOP_LEFT, timeout: 2000 @@ -418,11 +422,13 @@ To attempt Q.${props.currentQuestionIndex + 1}, unselect an answer to another qu } } state.toast.success( - `You have answered ${attemptedQuestions} out of ${props.numQuestions} questions. ${markedForReviewAndUnansweredQuestions} questions which are marked for review are unanswered. -Click on the Question Palette to view unanswered questions before submitting the test. Click the End Test button again to make the final submission.`, + `You have answered ${attemptedQuestions} out of ${props.numQuestions} questions. +${markedForReviewAndUnansweredQuestions} questions marked for review are UNANSWERED. +Click on the Question Palette to view unanswered questions before submitting the test. +Click the End Test button again to make the final submission.`, { position: POSITION.TOP_CENTER, - timeout: 5000, + timeout: 6000, draggablePercent: 0.4 } ) From c68bcf42e38d105a9cbc3eaa50c5ae353737acc6 Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Wed, 17 Jul 2024 10:58:26 +0530 Subject: [PATCH 09/13] jest mocks --- jest.init.ts | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/jest.init.ts b/jest.init.ts index decc871..750fd09 100644 --- a/jest.init.ts +++ b/jest.init.ts @@ -7,12 +7,33 @@ import { config } from "@vue/test-utils"; import VueClickAway from "vue3-click-away"; +// Mock window.matchMedia +Object.defineProperty(window, 'matchMedia', { + writable: true, + value: (query: string) => ({ + matches: false, + media: query, + onchange: null, + addListener: jest.fn(), // deprecated + removeListener: jest.fn(), // deprecated + addEventListener: jest.fn(), + removeEventListener: jest.fn(), + dispatchEvent: jest.fn(), + }), +}); + +// Mock window.scrollTo +Object.defineProperty(window, 'scrollTo', { + writable: true, + value: jest.fn(), +}); + // inline-svg stub const InlineSvg = { template: "", }; config.global.stubs = { - InlineSvg: InlineSvg, + InlineSvg, }; config.global.plugins = [VueClickAway]; From d812d710bcb990f554db0c58b8cbba2ebaf561f1 Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Mon, 19 Aug 2024 17:34:05 +0530 Subject: [PATCH 10/13] 19 aug changes --- src/components/Questions/Footer.vue | 2 +- src/components/Questions/QuestionModal.vue | 7 ++++++- src/components/Splash.vue | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/components/Questions/Footer.vue b/src/components/Questions/Footer.vue index 9b8db49..79a8321 100644 --- a/src/components/Questions/Footer.vue +++ b/src/components/Questions/Footer.vue @@ -59,7 +59,7 @@ }" :titleConfig="markForReviewButtonTitleConfig" :buttonClass="markForReviewButtonClass" - :isDisabled="isAnswerSubmitted || isSessionAnswerRequestProcessing || isMarkedForReview" + :isDisabled="isSessionAnswerRequestProcessing || isMarkedForReview" @click="toggleMarkForReview" data-test="markForReviewButton" > diff --git a/src/components/Questions/QuestionModal.vue b/src/components/Questions/QuestionModal.vue index 21057fc..2f1ca46 100644 --- a/src/components/Questions/QuestionModal.vue +++ b/src/components/Questions/QuestionModal.vue @@ -325,6 +325,7 @@ To attempt Q.${props.currentQuestionIndex + 1}, unselect an answer to another qu state.previousLocalResponse = clonedeep(state.localResponses[props.currentQuestionIndex]); state.localResponses[props.currentQuestionIndex].answer = state.draftResponses[props.currentQuestionIndex] + state.localResponses[props.currentQuestionIndex].marked_for_review = false; context.emit("submit-question") } @@ -338,7 +339,11 @@ To attempt Q.${props.currentQuestionIndex + 1}, unselect an answer to another qu state.previousLocalResponse = clonedeep(state.localResponses[props.currentQuestionIndex]); state.localResponses[props.currentQuestionIndex].marked_for_review = true; let markForReviewInfoText = `Question ${props.currentQuestionIndex + 1} is marked for review.` - if (state.draftResponses[props.currentQuestionIndex] != null) { + if (state.localResponses[props.currentQuestionIndex].answer != null) { + markForReviewInfoText += "This action clears your answer!" + clearAnswer() + submitQuestion() + } else if (state.draftResponses[props.currentQuestionIndex] != null) { markForReviewInfoText += "This action does not save your answer!" } state.toast.info( diff --git a/src/components/Splash.vue b/src/components/Splash.vue index 44306f9..cd012d3 100644 --- a/src/components/Splash.vue +++ b/src/components/Splash.vue @@ -185,7 +185,7 @@ export default defineComponent({ }; if (isSessionDataFetched.value) { if (props.isFirstSession) { - config.value = "Let's Start"; + config.value = "Let's Starsldkfjsdt"; } else { if (props.hasQuizEnded && !props.reviewAnswers) { config.class = "text-sm md:text-sm text-white font-poppins-bold"; From 09964d6565b049dacc6b8f3b7ef78c0201ff1f90 Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Tue, 27 Aug 2024 23:04:16 +0530 Subject: [PATCH 11/13] adds reviewed label --- src/components/InstructionPage.vue | 44 ++++++++++++++----- src/components/Questions/Body.vue | 17 +++++++ src/components/Questions/QuestionModal.vue | 24 ++++++---- src/components/Splash.vue | 2 +- src/views/Player.vue | 5 ++- .../specs/renders-player-to-check-timed.js | 3 ++ 6 files changed, 71 insertions(+), 24 deletions(-) diff --git a/src/components/InstructionPage.vue b/src/components/InstructionPage.vue index 7683293..a2715b9 100644 --- a/src/components/InstructionPage.vue +++ b/src/components/InstructionPage.vue @@ -54,31 +54,48 @@

    General Instructions

      -
    1. The countdown timer in the top right corner of screen will display the remaining time available for you to complete the test. When the timer reaches zero, the test will end by itself. You will not be required to end or submit your test.
    2. -
    3. You can click on the button on the top left corner of the page to expand the Question Palette.
    4. -
    5. The Question Palette will show the status of each question using one of the following symbols: +
    6. + The countdown timer in the top right corner of the screen will display the remaining time available for you to complete the test. When the timer reaches zero, the test will end by itself. You will not be required to end or submit your test. +
    7. +
    8. + You can click on the + + + + button on the top left corner of the page to expand the Question Palette. +
    9. +
    10. + The Question Palette will show the status of each question using one of the following symbols:
      - + You have answered the question
      - + You have not visited the question yet
      - + You have not answered the question
      -
      - - You have marked the question for review +
      + + You have marked the question for review + NEW
    11. -
    12. You can click on the button again to collapse the Question Palette.
    13. +
    14. + You can click on the + + + + button again to collapse the Question Palette. +
    +

    Answering a Question:

    @@ -89,7 +106,10 @@
  • To deselect your chosen answer, click on the button of the chosen option again or click on the Clear button.
  • To change your chosen answer, click on the button of another option.
  • To save your answer, you MUST click on the "Save & Next" button.
  • -
  • To review the question later, you can click on the "Mark For Review & Next" button.
  • +
  • + To review a question later, you can click on the "Mark For Review & Next" button. This action will not change your answer. + NEW +
  • To change your answer to a question that has already been answered, first select that question for answering and then follow the procedure for answering that type of question.
  • @@ -97,7 +117,7 @@
    !
    -
    Note that selecting an option does NOT save your answer to the current question. Click on "Save & Next" to save your answer for the current question and then go to the next question.
    +
    Note that selecting an option DOES NOT save your answer to the current question. Click on "Save & Next" to save your answer for the current question and then go to the next question.
    diff --git a/src/components/Questions/Body.vue b/src/components/Questions/Body.vue index 03c5120..e924f88 100644 --- a/src/components/Questions/Body.vue +++ b/src/components/Questions/Body.vue @@ -271,6 +271,15 @@ + +
    + REVIEWED + ANSWERED + NOT ANSWERED +
    props.currentQuestionIndex, (newValue: Number) => { + console.log(state.localResponses[props.currentQuestionIndex].answer, state.localResponses[props.currentQuestionIndex].marked_for_review) state.localCurrentQuestionIndex = newValue.valueOf() if (!props.hasQuizEnded && optionalLimitReached.value && currentQuestionResponseAnswer.value == null) { state.toast.warning( @@ -322,10 +325,12 @@ To attempt Q.${props.currentQuestionIndex + 1}, unselect an answer to another qu function submitQuestion() { if (!state.localResponses.length) return - state.previousLocalResponse = clonedeep(state.localResponses[props.currentQuestionIndex]); state.localResponses[props.currentQuestionIndex].answer = state.draftResponses[props.currentQuestionIndex] - state.localResponses[props.currentQuestionIndex].marked_for_review = false; + if (state.draftResponses[props.currentQuestionIndex] != null) { + // question is answered => set review to false + state.localResponses[props.currentQuestionIndex].marked_for_review = false; + } context.emit("submit-question") } @@ -340,17 +345,17 @@ To attempt Q.${props.currentQuestionIndex + 1}, unselect an answer to another qu state.localResponses[props.currentQuestionIndex].marked_for_review = true; let markForReviewInfoText = `Question ${props.currentQuestionIndex + 1} is marked for review.` if (state.localResponses[props.currentQuestionIndex].answer != null) { - markForReviewInfoText += "This action clears your answer!" + markForReviewInfoText += `\nAnswer to Question ${props.currentQuestionIndex + 1} is cleared!` clearAnswer() submitQuestion() } else if (state.draftResponses[props.currentQuestionIndex] != null) { - markForReviewInfoText += "This action does not save your answer!" + markForReviewInfoText += "\nThis action does not save your answer!" } state.toast.info( markForReviewInfoText, { position: POSITION.TOP_LEFT, - timeout: 2000 + timeout: 3000, } ) context.emit("update-review-status") @@ -427,10 +432,11 @@ To attempt Q.${props.currentQuestionIndex + 1}, unselect an answer to another qu } } state.toast.success( - `You have answered ${attemptedQuestions} out of ${props.numQuestions} questions. -${markedForReviewAndUnansweredQuestions} questions marked for review are UNANSWERED. -Click on the Question Palette to view unanswered questions before submitting the test. -Click the End Test button again to make the final submission.`, + `Total Questions: ${props.numQuestions} +Questions Answered: ${attemptedQuestions} +Questions Marked for Review and Unanswered: ${markedForReviewAndUnansweredQuestions} +\nUse the Question Palette to review all questions. +For final submission, click the End Test button again.`, { position: POSITION.TOP_CENTER, timeout: 6000, diff --git a/src/components/Splash.vue b/src/components/Splash.vue index cd012d3..44306f9 100644 --- a/src/components/Splash.vue +++ b/src/components/Splash.vue @@ -185,7 +185,7 @@ export default defineComponent({ }; if (isSessionDataFetched.value) { if (props.isFirstSession) { - config.value = "Let's Starsldkfjsdt"; + config.value = "Let's Start"; } else { if (props.hasQuizEnded && !props.reviewAnswers) { config.class = "text-sm md:text-sm text-white font-poppins-bold"; diff --git a/src/views/Player.vue b/src/views/Player.vue index 813e96c..52483d5 100644 --- a/src/views/Player.vue +++ b/src/views/Player.vue @@ -240,7 +240,7 @@ export default defineComponent({ }); const isQuizLoaded = computed(() => numQuestions.value > 0); const scorecardResult = computed(() => ({ - title: isQuizAssessment.value ? "Score" : "Accuracy", + title: isQuizAssessment.value ? "Score" : "Score %", value: scorecardResultValue.value, })); @@ -513,7 +513,8 @@ export default defineComponent({ state.continueAfterAnswerSubmit = false; const itemResponse = state.responses[state.currentQuestionIndex]; const payload: UpdateSessionAnswerAPIPayload = { - answer: itemResponse.answer + answer: itemResponse.answer, + marked_for_review: itemResponse.marked_for_review } if (!isQuizAssessment.value) { // we update time spent for homework immediately when answer is submitted diff --git a/tests/e2e/specs/renders-player-to-check-timed.js b/tests/e2e/specs/renders-player-to-check-timed.js index 15b0f5f..3d0404c 100644 --- a/tests/e2e/specs/renders-player-to-check-timed.js +++ b/tests/e2e/specs/renders-player-to-check-timed.js @@ -342,6 +342,7 @@ describe("Player for Homework Quizzes", () => { .should("deep.equal", { answer: [0], time_spent: 3, + marked_for_review: false, }); }); @@ -365,6 +366,7 @@ describe("Player for Homework Quizzes", () => { .should("deep.equal", { answer: [0], time_spent: 0, + marked_for_review: false, }); // click submit again to continue cy.get('[data-test="modal"]') @@ -405,6 +407,7 @@ describe("Player for Homework Quizzes", () => { .should("deep.equal", { answer: [1], time_spent: 3, // not 6 + marked_for_review: false, }); }); }); From 27aab5477b91e890a598396c17db4aee7aa45fb4 Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Thu, 29 Aug 2024 13:11:15 +0530 Subject: [PATCH 12/13] small corrections --- src/components/InstructionPage.vue | 2 +- src/components/Questions/QuestionModal.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/InstructionPage.vue b/src/components/InstructionPage.vue index a2715b9..4f4e700 100644 --- a/src/components/InstructionPage.vue +++ b/src/components/InstructionPage.vue @@ -107,7 +107,7 @@
  • To change your chosen answer, click on the button of another option.
  • To save your answer, you MUST click on the "Save & Next" button.
  • - To review a question later, you can click on the "Mark For Review & Next" button. This action will not change your answer. + To review a question later, you can click on the "Review >" button. This action will not save your answer. NEW
  • diff --git a/src/components/Questions/QuestionModal.vue b/src/components/Questions/QuestionModal.vue index 81c068f..86c4dd9 100644 --- a/src/components/Questions/QuestionModal.vue +++ b/src/components/Questions/QuestionModal.vue @@ -355,7 +355,7 @@ To attempt Q.${props.currentQuestionIndex + 1}, unselect an answer to another qu markForReviewInfoText, { position: POSITION.TOP_LEFT, - timeout: 3000, + timeout: 3500, } ) context.emit("update-review-status") From 6fa9bedc2a2e607d2e82a8d3e34d8c9bc6515295 Mon Sep 17 00:00:00 2001 From: suryabulusu Date: Thu, 29 Aug 2024 13:19:49 +0530 Subject: [PATCH 13/13] changes label --- src/components/Questions/Body.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Questions/Body.vue b/src/components/Questions/Body.vue index e924f88..edb75e6 100644 --- a/src/components/Questions/Body.vue +++ b/src/components/Questions/Body.vue @@ -276,7 +276,7 @@ v-if="isQuizAssessment && !hasQuizEnded && !isSessionAnswerRequestProcessing" class="mx-6 md:mx-10 pb-4" > - REVIEWED + MARKED FOR REVIEW ANSWERED NOT ANSWERED