@windward/games 0.14.0 → 0.16.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ### Release [0.16.0] created - 2025-04-29
4
+
5
+
6
+ ### Release [0.15.0] created - 2025-04-09
7
+
8
+
3
9
  ### Release [0.14.0] created - 2025-03-25
4
10
 
5
11
 
@@ -33,7 +33,15 @@
33
33
  )
34
34
  }}
35
35
  </p>
36
- <p>{{ error }}</p>
36
+ <p>
37
+ {{
38
+ render
39
+ ? $t(
40
+ 'windward.games.components.content.blocks.crossword.error.unable_to_load_student'
41
+ )
42
+ : error
43
+ }}
44
+ </p>
37
45
  </v-alert>
38
46
  <div
39
47
  v-if="!error"
@@ -284,7 +292,6 @@ export default {
284
292
  )
285
293
  }
286
294
  }
287
-
288
295
  // this is true if render is toggled back to true
289
296
  if (generate && this.error === '') {
290
297
  this.generateGrid(this.wordMap)
@@ -443,7 +450,7 @@ export default {
443
450
 
444
451
  if (grid.length > MATRIX_LENGTH) {
445
452
  this.error = this.$t(
446
- 'windward.games.components.content.blocks.crossword.error.could_not_generate'
453
+ 'windward.games.components.content.blocks.crossword.error.unable_to_load_editor'
447
454
  )
448
455
  return false
449
456
  }
@@ -68,6 +68,7 @@
68
68
  outlined
69
69
  tile
70
70
  @click="onChooseAnswer(answer, question)"
71
+ @keyup.enter="onChooseAnswer(answer, question)"
71
72
  >
72
73
  <div class="d-flex justify-space-between">
73
74
  <p class="mb-0">
@@ -79,6 +80,12 @@
79
80
  </p>
80
81
  <div>
81
82
  <v-icon
83
+ v-if="
84
+ handleInformationOutline(
85
+ question,
86
+ answer
87
+ ) !== undefined
88
+ "
82
89
  :class="
83
90
  handleInformationClass(
84
91
  question,
@@ -240,14 +247,12 @@ export default {
240
247
  data() {
241
248
  return {
242
249
  updateKey: 0,
243
- completedItems: [],
244
250
  dialog: false,
245
251
  hint: false,
246
252
  hintText: '',
247
253
  answerDescriptionModal: false,
248
254
  answerDescription: '',
249
255
  studentResponses: [],
250
- mountCourseCounter: false,
251
256
  }
252
257
  },
253
258
  computed: {
@@ -257,8 +262,8 @@ export default {
257
262
  enrollment: 'enrollment/get',
258
263
  }),
259
264
  completedAmount() {
260
- if (this.completedItems) {
261
- return _.flatten(this.completedItems).length
265
+ if (this.studentResponses) {
266
+ return _.flatten(this.studentResponses).length
262
267
  }
263
268
  },
264
269
  totalAmountQuestions() {
@@ -269,7 +274,7 @@ export default {
269
274
  completedPercent() {
270
275
  if (
271
276
  this.block.metadata.config.questions.length > 0 &&
272
- this.completedItems.length > 0
277
+ this.studentResponses.length > 0
273
278
  ) {
274
279
  return (this.completedAmount / this.totalAmountQuestions) * 100
275
280
  }
@@ -284,34 +289,33 @@ export default {
284
289
  this.answerDescription = question.answer_description
285
290
  },
286
291
  onChooseAnswer(answer, question) {
287
- let studRep
288
- this.studentResponses.find((obj) => {
289
- if (obj.id === question.id) {
290
- studRep = obj
291
- }
292
- })
293
- if (_.isEmpty(this.studentResponses) || _.isEmpty(studRep)) {
294
- // lets html side know whish answer was chosen, this is important in determine css
295
- answer.chosen = true
296
- // clones question block into the correct index in the studentResponses araay
292
+ // check to see if student already answered this question
293
+ let studentResponse = this.studentResponses.find(
294
+ (obj) => obj.id === question.id
295
+ )
296
+ // if there is no student response for this question or there no student responses to any of the questions
297
+ if (
298
+ _.isEmpty(this.studentResponses) ||
299
+ _.isEmpty(studentResponse)
300
+ ) {
301
+ // get question and answer index to update the answer directly
302
+ // on block.metadata.config.questions to prevent buggy behavior
303
+ const questionIndex =
304
+ this.block.metadata.config.questions.findIndex(
305
+ (q) => q.id === question.id
306
+ )
307
+ const answerIndex = this.block.metadata.config.questions[
308
+ questionIndex
309
+ ].answer_options.findIndex((a) => a.id === answer.id)
310
+ // lets html side know which answer was chosen, this is important in determine css
311
+ this.block.metadata.config.questions[
312
+ questionIndex
313
+ ].answer_options[answerIndex].chosen = true
314
+ // clones question block to break reference
297
315
  const clonedQuestion = _.cloneDeep(question)
298
316
  clonedQuestion.student_response = answer
299
317
 
300
- if (answer.correctAnswer === true) {
301
- clonedQuestion.isStudentCorrect = true
302
- } else {
303
- clonedQuestion.isStudentCorrect = false
304
- }
305
-
306
318
  this.studentResponses.push(clonedQuestion)
307
- // ensure the object is not already in the completed items array if not push into the array
308
- const questionDone = this.completedItems.find(
309
- (item) => item === question
310
- )
311
-
312
- if (!questionDone) {
313
- this.completedItems.push(question)
314
- }
315
319
 
316
320
  this.updateKey = Crypto.id()
317
321
  }
@@ -365,6 +369,7 @@ export default {
365
369
  }
366
370
  }
367
371
  )
372
+ // check if student already responded
368
373
  if (studentsQuestionResponse) {
369
374
  // requirements for correct and chosen
370
375
  if (
@@ -380,7 +385,12 @@ export default {
380
385
  return 'mdi-check-circle-outline'
381
386
  }
382
387
  // requirements for wrong and chosen
383
- if (answer.correctAnswer !== true && answer.chosen === true) {
388
+ if (
389
+ answer.id ===
390
+ studentsQuestionResponse.student_response.id &&
391
+ answer.correctAnswer !== true &&
392
+ answer.chosen === true
393
+ ) {
384
394
  return 'mdi-close-circle'
385
395
  }
386
396
  }
@@ -464,9 +474,8 @@ export default {
464
474
  // launches dialog modal
465
475
  this.dialog = true
466
476
  this.hint = true
467
- // sets text for modal, cannot just reference question.hint in html because
468
- // the carousel loads all elements regardless of if they are on a different slide or not
469
- // when mountCourseCounter so it always shows the last question if referenced question.hint
477
+ // sets text for modal, cannot just reference question.hint in html because the carousel loads
478
+ // all elements regardless of if they are on a different slide so it always shows the last question
470
479
  this.hintText = question.hint
471
480
  },
472
481
  onFifty(question) {
@@ -207,6 +207,7 @@
207
207
  hide-background
208
208
  hide-decorative
209
209
  hide-modal
210
+ :disabled="render"
210
211
  ></ImageAssetSettings>
211
212
  </v-card-text>
212
213
  </v-card>
@@ -204,6 +204,7 @@
204
204
  ][indexPrompt].fileConfig
205
205
  "
206
206
  :assets.sync="block.assets"
207
+ :disabled="render"
207
208
  hide-background
208
209
  hide-decorative
209
210
  hide-modal
@@ -89,11 +89,11 @@
89
89
  block.metadata.config.slides[index].fileConfig
90
90
  "
91
91
  :assets.sync="block.assets"
92
+ :disabled="render"
92
93
  hide-background
93
94
  hide-decorative
94
95
  hide-modal
95
96
  ></ImageAssetSettings>
96
-
97
97
  </v-container>
98
98
  </template>
99
99
  </SortableExpansionPanel>
@@ -14,6 +14,10 @@ export default {
14
14
  could_not_generate:
15
15
  'Could not generate a {0} by {0} crossword with the supplied words',
16
16
  unknown: 'An unknown error occurred during the crossword creation',
17
+ unable_to_load_editor:
18
+ 'Unable to generate crossword puzzle. Your current word list may have too many words, words that are too short/long, or insufficient shared letters for crossings. You can edit your word list and try again.',
19
+ unable_to_load_student:
20
+ 'Unable to generate crossword puzzle with these words. Please try refreshing the page until it loads successfully or contact support if the issue persists.',
17
21
  },
18
22
 
19
23
  play_again: 'Randomize Crossword and Play Again',
@@ -17,6 +17,10 @@ export default {
17
17
  'No se pudo generar un crucigrama {0} por {0} con las palabras proporcionadas',
18
18
  unknown:
19
19
  'Se produjo un error desconocido durante la creación del crucigrama',
20
+ unable_to_load_editor:
21
+ 'No se puede generar el crucigrama. Tu lista de palabras actual puede tener demasiadas palabras, palabras demasiado cortas o largas, o suficientes letras compartidas para los cruces. Puedes editar tu lista de palabras e intentarlo de nuevo.',
22
+ unable_to_load_student:
23
+ 'No se puede generar un crucigrama con estas palabras. Actualice la página hasta que se cargue correctamente o contacte con el soporte si el problema persiste.',
20
24
  },
21
25
 
22
26
  play_again: 'Aleatorizar crucigramas y jugar de nuevo',
@@ -12,6 +12,10 @@ export default {
12
12
  could_not_generate:
13
13
  'Det gick inte att skapa ett {0} gånger {0} korsord med de angivna orden',
14
14
  unknown: 'Ett okänt fel inträffade under korsordsskapandet',
15
+ unable_to_load_editor:
16
+ 'Det går inte att skapa korsord. Din nuvarande ordlista kan ha för många ord, ord som är för korta/långa eller otillräckliga delade bokstäver för korsningar. Du kan redigera din ordlista och försöka igen.',
17
+ unable_to_load_student:
18
+ 'Det går inte att skapa korsord med dessa ord. Försök att uppdatera sidan tills den läses in eller kontakta supporten om problemet kvarstår.',
15
19
  },
16
20
 
17
21
  play_again: 'Randomisera korsord och spela igen',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windward/games",
3
- "version": "0.14.0",
3
+ "version": "0.16.0",
4
4
  "description": "Windward UI Plugin Games",
5
5
  "main": "plugin.js",
6
6
  "scripts": {