Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…into feat/review-quiz
  • Loading branch information
suryabulusu committed Nov 25, 2024
2 parents 729fa4f + e62e560 commit 3e2dee8
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 117 deletions.
16 changes: 10 additions & 6 deletions src/components/InstructionPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
<tr>
<th class="border-black border-1 text-left px-4 py-2">Subjects</th>
<td class="border-black border-1 px-4 py-2" data-test="subject">
{{ $props.subject }}
{{ $props.subject|| "..." }}
</td>
</tr>
</table>
Expand Down Expand Up @@ -98,7 +98,7 @@
></span>
{{ $t("generalInstructions.expandPalette") }}
</li>
<li>
<li v-if="!isOmrMode">
{{ $t("generalInstructions.paletteSymbols") }}
<div class="flex flex-wrap mx-2 md:mx-4 my-2">
<div class="flex items-center my-2 md:mx-4">
Expand Down Expand Up @@ -133,17 +133,17 @@
<li>{{ $t("answeringQuestion.selectAnswer") }}</li>
<li>{{ $t("answeringQuestion.deselectAnswer") }}</li>
<li>{{ $t("answeringQuestion.changeAnswer") }}</li>
<li>{{ $t("answeringQuestion.saveAnswer") }}</li>
<li class="relative border border-violet-600 p-2 rounded-md">
<li v-if="!isOmrMode">{{ $t("answeringQuestion.saveAnswer") }}</li>
<li class="relative border border-violet-600 p-2 rounded-md" v-if="!isOmrMode">
{{ $t("answeringQuestion.reviewQuestion") }}
<span class="bg-violet-800 text-white text-xs font-bold py-0.5 px-2 rounded-full">NEW</span>
</li>
</ol>
</li>
<li>{{ $t("answeringQuestion.changeAnsweredQuestion") }}</li>
<li v-if="!isOmrMode">{{ $t("answeringQuestion.changeAnsweredQuestion") }}</li>
</ol>
</div>
<div class="mt-5 ml-6 mr-4 flex border-red-400 border-1 p-2">
<div class="mt-5 ml-6 mr-4 flex border-red-400 border-1 p-2" v-if="!isOmrMode">
<div class="float-left text-red-400 pr-5 pl-3 text-xl font-bold">!</div>
<div class="float-right text-justify pr-2">
{{ $t("answeringQuestion.noteSaveAnswer") }}
Expand Down Expand Up @@ -206,6 +206,10 @@ export default defineComponent({
type: [null, String] as PropType<testFormat>,
default: null,
},
isOmrMode: {
type: Boolean,
default: false,
},
},
setup(props) {
const { t, locale } = useI18n();
Expand Down
183 changes: 100 additions & 83 deletions src/components/Omr/OmrModal.vue
Original file line number Diff line number Diff line change
@@ -1,72 +1,65 @@
<template>
<div class="flex flex-col bg-white w-full justify-between">
<Header
class="fixed top-0"
v-if="isQuizAssessment"
:hasQuizEnded="hasQuizEnded"
:hasTimeLimit="quizTimeLimit != null"
:quizType="quizType"
:title="title"
:userId="userId"
:isOmrMode="isOmrMode"
:isSessionAnswerRequestProcessing="isSessionAnswerRequestProcessing"
v-model:isPaletteVisible="isPaletteVisible"
:timeRemaining="timeRemaining"
:warningTimeLimit="timeLimitWarningThreshold"
@time-limit-warning="displayTimeLimitWarning"
@end-test="endTest"
@end-test-by-time="endTestByTime"
data-test="omr-header"
></Header>
<div
class="flex flex-col grow space-y-10"
>
<div class="mt-20 mb-20">
<div
v-for="(questionSetState, index) in questionSetStates" :key="index" class="space-y-2 mt-[66px]">
<div class="bg-gray-300"><p :class="titleTextClass" :data-test="`questionSetTitle-${index}`">{{ questionSetState.title }}</p></div>
<p :class="instructionTextClass" v-html="questionSetState.instructionText" :data-test="`questionSetInstruction-${index}`"></p>
<div class="mt-4 space-y-4">
<OmrItem
v-for="(questionState, qindex) in questionSetState.paletteItems"
:class="{ 'mt-4': qindex == 0 }"
:options="$props.questions[questionState.index].options"
:correctAnswer="$props.questions[questionState.index].correct_answer"
:questionType="$props.questions[questionState.index].type"
:isGradedQuestion="$props.questions[questionState.index].graded"
:maxCharLimit="$props.questions[questionState.index].max_char_limit"
:matrixSize="$props.questions[questionState.index].matrix_size"
:isPortrait="isPortrait"
:quizType="quizType"
:hasQuizEnded="hasQuizEnded"
:submittedAnswer="draftResponses[questionState.index]"
:isQuestionDisabled="questionDisabledArray[questionState.index]"
:currentQuestionIndex="questionState.index"
@option-selected="questionOptionSelected"
@subjective-answer-entered="subjectiveAnswerUpdated"
@numerical-answer-entered="numericalAnswerUpdated"
:key="questionState.index"
:data-test="`OmrItem-${questionState.index}`"
:ref="`omritem-${questionState.index}`"
></OmrItem>
</div>
<div class="flex flex-col bg-white w-full h-full overflow-auto justify-between">
<Header class="fixed top-0" v-if="isQuizAssessment" :hasQuizEnded="hasQuizEnded"
:hasTimeLimit="quizTimeLimit != null" :title="title" :userId="userId" :isOmrMode=true
:isSessionAnswerRequestProcessing="isSessionAnswerRequestProcessing" v-model:isPaletteVisible="isPaletteVisible"
:timeRemaining="timeRemaining" :warningTimeLimit="timeLimitWarningThreshold"
@time-limit-warning="displayTimeLimitWarning" @end-test="endTest" @end-test-by-time="endTestByTime"
data-test="omr-header"></Header>
<div class="flex flex-col w-full h-full mt-20 mb-20 -z-10">
<div class="h-full relative">
<div class="scroll-container flex flex-col grow bg-white w-full justify-between overflow-hidden mt-[66px]">
<div class="flex grow flex-col w-full h-full overflow-y-auto">
<QuestionPalette v-if="isPaletteVisible" :hasQuizEnded="hasQuizEnded" :questionSetStates="questionSetStates"
:currentQuestionIndex="currentQuestionIndex" :title="title" :subject="subject" :testFormat="testFormat"
:maxMarks="maxMarks" :numQuestions="numQuestions" :quizTimeLimit="quizTimeLimit" :isOmrMode=true
class="absolute w-full h-full sm:w-2/3 lg:w-1/2 xl:w-1/3 z-10 bg-white overflow-y-scroll pb-[56px]"
data-test="questionPalette">
</QuestionPalette>
</div>
</div>

<!-- footer -->
<div
class="flex w-full lg:p-6 justify-between z-50 place-self-end fixed bottom-0"
:class="{
<div v-for="(questionSetState, index) in questionSetStates" :key="index" class="space-y-2 pb-[56px]">
<div class="bg-gray-300">
<p :class="titleTextClass" :data-test="`questionSetTitle-${index}`">{{ questionSetState.title }}</p>
</div>
<p :class="instructionTextClass" v-html="questionSetState.instructionText"
:data-test="`questionSetInstruction-${index}`"></p>
<div class="mt-4 space-y-4">
<!-- it is being stopping endbutton make sur eu -->
<OmrItem v-for="(questionState, qindex) in questionSetState.paletteItems" :class="{ 'mt-4': qindex == 0 }"
:options="$props.questions[questionState.index].options"
:correctAnswer="$props.questions[questionState.index].correct_answer"
:questionType="$props.questions[questionState.index].type"
:isGradedQuestion="$props.questions[questionState.index].graded"
:maxCharLimit="$props.questions[questionState.index].max_char_limit"
:matrixSize="$props.questions[questionState.index].matrix_size"
:isPortrait="isPortrait"
:quizType="quizType"
:hasQuizEnded="hasQuizEnded"
:submittedAnswer="draftResponses[questionState.index]"
:isQuestionDisabled="questionDisabledArray[questionState.index]"
:currentQuestionIndex="questionState.index"
@option-selected="questionOptionSelected"
@subjective-answer-entered="subjectiveAnswerUpdated"
@numerical-answer-entered="numericalAnswerUpdated"
:key="questionState.index"
:data-test="`OmrItem-${questionState.index}`"
:ref="`omritem-${questionState.index}`"></OmrItem>
</div>
</div>
<!-- footer -->
<div class="flex w-full lg:p-6 justify-between z-50 place-self-end fixed bottom-0" :class="{
'bg-white p-4': !isQuizAssessment,
'bg-gray-200 py-2 px-2': isQuizAssessment,
}"
></div>
}"></div>
</div>
</div>
</div>
</div>
</template>

<script lang="ts">
import Header from "../Questions/Header.vue"
import QuestionPalette from "../Questions/Palette/QuestionPalette.vue"
import OmrItem from "./OmrItem.vue"
import {
defineComponent,
Expand All @@ -85,6 +78,7 @@ import {
SubmittedResponse,
DraftResponse,
quizType,
testFormat,
QuestionSetIndexLimits,
questionSetPalette,
TimeLimit,
Expand All @@ -99,7 +93,8 @@ export default defineComponent({
name: "OmrModal",
components: {
OmrItem,
Header
Header,
QuestionPalette
},
props: {
questions: {
Expand Down Expand Up @@ -158,18 +153,26 @@ export default defineComponent({
type: Number,
default: 0
},
isOmrMode: {
type: Boolean,
default: false,
},
userId: {
type: String,
default: ""
},
title: {
required: true,
type: [null, String] as PropType<quizTitleType>,
}
},
subject: {
type: String,
default: null,
},
testFormat: {
type: [null, String] as PropType<testFormat>,
default: null,
},
maxMarks: {
type: Number,
required: true,
},
},
setup(props, context) {
const state = reactive({
Expand Down Expand Up @@ -217,15 +220,15 @@ export default defineComponent({
(newValue: Number) => {
if (!props.hasQuizEnded && optionalLimitReachedArray.value[props.qsetIndex]) {
state.toast.warning(
`You have already attempted maximum allowed (${props.maxQuestionsAllowedToAttempt}) questions in current section (Q.${props.qsetIndexLimits.low + 1} - Q.${props.qsetIndexLimits.high}).
`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.
`,
{
position: POSITION.TOP_CENTER,
timeout: 7000,
draggablePercent: 0.4
}
{
position: POSITION.TOP_CENTER,
timeout: 7000,
draggablePercent: 0.4
}
)
context.emit("test-optional-warning-shown");
}
Expand Down Expand Up @@ -288,12 +291,12 @@ export default defineComponent({
}
}
state.toast.success(
`You have answered ${attemptedQuestions} out of ${props.numQuestions} questions. Please verify your responses and click End Test button again to make final submission.`,
{
position: POSITION.TOP_CENTER,
timeout: 5000,
draggablePercent: 0.4
}
`You have answered ${attemptedQuestions} out of ${props.numQuestions} questions. Please verify your responses and click End Test button again to make final submission.`,
{
position: POSITION.TOP_CENTER,
timeout: 5000,
draggablePercent: 0.4
}
)
state.hasEndTestBeenClickedOnce = false;
} else {
Expand Down Expand Up @@ -443,12 +446,12 @@ export default defineComponent({
function displayTimeLimitWarning() {
if (!props.hasQuizEnded) {
state.toast.warning(
`Only ${timeLimitWarningThreshold} minutes left! Please submit!`,
{
position: POSITION.TOP_CENTER,
timeout: 3000,
draggablePercent: 0.4
}
`Only ${timeLimitWarningThreshold} minutes left! Please submit!`,
{
position: POSITION.TOP_CENTER,
timeout: 3000,
draggablePercent: 0.4
}
)
context.emit("test-warning-shown");
}
Expand Down Expand Up @@ -490,3 +493,17 @@ export default defineComponent({
],
});
</script>

<style>
.truncate {
@apply whitespace-nowrap overflow-hidden overflow-ellipsis;
max-width: 10em;
/*(10em) Adjust this value to determine the maximum width in characters */
}
.scroll-container {
height: 100vh;
/* Adjust the height as per your needs */
overflow: auto;
}
</style>
5 changes: 3 additions & 2 deletions src/components/Questions/Body.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
></p>
</div>
<!-- question text -->
<div class="mx-6 md:mx-10">
<div class="mx-6 md:mx-10" v-bind="isQuizAssessment && !hasQuizEnded ? { inert: true } : {}">
<p :class="questionTextClass" data-test="text" v-html="text"></p>
</div>
<div :class="orientationClass">
Expand All @@ -52,7 +52,7 @@
/>
</div>
<!-- question image container -->
<div :class="questionImageContainerClass" v-if="isQuestionImagePresent">
<div :class="questionImageContainerClass" v-if="isQuestionImagePresent" v-bind="isQuizAssessment && !hasQuizEnded ? { inert: true } : {}">
<img
:src="imageData.url"
class="object-contain h-full w-full"
Expand Down Expand Up @@ -97,6 +97,7 @@
v-html="option.text"
class="ml-2 h-full place-self-center text-base sm:text-lg"
:data-test="`option-${optionIndex}`"
v-bind="isQuizAssessment && !hasQuizEnded ? { inert: true } : {}"
></div>
</label>
</div>
Expand Down
10 changes: 5 additions & 5 deletions src/components/Questions/Header.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
<template>
<div>
<div class="fixed top-0 left-0 w-full ">
<div class="flex w-full justify-between bg-gray-200 p-4">
<div class="flex w-full justify-between bg-gray-200 p-4 z-20">
<!-- hamburger for question palette -->
<icon-button
:class="{invisible: isOmrMode}"
:iconConfig="togglePaletteButtonIconConfig"
:buttonClass="togglePaletteButtonClass"
:isDisabled="isSessionAnswerRequestProcessing"
Expand Down Expand Up @@ -45,10 +44,10 @@
class="bg-white-400 w-full justify between">
<div class="py-4 h-12 bg-white px-4">
<div class="float-left text-lg sm:text-xl text-base truncate" data-test="test-name">
{{ $props.title }}
{{ $props.title || "no data" }}
</div>
<div class="float-right text-lg sm:text-xl text-base mx-1 px-1" data-test="user-id">
Id: {{ $props.userId }}
Id: {{ $props.userId || "no data" }}
</div>
</div>
</div>
Expand Down Expand Up @@ -153,7 +152,8 @@ export default defineComponent({
window.location.href = url.toString();
}
const shouldShowOmrToggle = computed(() => props.quizType == "assessment")
// const shouldShowOmrToggle = computed(() => props.quizType == "assessment")
const shouldShowOmrToggle = computed(() => false)
const toggleButtonTextConfig = computed(() => {
const config = {
Expand Down
Loading

0 comments on commit 3e2dee8

Please sign in to comment.