@pocketprep/ui-kit 3.4.89 → 3.5.0
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/@pocketprep/ui-kit.js +14834 -16036
- package/dist/@pocketprep/ui-kit.js.map +1 -1
- package/dist/@pocketprep/ui-kit.umd.cjs +12 -12
- package/dist/@pocketprep/ui-kit.umd.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/lib/components/Bundles/BundleSearch.vue +41 -11
- package/lib/components/Pagination/QuestionReviewPagination.vue +21 -19
- package/lib/components/Quiz/Question/ChoicesContainer.vue +95 -129
- package/lib/components/Quiz/Question/DropdownExplanation.vue +39 -53
- package/lib/components/Quiz/Question/Explanation.vue +47 -57
- package/lib/components/Quiz/Question/MatrixChoicesContainer.vue +211 -224
- package/lib/components/Quiz/Question/MatrixRadioGroup.vue +5 -4
- package/lib/components/Quiz/Question/MobileMatrixChoicesContainer.vue +321 -319
- package/lib/components/Quiz/Question/MobileMatrixRadioGroup.vue +7 -6
- package/lib/components/Quiz/Question/PassageAndImage.vue +32 -43
- package/lib/components/Quiz/Question/PassageAndImageDropdown.vue +32 -43
- package/lib/components/Quiz/Question/Paywall.vue +28 -39
- package/lib/components/Quiz/Question/QuestionContext.vue +23 -31
- package/lib/components/Quiz/Question/StatsSummary.vue +10 -20
- package/lib/components/Quiz/Question/Summary.vue +54 -64
- package/lib/components/Quiz/Question/composables.ts +71 -0
- package/lib/components/Quiz/Question/injectionSymbols.ts +69 -0
- package/lib/components/Quiz/Question.vue +788 -988
- package/lib/components/Quiz/QuizContainer.vue +36 -34
- package/lib/components/Quiz/question.d.ts +4 -4
- package/lib/directives.ts +27 -22
- package/lib/styles/_breakpoints.scss +6 -12
- package/package.json +4 -4
|
@@ -13,14 +13,14 @@
|
|
|
13
13
|
|
|
14
14
|
}"
|
|
15
15
|
v-dark="isDarkMode"
|
|
16
|
-
v-breakpoint
|
|
16
|
+
v-breakpoint="breakpointsWithEl"
|
|
17
17
|
>
|
|
18
18
|
<div
|
|
19
19
|
class="uikit-question-mobile-matrix-choices-container__row-container"
|
|
20
20
|
v-for="(rowLabel, rowIndex) in matrixRowLabels"
|
|
21
21
|
:key="rowIndex"
|
|
22
22
|
v-dark="isDarkMode"
|
|
23
|
-
v-breakpoint
|
|
23
|
+
v-breakpoint="breakpointsWithEl"
|
|
24
24
|
>
|
|
25
25
|
<div
|
|
26
26
|
class="uikit-question-mobile-matrix-choices-container__row"
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
expandedRowNumbers.includes(rowIndex),
|
|
30
30
|
}"
|
|
31
31
|
v-dark="isDarkMode"
|
|
32
|
-
v-breakpoint
|
|
32
|
+
v-breakpoint="breakpointsWithEl"
|
|
33
33
|
@click.stop="toggleChoiceDropdown(rowIndex)"
|
|
34
34
|
>
|
|
35
35
|
<Icon
|
|
@@ -71,20 +71,13 @@
|
|
|
71
71
|
v-for="(colHeader, colHeaderIndex) in selectedColumnHeaders"
|
|
72
72
|
:key="colHeaderIndex"
|
|
73
73
|
>
|
|
74
|
-
<template v-if="
|
|
75
|
-
selectedColumnHeaders &&
|
|
76
|
-
selectedColumnHeaders[rowIndex] &&
|
|
77
|
-
selectedColumnHeaders[rowIndex][colHeaderIndex]">
|
|
74
|
+
<template v-if="doesSelectedColumnHeaderExist(rowIndex, colHeaderIndex)">
|
|
78
75
|
<div
|
|
79
76
|
class="uikit-question-mobile-matrix-choices-container__selected-choice-labels"
|
|
80
77
|
v-dark="isDarkMode"
|
|
81
|
-
v-breakpoint
|
|
78
|
+
v-breakpoint="breakpointsWithEl"
|
|
82
79
|
>
|
|
83
|
-
{{
|
|
84
|
-
selectedColumnHeaders[rowIndex][selectedColumnHeaders[rowIndex].length - 1] ?
|
|
85
|
-
stripHtmlTags(selectedColumnHeaders[rowIndex][colHeaderIndex]) :
|
|
86
|
-
`${stripHtmlTags(selectedColumnHeaders[rowIndex][colHeaderIndex])},`
|
|
87
|
-
}}
|
|
80
|
+
{{ getSelectedChoiceLabels(rowIndex, colHeaderIndex) }}
|
|
88
81
|
</div>
|
|
89
82
|
</template>
|
|
90
83
|
</div>
|
|
@@ -117,7 +110,7 @@
|
|
|
117
110
|
/>
|
|
118
111
|
<Checkbox
|
|
119
112
|
v-else
|
|
120
|
-
:model-value="matrixCheckboxGrid[rowIndex][columnIndex]"
|
|
113
|
+
:model-value="matrixCheckboxGrid[rowIndex]?.[columnIndex]"
|
|
121
114
|
:is-dark-mode="isDarkMode"
|
|
122
115
|
:disabled="showMatrixAnswers || reviewMode"
|
|
123
116
|
:checkbox-styles="checkboxContainerStyling(rowIndex, columnIndex)"
|
|
@@ -128,8 +121,8 @@
|
|
|
128
121
|
:class="{
|
|
129
122
|
'uikit-question-mobile-matrix-choices-container__checkbox-label--distractor':
|
|
130
123
|
(showMatrixAnswers || reviewMode) &&
|
|
131
|
-
matrixChoiceLayout[rowIndex] &&
|
|
132
|
-
matrixChoiceLayout[rowIndex][columnIndex]?.startsWith('d'),
|
|
124
|
+
matrixChoiceLayout?.[rowIndex] &&
|
|
125
|
+
matrixChoiceLayout?.[rowIndex]?.[columnIndex]?.startsWith('d'),
|
|
133
126
|
}"
|
|
134
127
|
>
|
|
135
128
|
{{ stripHtmlTags(column) }}
|
|
@@ -151,7 +144,6 @@
|
|
|
151
144
|
:matrix-answer-keys="matrixAnswerKeys"
|
|
152
145
|
:is-dark-mode="isDarkMode"
|
|
153
146
|
:question-el="questionEl"
|
|
154
|
-
:breakpoints="breakpoints"
|
|
155
147
|
:disabled="false"
|
|
156
148
|
@update:modelValue="updateRadioRowSelection(rowIndex, $event)"
|
|
157
149
|
/>
|
|
@@ -161,389 +153,399 @@
|
|
|
161
153
|
</div>
|
|
162
154
|
</template>
|
|
163
155
|
|
|
164
|
-
<script lang="ts">
|
|
165
|
-
import { Component, Vue, Prop, Emit, Watch } from 'vue-facing-decorator'
|
|
156
|
+
<script setup lang="ts">
|
|
166
157
|
import Icon from '../../Icons/Icon.vue'
|
|
167
|
-
import PocketButton from '../../Buttons/Button.vue'
|
|
168
158
|
import Checkbox from '../../Forms/Checkbox.vue'
|
|
169
159
|
import MobileMatrixRadioGroup from './MobileMatrixRadioGroup.vue'
|
|
170
|
-
import { dark, breakpoint } from '../../../directives'
|
|
171
|
-
import
|
|
172
|
-
import type {
|
|
160
|
+
import { dark as vDark, breakpoint as vBreakpoint } from '../../../directives'
|
|
161
|
+
import { useQuestionContext } from './composables'
|
|
162
|
+
import type { IRadioOptions, TMatrixChoiceKey } from './../question'
|
|
173
163
|
import BrandColors from '../../../pocketprep-export.module.scss'
|
|
164
|
+
import { computed, onMounted, ref, watch } from 'vue'
|
|
165
|
+
|
|
166
|
+
const emit = defineEmits<{
|
|
167
|
+
'emitSelectedMatrixChoice': [matrixChoiceKeys: TMatrixChoiceKey[]]
|
|
168
|
+
}>()
|
|
169
|
+
|
|
170
|
+
const {
|
|
171
|
+
// questionEl is used by the breakpoint directive
|
|
172
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
173
|
+
questionEl,
|
|
174
|
+
question,
|
|
175
|
+
isMatrixQuestionCorrect,
|
|
176
|
+
reviewMode,
|
|
177
|
+
isDarkMode,
|
|
178
|
+
breakpointsWithEl,
|
|
179
|
+
showMatrixAnswers,
|
|
180
|
+
matrixAnswerKeys,
|
|
181
|
+
selectedMatrixChoices,
|
|
182
|
+
} = useQuestionContext()
|
|
183
|
+
|
|
184
|
+
const matrixCheckboxGrid = ref<boolean[][] | undefined>(undefined)
|
|
185
|
+
const matrixRadioGrid = ref<IRadioOptions[] | undefined>(undefined)
|
|
186
|
+
const expandedRowNumbers = ref<number[]>([])
|
|
187
|
+
const selectedColumnHeaders = ref<string[][]>([])
|
|
188
|
+
const brandColors = BrandColors
|
|
189
|
+
|
|
190
|
+
const stripHtmlTags = (string?: string) => {
|
|
191
|
+
if (string) {
|
|
192
|
+
const div = document.createElement('div')
|
|
193
|
+
div.innerHTML = string
|
|
194
|
+
return div.textContent || ''
|
|
195
|
+
}
|
|
196
|
+
return ''
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const matrixChoiceLayout = computed(() => {
|
|
200
|
+
return question.value.matrixChoiceLayout
|
|
201
|
+
})
|
|
174
202
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
MobileMatrixRadioGroup,
|
|
181
|
-
},
|
|
182
|
-
directives: {
|
|
183
|
-
dark,
|
|
184
|
-
breakpoint,
|
|
185
|
-
},
|
|
203
|
+
const defaultCheckboxGrid = computed(() => {
|
|
204
|
+
return matrixChoiceLayout.value?.map(row => {
|
|
205
|
+
const choiceRow = row.map(() => false)
|
|
206
|
+
return choiceRow
|
|
207
|
+
})
|
|
186
208
|
})
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
'tablet-portrait': 1023,
|
|
194
|
-
'tablet-landscape': 1439,
|
|
195
|
-
} }) breakpoints!: TBreakPointsObject
|
|
196
|
-
@Prop() question!: Study.Class.QuestionJSON
|
|
197
|
-
@Prop() matrixChoiceLayout!: string[][]
|
|
198
|
-
@Prop({ default: false }) showMatrixAnswers!: boolean
|
|
199
|
-
@Prop({ default: false }) isUnanswered!: boolean
|
|
200
|
-
@Prop({ default: false }) isMatrixQuestionCorrect!: boolean
|
|
201
|
-
@Prop() matrixAnswerKeys!: TMatrixChoiceKey[]
|
|
202
|
-
@Prop() matrixDistractorKeys!: TMatrixChoiceKey[]
|
|
203
|
-
@Prop() selectedMatrixChoices!: TMatrixChoiceKey[]
|
|
204
|
-
@Prop() matrixChoices!: TMatrixChoiceKey[]
|
|
205
|
-
|
|
206
|
-
matrixCheckboxGrid: boolean[][] | undefined = undefined
|
|
207
|
-
matrixRadioGrid: IRadioOptions[] | undefined = undefined
|
|
208
|
-
expandedRowNumbers: number[] = []
|
|
209
|
-
selectedColumnHeaders: string[][] = []
|
|
210
|
-
brandColors = BrandColors
|
|
211
|
-
|
|
212
|
-
stripHtmlTags (string?: string) {
|
|
213
|
-
if (string) {
|
|
214
|
-
const div = document.createElement('div')
|
|
215
|
-
div.innerHTML = string
|
|
216
|
-
return div.textContent || ''
|
|
209
|
+
|
|
210
|
+
const defaultRadioButtonGrid = computed(() => {
|
|
211
|
+
return matrixChoiceLayout.value?.map(row => {
|
|
212
|
+
return {
|
|
213
|
+
choices: row as TMatrixChoiceKey[],
|
|
214
|
+
value: null as TMatrixChoiceKey | null,
|
|
217
215
|
}
|
|
218
|
-
|
|
219
|
-
|
|
216
|
+
})
|
|
217
|
+
})
|
|
220
218
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
return choiceRow
|
|
225
|
-
})
|
|
226
|
-
}
|
|
219
|
+
const matrixRowLabels = computed(() => {
|
|
220
|
+
return question.value.matrixLabels?.rows
|
|
221
|
+
})
|
|
227
222
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
choices: row as TMatrixChoiceKey[],
|
|
232
|
-
value: null as TMatrixChoiceKey | null,
|
|
233
|
-
}
|
|
234
|
-
})
|
|
235
|
-
}
|
|
223
|
+
const matrixColumnLabels = computed(() => {
|
|
224
|
+
return question.value.matrixLabels?.columns
|
|
225
|
+
})
|
|
236
226
|
|
|
237
|
-
|
|
238
|
-
|
|
227
|
+
onMounted(() => {
|
|
228
|
+
if (question.value.type === 'Matrix Checkbox') {
|
|
229
|
+
matrixCheckboxGrid.value = convertSelectedMatrixChoiceToCheckboxGrid()
|
|
239
230
|
}
|
|
240
231
|
|
|
241
|
-
|
|
242
|
-
|
|
232
|
+
if (question.value.type === 'Matrix Radio Button') {
|
|
233
|
+
matrixRadioGrid.value = convertSelectedMatrixChoiceToRadioBtnGrid()
|
|
243
234
|
}
|
|
244
235
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
236
|
+
question.value.matrixChoiceLayout?.forEach(() => {
|
|
237
|
+
selectedColumnHeaders.value.push([])
|
|
238
|
+
})
|
|
239
|
+
})
|
|
249
240
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
241
|
+
const toggleChoiceDropdown = (rowIndex: number) => {
|
|
242
|
+
const includedRowNumberIndex = expandedRowNumbers.value.findIndex(row => row === rowIndex)
|
|
243
|
+
if (includedRowNumberIndex === -1) {
|
|
244
|
+
expandedRowNumbers.value.push(rowIndex)
|
|
245
|
+
} else {
|
|
246
|
+
expandedRowNumbers.value.splice(includedRowNumberIndex, 1)
|
|
247
|
+
}
|
|
248
|
+
}
|
|
253
249
|
|
|
254
|
-
|
|
255
|
-
|
|
250
|
+
const selectedChoiceKey = (rowIndex: number, columnIndex: number) => {
|
|
251
|
+
const row = rowIndex += 1
|
|
252
|
+
const column = columnIndex += 1
|
|
253
|
+
if (selectedMatrixChoices.value.length && matrixAnswerKeys.value.length) {
|
|
254
|
+
const matrixSelectedChoiceKey = selectedMatrixChoices.value.find((choice) => {
|
|
255
|
+
const substring = choice.substring(1)
|
|
256
|
+
return substring === `${row}_${column}`
|
|
256
257
|
})
|
|
257
|
-
}
|
|
258
258
|
|
|
259
|
-
|
|
260
|
-
const includedRowNumberIndex = this.expandedRowNumbers.findIndex(row => row === rowIndex)
|
|
261
|
-
if (includedRowNumberIndex === -1) {
|
|
262
|
-
this.expandedRowNumbers.push(rowIndex)
|
|
263
|
-
} else {
|
|
264
|
-
this.expandedRowNumbers.splice(includedRowNumberIndex, 1)
|
|
265
|
-
}
|
|
259
|
+
return matrixSelectedChoiceKey
|
|
266
260
|
}
|
|
261
|
+
return undefined
|
|
262
|
+
}
|
|
267
263
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (this.selectedMatrixChoices.length && this.matrixAnswerKeys.length) {
|
|
272
|
-
const matrixSelectedChoiceKey = this.selectedMatrixChoices.find((choice) => {
|
|
273
|
-
const substring = choice.substring(1)
|
|
274
|
-
return substring === `${row}_${column}`
|
|
275
|
-
})
|
|
276
|
-
|
|
277
|
-
return matrixSelectedChoiceKey
|
|
278
|
-
}
|
|
279
|
-
return undefined
|
|
280
|
-
}
|
|
264
|
+
const getRadioRowSelection = (rowIndex: number) => {
|
|
265
|
+
return matrixRadioGrid.value?.[rowIndex]?.value
|
|
266
|
+
}
|
|
281
267
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
268
|
+
const getRadioRowChoices = (rowIndex: number) => {
|
|
269
|
+
const choices = matrixRadioGrid.value?.[rowIndex]?.choices
|
|
270
|
+
return choices
|
|
271
|
+
}
|
|
285
272
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
273
|
+
const updateRadioRowSelection = (rowIndex: number, choiceKey: TMatrixChoiceKey | null) => {
|
|
274
|
+
const row = matrixRadioGrid.value?.[rowIndex]
|
|
275
|
+
if (row) {
|
|
276
|
+
row.value = choiceKey
|
|
290
277
|
|
|
291
|
-
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
const choiceKeyIndex = row.choices.findIndex(choice => choice === choiceKey)
|
|
298
|
-
const rowHeader = this.question.matrixLabels?.columns[choiceKeyIndex]
|
|
299
|
-
if (rowHeader) {
|
|
300
|
-
this.selectedColumnHeaders[rowIndex]?.pop()
|
|
301
|
-
this.selectedColumnHeaders[rowIndex]?.push(rowHeader)
|
|
302
|
-
}
|
|
278
|
+
// update row header label
|
|
279
|
+
const choiceKeyIndex = row.choices.findIndex(choice => choice === choiceKey)
|
|
280
|
+
const rowHeader = question.value.matrixLabels?.columns[choiceKeyIndex]
|
|
281
|
+
if (rowHeader) {
|
|
282
|
+
selectedColumnHeaders.value[rowIndex]?.pop()
|
|
283
|
+
selectedColumnHeaders.value[rowIndex]?.push(rowHeader)
|
|
303
284
|
}
|
|
304
285
|
}
|
|
286
|
+
}
|
|
305
287
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
288
|
+
const correctlySelectedChoice = (rowIndex: number, columnIndex: number) => {
|
|
289
|
+
if (selectedMatrixChoices.value && matrixAnswerKeys.value) {
|
|
290
|
+
const selectedChoice = selectedChoiceKey(rowIndex, columnIndex)
|
|
291
|
+
if (selectedChoice && selectedChoice.startsWith('a') && matrixAnswerKeys.value.includes(selectedChoice)) {
|
|
292
|
+
return true
|
|
312
293
|
}
|
|
313
|
-
return false
|
|
314
294
|
}
|
|
295
|
+
return false
|
|
296
|
+
}
|
|
315
297
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
298
|
+
const incorrectlySelectedChoice = (rowIndex: number, columnIndex: number) => {
|
|
299
|
+
if (selectedMatrixChoices.value && matrixAnswerKeys.value) {
|
|
300
|
+
const selectedChoice = selectedChoiceKey(rowIndex, columnIndex)
|
|
301
|
+
if (selectedChoice && selectedChoice.startsWith('d')) {
|
|
302
|
+
return true
|
|
322
303
|
}
|
|
323
|
-
return false
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
correctAnswerButNotSelected (rowIndex: number, columnIndex: number) {
|
|
327
|
-
const selectedChoice = this.selectedChoiceKey(rowIndex, columnIndex)
|
|
328
|
-
const answerKey = this.matrixAnswerKeys.find(choice => choice === `a${rowIndex + 1}_${columnIndex + 1}`)
|
|
329
|
-
return answerKey && !selectedChoice
|
|
330
304
|
}
|
|
305
|
+
return false
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const correctAnswerButNotSelected = (rowIndex: number, columnIndex: number) => {
|
|
309
|
+
const selectedChoice = selectedChoiceKey(rowIndex, columnIndex)
|
|
310
|
+
const answerKey = matrixAnswerKeys.value.find(choice => choice === `a${rowIndex + 1}_${columnIndex + 1}`)
|
|
311
|
+
return answerKey && !selectedChoice
|
|
312
|
+
}
|
|
331
313
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const incorrectlySelectedChoice = this.incorrectlySelectedChoice(rowIndex, columnIndex)
|
|
314
|
+
const checkboxContainerStyling = (rowIndex: number, columnIndex: number) => {
|
|
315
|
+
const isReviewMode = showMatrixAnswers.value || reviewMode
|
|
335
316
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
}
|
|
317
|
+
// check box is correctlySelected
|
|
318
|
+
if (isReviewMode && correctlySelectedChoice(rowIndex, columnIndex)) {
|
|
319
|
+
const borderColor = isDarkMode ? brandColors.jungleGreen : brandColors.cadaverous
|
|
320
|
+
return {
|
|
321
|
+
borderColor: `${borderColor} !important`,
|
|
322
|
+
background: `${borderColor} !important`,
|
|
343
323
|
}
|
|
324
|
+
}
|
|
344
325
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
}
|
|
326
|
+
if (isReviewMode && incorrectlySelectedChoice(rowIndex, columnIndex)) {
|
|
327
|
+
return {
|
|
328
|
+
background: `${brandColors.steel} !important`,
|
|
329
|
+
border: `1px solid ${brandColors.steel} !important`,
|
|
350
330
|
}
|
|
331
|
+
}
|
|
351
332
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
333
|
+
if (isReviewMode && correctAnswerButNotSelected(rowIndex, columnIndex)) {
|
|
334
|
+
return {
|
|
335
|
+
background: 'transparent !important',
|
|
336
|
+
border: `1px solid ${brandColors.slate} !important`,
|
|
357
337
|
}
|
|
358
338
|
}
|
|
339
|
+
}
|
|
359
340
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
}
|
|
341
|
+
const checkboxCheckStyling = (rowIndex: number, columnIndex: number) => {
|
|
342
|
+
const isReviewMode = showMatrixAnswers.value || reviewMode
|
|
343
|
+
if (isReviewMode && correctAnswerButNotSelected(rowIndex, columnIndex)) {
|
|
344
|
+
const color = isDarkMode ? brandColors.jungleGreen : brandColors.cadaverous
|
|
345
|
+
return {
|
|
346
|
+
color: `${color} !important`,
|
|
367
347
|
}
|
|
368
348
|
}
|
|
349
|
+
}
|
|
369
350
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
}
|
|
400
|
-
return false
|
|
351
|
+
const correctRow = (rowIndex: number) => {
|
|
352
|
+
if (matrixChoiceLayout.value && matrixChoiceLayout.value[rowIndex]) {
|
|
353
|
+
if (
|
|
354
|
+
question?.value.type === 'Matrix Checkbox' &&
|
|
355
|
+
matrixCheckboxGrid.value &&
|
|
356
|
+
matrixCheckboxGrid.value[rowIndex]
|
|
357
|
+
) {
|
|
358
|
+
const correctAnswerKeys = matrixChoiceLayout.value[rowIndex]?.filter(choice =>
|
|
359
|
+
choice.startsWith('a')
|
|
360
|
+
)
|
|
361
|
+
const selectedAnswerKeys = matrixCheckboxGrid.value[rowIndex]?.map((choice, choiceIndex) => {
|
|
362
|
+
return selectedChoiceKey(rowIndex, choiceIndex)
|
|
363
|
+
})
|
|
364
|
+
const correctSelectedKeys = matrixCheckboxGrid.value[rowIndex]?.filter((choice, choiceIndex) => {
|
|
365
|
+
const selectedChoice = selectedChoiceKey(rowIndex, choiceIndex)
|
|
366
|
+
return selectedChoice?.startsWith('a')
|
|
367
|
+
})
|
|
368
|
+
return !selectedAnswerKeys?.some(choice => choice?.startsWith('d')) &&
|
|
369
|
+
(correctAnswerKeys?.length === correctSelectedKeys?.length)
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (
|
|
373
|
+
question?.value.type === 'Matrix Radio Button' &&
|
|
374
|
+
matrixRadioGrid.value &&
|
|
375
|
+
matrixRadioGrid.value[rowIndex]
|
|
376
|
+
) {
|
|
377
|
+
const rowVal = matrixRadioGrid.value[rowIndex]?.value
|
|
378
|
+
if (rowVal) {
|
|
379
|
+
return rowVal.startsWith('a')
|
|
401
380
|
}
|
|
381
|
+
return false
|
|
402
382
|
}
|
|
403
|
-
return false
|
|
404
383
|
}
|
|
384
|
+
return false
|
|
385
|
+
}
|
|
405
386
|
|
|
406
|
-
|
|
407
|
-
|
|
387
|
+
const convertSelectedMatrixChoiceToCheckboxGrid = () => {
|
|
388
|
+
const checkboxGrid = defaultCheckboxGrid.value
|
|
408
389
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
390
|
+
// Reset selectedColumnHeaders string[][] in case in headers are still in the arrays
|
|
391
|
+
// Let selectedMatrixChoices set those columns
|
|
392
|
+
const columnMatrixLabels = question.value.matrixLabels?.rows
|
|
393
|
+
const defaultSelectedColumnLabels: string[][] = []
|
|
394
|
+
if (columnMatrixLabels) {
|
|
395
|
+
columnMatrixLabels.forEach(() => {
|
|
396
|
+
defaultSelectedColumnLabels.push([])
|
|
397
|
+
})
|
|
417
398
|
|
|
418
|
-
|
|
419
|
-
|
|
399
|
+
selectedColumnHeaders.value = defaultSelectedColumnLabels
|
|
400
|
+
}
|
|
420
401
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
402
|
+
selectedMatrixChoices.value.forEach(choice => {
|
|
403
|
+
const rowIndex = Number(choice.substring(1, choice.indexOf('_'))) - 1
|
|
404
|
+
const columnIndex = Number(choice.split('_').pop()) - 1
|
|
405
|
+
const row = checkboxGrid && checkboxGrid[rowIndex]
|
|
406
|
+
if (row) {
|
|
407
|
+
row[columnIndex] = true
|
|
408
|
+
if (selectedColumnHeaders.value[rowIndex] && question.value.matrixLabels?.columns[columnIndex]) {
|
|
409
|
+
const columnHeader = question.value.matrixLabels?.columns[columnIndex]
|
|
410
|
+
if (columnHeader) {
|
|
411
|
+
selectedColumnHeaders.value[rowIndex]?.push(columnHeader)
|
|
429
412
|
}
|
|
430
413
|
}
|
|
431
|
-
})
|
|
432
|
-
return checkboxGrid
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
convertSelectedMatrixChoiceToRadioBtnGrid () {
|
|
436
|
-
const radioBtnGrid = this.defaultRadioButtonGrid
|
|
437
|
-
|
|
438
|
-
const columnMatrixLabels = this.question.matrixLabels?.rows
|
|
439
|
-
const defaultSelectedColumnLabels: string[][] = []
|
|
440
|
-
if (columnMatrixLabels) {
|
|
441
|
-
columnMatrixLabels.forEach(() => {
|
|
442
|
-
defaultSelectedColumnLabels.push([])
|
|
443
|
-
})
|
|
444
|
-
|
|
445
|
-
this.selectedColumnHeaders = defaultSelectedColumnLabels
|
|
446
414
|
}
|
|
415
|
+
})
|
|
416
|
+
return checkboxGrid
|
|
417
|
+
}
|
|
447
418
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
this.selectedColumnHeaders[rowIndex].push(columnHeader)
|
|
457
|
-
}
|
|
458
|
-
if (radioBtnGrid && radioBtnGrid[rowIndex]) {
|
|
459
|
-
radioBtnGrid[rowIndex].value = choice
|
|
460
|
-
}
|
|
419
|
+
const convertSelectedMatrixChoiceToRadioBtnGrid = () => {
|
|
420
|
+
const radioBtnGrid = defaultRadioButtonGrid.value
|
|
421
|
+
|
|
422
|
+
const columnMatrixLabels = question.value.matrixLabels?.rows
|
|
423
|
+
const defaultSelectedColumnLabels: string[][] = []
|
|
424
|
+
if (columnMatrixLabels) {
|
|
425
|
+
columnMatrixLabels.forEach(() => {
|
|
426
|
+
defaultSelectedColumnLabels.push([])
|
|
461
427
|
})
|
|
462
|
-
|
|
428
|
+
|
|
429
|
+
selectedColumnHeaders.value = defaultSelectedColumnLabels
|
|
463
430
|
}
|
|
464
431
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
432
|
+
selectedMatrixChoices.value.forEach(choice => {
|
|
433
|
+
const rowIndex = Number(choice.substring(1, choice.indexOf('_'))) - 1
|
|
434
|
+
const columnIndex = Number(choice.split('_').pop()) - 1
|
|
435
|
+
if (selectedColumnHeaders.value[rowIndex] && question.value.matrixLabels?.columns[columnIndex]) {
|
|
436
|
+
const columnHeader = question.value.matrixLabels?.columns[columnIndex]
|
|
437
|
+
// In case a column header is still in selectedColumnHeaders, remove it first and let
|
|
438
|
+
// selectedMatrixChoices add selected column header based on selected choices
|
|
439
|
+
if (columnHeader) {
|
|
440
|
+
selectedColumnHeaders.value[rowIndex]?.pop()
|
|
441
|
+
selectedColumnHeaders.value[rowIndex]?.push(columnHeader)
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
const radioBtnGridRow = radioBtnGrid && radioBtnGrid[rowIndex]
|
|
445
|
+
if (radioBtnGridRow) {
|
|
446
|
+
radioBtnGridRow.value = choice
|
|
447
|
+
}
|
|
448
|
+
})
|
|
449
|
+
return radioBtnGrid
|
|
450
|
+
}
|
|
469
451
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
452
|
+
const checkboxRowClicked = (rowIndex: number, columnIndex: number) => {
|
|
453
|
+
const matrixCheckboxGridRow = matrixCheckboxGrid.value && matrixCheckboxGrid.value[rowIndex]
|
|
454
|
+
if (matrixCheckboxGridRow) {
|
|
455
|
+
matrixCheckboxGridRow[columnIndex] = !matrixCheckboxGridRow[columnIndex]
|
|
456
|
+
const columnHeader = question.value.matrixLabels?.columns[columnIndex]
|
|
457
|
+
|
|
458
|
+
if (selectedColumnHeaders.value && selectedColumnHeaders.value[rowIndex] && columnHeader) {
|
|
459
|
+
if (selectedColumnHeaders.value[rowIndex]?.includes(columnHeader)) {
|
|
460
|
+
const columnHeaderIndex = selectedColumnHeaders.value[rowIndex]?.indexOf(columnHeader)
|
|
461
|
+
if (columnHeaderIndex !== undefined && columnHeaderIndex !== -1) {
|
|
462
|
+
selectedColumnHeaders.value[rowIndex]?.splice(columnHeaderIndex, 1)
|
|
478
463
|
}
|
|
464
|
+
} else {
|
|
465
|
+
selectedColumnHeaders.value[rowIndex]?.push(columnHeader)
|
|
479
466
|
}
|
|
480
467
|
}
|
|
481
468
|
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
const doesSelectedColumnHeaderExist = (rowIndex: number, columnIndex: number) => {
|
|
472
|
+
return selectedColumnHeaders.value?.[rowIndex]?.[columnIndex] || false
|
|
473
|
+
}
|
|
482
474
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
475
|
+
const getSelectedChoiceLabels = (rowIndex: number, columnIndex: number) => {
|
|
476
|
+
const columnHeadersInRow = selectedColumnHeaders.value?.[rowIndex]
|
|
477
|
+
if (!columnHeadersInRow) {
|
|
478
|
+
return
|
|
479
|
+
}
|
|
480
|
+
const selectedColumnHeader = columnHeadersInRow[columnIndex]
|
|
481
|
+
const lastColumnHeader = columnHeadersInRow[columnHeadersInRow.length - 1]
|
|
482
|
+
if (!selectedColumnHeader) {
|
|
483
|
+
return ''
|
|
486
484
|
}
|
|
487
485
|
|
|
486
|
+
return selectedColumnHeader === lastColumnHeader
|
|
487
|
+
? stripHtmlTags(selectedColumnHeader)
|
|
488
|
+
: `${stripHtmlTags(selectedColumnHeader)},`
|
|
489
|
+
}
|
|
488
490
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
const selectedCheckboxChoices: TMatrixChoiceKey[] = []
|
|
491
|
+
const emitSelectedMatrixChoice = (matrixChoiceKeys: TMatrixChoiceKey[]) => {
|
|
492
|
+
emit('emitSelectedMatrixChoice', matrixChoiceKeys)
|
|
493
|
+
}
|
|
493
494
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
495
|
+
watch(matrixCheckboxGrid, () => {
|
|
496
|
+
if (matrixChoiceLayout.value && matrixCheckboxGrid.value && (!reviewMode || !showMatrixAnswers.value)) {
|
|
497
|
+
const selectedCheckboxChoices: TMatrixChoiceKey[] = []
|
|
498
|
+
|
|
499
|
+
matrixCheckboxGrid.value.forEach((row, rowIndex) => {
|
|
500
|
+
row.forEach((choice, choiceIndex) => {
|
|
501
|
+
if (
|
|
502
|
+
choice &&
|
|
503
|
+
matrixChoiceLayout.value?.[rowIndex] &&
|
|
504
|
+
matrixChoiceLayout.value?.[rowIndex]?.[choiceIndex]
|
|
505
|
+
) {
|
|
506
|
+
const choiceKey = matrixChoiceLayout.value?.[rowIndex]?.[choiceIndex] as TMatrixChoiceKey
|
|
507
|
+
if (choiceKey) {
|
|
502
508
|
selectedCheckboxChoices.push(choiceKey)
|
|
503
509
|
}
|
|
504
|
-
}
|
|
510
|
+
}
|
|
505
511
|
})
|
|
512
|
+
})
|
|
506
513
|
|
|
507
|
-
|
|
508
|
-
}
|
|
514
|
+
emitSelectedMatrixChoice(selectedCheckboxChoices)
|
|
509
515
|
}
|
|
516
|
+
}, { deep: true })
|
|
510
517
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
const selectedRadioButtonChoices: TMatrixChoiceKey[] = []
|
|
518
|
+
watch(matrixRadioGrid, () => {
|
|
519
|
+
if (matrixChoiceLayout.value && matrixRadioGrid.value && (!reviewMode || !showMatrixAnswers.value)) {
|
|
520
|
+
const selectedRadioButtonChoices: TMatrixChoiceKey[] = []
|
|
515
521
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
522
|
+
matrixRadioGrid.value.forEach((row) => {
|
|
523
|
+
if (row.value) {
|
|
524
|
+
selectedRadioButtonChoices.push(row.value)
|
|
525
|
+
}
|
|
526
|
+
})
|
|
521
527
|
|
|
522
|
-
|
|
523
|
-
}
|
|
528
|
+
emitSelectedMatrixChoice(selectedRadioButtonChoices)
|
|
524
529
|
}
|
|
530
|
+
}, { deep: true })
|
|
525
531
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
this.expandedRowNumbers = []
|
|
530
|
-
}
|
|
532
|
+
watch(showMatrixAnswers, () => {
|
|
533
|
+
if (showMatrixAnswers) {
|
|
534
|
+
expandedRowNumbers.value = []
|
|
531
535
|
}
|
|
536
|
+
})
|
|
532
537
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
this.matrixCheckboxGrid = selectedCheckboxGrid ? selectedCheckboxGrid : this.defaultCheckboxGrid
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
if ((this.reviewMode || this.showMatrixAnswers) && this.question.type === 'Matrix Radio Button') {
|
|
541
|
-
const selectedRadioBtnGrid = this.convertSelectedMatrixChoiceToRadioBtnGrid()
|
|
542
|
-
this.matrixRadioGrid = selectedRadioBtnGrid
|
|
543
|
-
}
|
|
538
|
+
watch(selectedMatrixChoices, () => {
|
|
539
|
+
if ((reviewMode || showMatrixAnswers.value) && question.value.type === 'Matrix Checkbox') {
|
|
540
|
+
const selectedCheckboxGrid = convertSelectedMatrixChoiceToCheckboxGrid()
|
|
541
|
+
matrixCheckboxGrid.value = selectedCheckboxGrid ? selectedCheckboxGrid : defaultCheckboxGrid.value
|
|
544
542
|
}
|
|
545
|
-
}
|
|
546
543
|
|
|
544
|
+
if ((reviewMode || showMatrixAnswers.value) && question.value.type === 'Matrix Radio Button') {
|
|
545
|
+
const selectedRadioBtnGrid = convertSelectedMatrixChoiceToRadioBtnGrid()
|
|
546
|
+
matrixRadioGrid.value = selectedRadioBtnGrid
|
|
547
|
+
}
|
|
548
|
+
})
|
|
547
549
|
</script>
|
|
548
550
|
|
|
549
551
|
<style lang="scss">
|