@windward/games 0.9.0 → 0.11.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.
Files changed (25) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/components/content/blocks/crosswordPuzzle/CrosswordPuzzle.vue +2 -6
  3. package/components/content/blocks/dragDrop/BucketGame.vue +157 -87
  4. package/components/content/blocks/dragDrop/SortingGame.vue +42 -66
  5. package/components/content/blocks/flashcards/CardFace.vue +22 -57
  6. package/components/content/blocks/flashcards/Flashcard.vue +12 -13
  7. package/components/content/blocks/matchingGame/MatchingGame.vue +73 -117
  8. package/components/content/blocks/slideshow/SlideShow.vue +10 -24
  9. package/components/settings/BucketGameSettingsManager.vue +9 -32
  10. package/components/settings/FlashCardSlidesManager.vue +26 -91
  11. package/components/settings/MatchingGameManager.vue +14 -94
  12. package/components/settings/SlideShowManager.vue +11 -46
  13. package/components/settings/SortingGameSettingsManager.vue +2 -19
  14. package/i18n/en-US/components/content/blocks/bucket_game.ts +1 -0
  15. package/i18n/en-US/components/content/blocks/sorting_game.ts +2 -0
  16. package/i18n/en-US/components/settings/sorting_game.ts +2 -0
  17. package/i18n/es-ES/components/content/blocks/bucket_game.ts +1 -0
  18. package/i18n/es-ES/components/content/blocks/sorting_game.ts +2 -0
  19. package/i18n/es-ES/components/settings/sorting_game.ts +2 -0
  20. package/i18n/sv-SE/components/content/blocks/bucket_game.ts +1 -0
  21. package/i18n/sv-SE/components/content/blocks/sorting_game.ts +2 -0
  22. package/i18n/sv-SE/components/settings/sorting_game.ts +2 -0
  23. package/package.json +1 -1
  24. package/test/__mocks__/contentBlockMock.js +94 -0
  25. package/test/mocks.js +1 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ### Release [0.11.0] created - 2025-02-05
4
+
5
+
6
+ ### Release [0.10.0] created - 2025-01-03
7
+
8
+
3
9
  ## Release [0.7.0] - 2024-08-29
4
10
 
5
11
  * Version bump to 0.7.0
@@ -91,7 +91,7 @@
91
91
  </v-col>
92
92
  </v-row>
93
93
  <v-row class="d-flex justify-center">
94
- <v-col cols="12" class="d-flex justify-center">
94
+ <v-col cols="12" class="d-flex justify-end">
95
95
  <v-btn
96
96
  color="primary"
97
97
  elevation="0"
@@ -99,11 +99,7 @@
99
99
  class="ma-3"
100
100
  @click="onSetUpData"
101
101
  >
102
- {{
103
- $t(
104
- 'windward.games.components.content.blocks.crossword.play_again'
105
- )
106
- }}
102
+ {{ $t('shared.forms.reset') }}
107
103
  </v-btn>
108
104
  </v-col>
109
105
  </v-row>
@@ -27,46 +27,52 @@
27
27
  )
28
28
  }}
29
29
  </h4>
30
- <v-container fluid :class="status">
31
- <v-row class="pa-4">
32
- <v-col></v-col>
33
- <v-col class="d-flex justify-center align-center">{{
34
- feedback
35
- ? feedback
36
- : $t(
37
- 'windward.games.components.content.blocks.bucket_game.form.feedback.feedback_here'
38
- )
39
- }}</v-col>
40
- <v-col class="d-flex justify-end pl-4">
41
- <v-btn
42
- v-if="status === 'container-success-outline'"
43
- class="mr-5"
44
- color="success"
45
- elevation="0"
46
- @click="continueGame"
47
- >{{ $t('shared.forms.continue') }}
48
- </v-btn>
49
- <v-container
50
- v-if="status === 'container-error-outline'"
51
- class="d-flex justify-end"
52
- @click="continueGame"
53
- ><v-icon class="icon--error" color="error"
54
- >mdi-close-circle</v-icon
55
- >
56
- </v-container>
57
- </v-col>
30
+ <v-alert fluid :class="status">
31
+ <v-row class="pa-4 d-flex justify-center">
32
+ <p class="mb-0 p-text-override">
33
+ {{
34
+ feedback
35
+ ? feedback
36
+ : $t(
37
+ 'windward.games.components.content.blocks.bucket_game.form.feedback.feedback_here'
38
+ )
39
+ }}
40
+ </p>
58
41
  </v-row>
59
- </v-container>
42
+ <v-row class="d-flex justify-center mt-0 mb-1">
43
+ <v-btn
44
+ v-if="
45
+ status === 'container-success-outline' &&
46
+ mainAnswer.length !== 0
47
+ "
48
+ color="success"
49
+ elevation="0"
50
+ @click="continueGame"
51
+ >{{ $t('shared.forms.continue') }}
52
+ </v-btn>
53
+ <v-btn
54
+ v-if="status === 'container-error-outline'"
55
+ color="error"
56
+ @click="continueGame"
57
+ >{{
58
+ $t(
59
+ 'windward.games.components.content.blocks.bucket_game.try_again'
60
+ )
61
+ }}
62
+ </v-btn>
63
+ </v-row>
64
+ </v-alert>
60
65
  <div v-if="render">
61
66
  <v-container>
62
67
  <draggable
68
+ v-if="mainAnswer.length !== 0"
63
69
  class="d-flex flex-wrap flex-row justify-center flex-fill"
64
70
  :list="mainAnswer"
65
71
  :disabled="!allow_drag"
66
72
  group="people"
67
73
  :move="onMoveCallback"
68
74
  >
69
- <v-row class="col-md-10">
75
+ <v-row class="ma-2">
70
76
  <v-card
71
77
  v-if="mainAnswer[0]"
72
78
  class="pa-2 d-flex justify-center flex-fill container-outline"
@@ -100,7 +106,7 @@
100
106
  "
101
107
  >
102
108
  <v-card-text
103
- class="d-flex justify-center text-center pl-0 pr-0"
109
+ class="d-flex justify-center text-center pa-0 container-card-text"
104
110
  >
105
111
  <draggable
106
112
  v-model="items[bindex]"
@@ -112,13 +118,16 @@
112
118
  tabindex="0"
113
119
  class="draggable-bucket"
114
120
  >
115
- <TextViewer
116
- v-model="
117
- block.metadata.config
118
- .bucket_titles[bindex].title
119
- "
120
- class="d-flex align-center justify-center container-buckets"
121
- ></TextViewer>
121
+ <p class="mb-0">
122
+ <TextViewer
123
+ v-model="
124
+ block.metadata.config
125
+ .bucket_titles[bindex]
126
+ .title
127
+ "
128
+ class="d-flex align-center justify-center container-buckets"
129
+ ></TextViewer>
130
+ </p>
122
131
  <v-container
123
132
  v-for="(
124
133
  nested_answer, nested_index
@@ -128,11 +137,37 @@
128
137
  :key="nested_index"
129
138
  class="d-flex justify-center align-center pa-0"
130
139
  >
131
- <TextViewer
132
- class="container-nested-answers mb-1"
133
- v-model="nested_answer.display"
134
- remove-root-element
135
- ></TextViewer>
140
+ <v-tooltip bottom>
141
+ <template
142
+ v-slot:activator="{
143
+ on,
144
+ attrs,
145
+ }"
146
+ >
147
+ <v-container
148
+ v-bind="attrs"
149
+ v-on="on"
150
+ class="my-0 pa-0"
151
+ >
152
+ <TextViewer
153
+ class="container-nested-answers mb-1"
154
+ v-model="
155
+ nested_answer.display
156
+ "
157
+ remove-root-element
158
+ ></TextViewer>
159
+ </v-container>
160
+ </template>
161
+ <span
162
+ ><TextViewer
163
+ class="container-nested-tooltip"
164
+ v-model="
165
+ nested_answer.display
166
+ "
167
+ remove-root-element
168
+ ></TextViewer
169
+ ></span>
170
+ </v-tooltip>
136
171
  </v-container>
137
172
  </draggable>
138
173
  </v-card-text>
@@ -207,15 +242,17 @@
207
242
  @change="change($event, bindex)"
208
243
  tabindex="0"
209
244
  >
210
- <TextViewer
211
- v-model="
212
- block.metadata.config.bucket_titles[
213
- bindex
214
- ].title
215
- "
216
- class="d-flex align-center"
217
- ></TextViewer></draggable
218
- ></v-card-text>
245
+ <p class="mb-0">
246
+ <TextViewer
247
+ v-model="
248
+ block.metadata.config
249
+ .bucket_titles[bindex].title
250
+ "
251
+ class="d-flex align-center justify-center container-buckets"
252
+ ></TextViewer>
253
+ </p>
254
+ </draggable>
255
+ </v-card-text>
219
256
  </v-card>
220
257
  </v-row>
221
258
  </v-row>
@@ -226,8 +263,8 @@
226
263
  align="end"
227
264
  >
228
265
  <v-layout>
229
- <v-flex xs8></v-flex>
230
- <v-flex xs4>
266
+ <v-col cols="3" xl="8" lg="8" md="8" sm="8"></v-col>
267
+ <v-col cols="9" xl="4" lg="4" md="4" sm="4">
231
268
  <v-row
232
269
  align="end"
233
270
  tabindex="0"
@@ -263,7 +300,7 @@
263
300
  </v-btn>
264
301
  </v-col>
265
302
  </v-row>
266
- </v-flex>
303
+ </v-col>
267
304
  </v-layout>
268
305
  </v-container>
269
306
  </div>
@@ -302,12 +339,6 @@ export default {
302
339
  if (_.isEmpty(this.block.metadata.config.instructions)) {
303
340
  this.block.metadata.config.instructions = ''
304
341
  }
305
- if (_.isEmpty(this.block.metadata.config.feedback_correct)) {
306
- this.block.metadata.config.feedback_correct = ''
307
- }
308
- if (_.isEmpty(this.block.metadata.config.feedback_incorrect)) {
309
- this.block.metadata.config.feedback_incorrect = ''
310
- }
311
342
  if (_.isEmpty(this.block.metadata.config.bucket_titles)) {
312
343
  this.block.metadata.config.bucket_titles = []
313
344
  }
@@ -494,16 +525,19 @@ export default {
494
525
  bucket_index
495
526
  )
496
527
  ) {
497
- this.feedback = evt.added.element.feedback
498
- ? evt.added.element.feedback
499
- : this.block.metadata.config.feedback_correct
528
+ // set correct feedback
529
+ if (evt.added.element.feedback) {
530
+ this.feedback = evt.added.element.feedback
531
+ } else {
532
+ this.feedback = this.$t(
533
+ 'windward.games.components.settings.bucket_game.form.feedback.correct_default'
534
+ )
535
+ }
500
536
  // determines if answer is correct and then sees if that was the last answer
501
537
  // needs to be nested in here because this.mainAnswer is bound to :list on draggable
502
538
  // list changes the array so when it is using the last object in the array it looks like the array is empty
503
539
  if (this.mainAnswer.length === 0) {
504
- this.feedback = this.$t(
505
- 'windward.games.components.content.blocks.matching_game.congratulations_feedback'
506
- )
540
+ this.status = 'container-success-outline'
507
541
  this.block.metadata.config.bucket_titles[
508
542
  bucket_index
509
543
  ].nested_answers.push(evt.added.element)
@@ -512,30 +546,17 @@ export default {
512
546
  this.block.metadata.config.bucket_titles[
513
547
  bucket_index
514
548
  ].nested_answers.push(evt.added.element)
515
- // set correct feedback
516
- if (evt.added.element.feedback) {
517
- this.feedback = evt.added.element.feedback
518
- } else {
519
- this.feedback = this.block.metadata.config
520
- .feedback_correct
521
- ? this.block.metadata.config.feedback_correct
522
- : this.$t(
523
- 'windward.games.components.settings.bucket_game.form.feedback.correct_default'
524
- )
525
- }
526
549
  }
527
550
  } else {
528
551
  let items = this.items[bucket_index]
529
552
  const indexOfAddedElement = items.indexOf(evt.added.element)
530
553
  this.items[bucket_index].splice(indexOfAddedElement, 1)
531
554
  // puts item back into mutable array for draggable component
532
- this.mainAnswer.push(evt.added.element)
555
+ this.mainAnswer.unshift(evt.added.element)
533
556
  // set incorrect feedback
534
- this.feedback = this.block.metadata.config.feedback_incorrect
535
- ? this.block.metadata.config.feedback_incorrect
536
- : this.$t(
537
- 'windward.games.components.settings.bucket_game.form.feedback.incorrect_default'
538
- )
557
+ this.feedback = this.$t(
558
+ 'windward.games.components.settings.bucket_game.form.feedback.incorrect_default'
559
+ )
539
560
  this.status = 'container-error-outline'
540
561
  }
541
562
  },
@@ -587,7 +608,6 @@ export default {
587
608
  color: black;
588
609
  }
589
610
  .container-nested-answers {
590
- max-width: 10vw;
591
611
  min-width: 10vw;
592
612
  padding-left: 4px;
593
613
  padding-right: 4px;
@@ -598,6 +618,12 @@ export default {
598
618
  color: black;
599
619
  box-shadow: 0px 2px 3px #0000004a;
600
620
  border-radius: 2px;
621
+ line-height: 50px !important;
622
+ }
623
+ .container-nested-tooltip {
624
+ max-width: 12vw;
625
+ padding-left: 4px;
626
+ padding-right: 4px;
601
627
  }
602
628
  .container-buckets {
603
629
  color: black;
@@ -605,10 +631,42 @@ export default {
605
631
  .draggable-bucket {
606
632
  width: 100%;
607
633
  }
634
+ @media (max-width: 1264px) {
635
+ .card-bucket {
636
+ width: 20vw;
637
+ max-width: 20vw;
638
+ }
639
+ .container-nested-answers {
640
+ display: block !important;
641
+ width: 100%;
642
+ max-width: 100%;
643
+ min-width: 100%;
644
+ overflow-x: hidden !important;
645
+ }
646
+ .container-nested-tooltip {
647
+ max-width: 20vw;
648
+ }
649
+ }
650
+ @media (max-width: 960px) {
651
+ .card-bucket {
652
+ width: 35vw;
653
+ max-width: 35vw;
654
+ }
655
+ .container-nested-answers {
656
+ display: block !important;
657
+ width: 100%;
658
+ max-width: 100%;
659
+ min-width: 100%;
660
+ overflow-x: hidden !important;
661
+ }
662
+ .container-nested-tooltip {
663
+ max-width: 35vw;
664
+ }
665
+ }
608
666
  @media (max-width: 600px) {
609
667
  .card-bucket {
610
- width: 40vh;
611
- max-width: 40vh;
668
+ width: 70vw;
669
+ max-width: 70vw;
612
670
  }
613
671
  .container-nested-answers {
614
672
  display: block !important;
@@ -617,5 +675,17 @@ export default {
617
675
  min-width: 100%;
618
676
  overflow-x: hidden !important;
619
677
  }
678
+ .container-nested-tooltip {
679
+ max-width: 75vw;
680
+ }
681
+ }
682
+ .container-outline {
683
+ cursor: grab;
684
+ }
685
+ .container-card-text {
686
+ height: 100%;
687
+ }
688
+ .p-text-override {
689
+ color: var(--v-primary-base);
620
690
  }
621
691
  </style>
@@ -6,31 +6,18 @@
6
6
  <p v-if="block.metadata.config.instructions" tabindex="0" class="pt-3">
7
7
  {{ block.metadata.config.instructions }}
8
8
  </p>
9
- <v-container :key="'feedback'" :class="feedbackClass()">
10
- <v-row
11
- class="d-flex justify-space-around pa-4"
12
- align="center"
13
- justify="center"
14
- >
15
- <v-col cols="2"></v-col>
16
- <v-col cols="8" class="d-flex justify-center">{{
17
- feedback
18
- }}</v-col>
19
- <v-col cols="2">
20
- <v-row
21
- v-if="onFail() || onSuccess()"
22
- class="d-flex justify-end"
23
- >
24
- <v-container
25
- v-if="onFail()"
26
- @click="onContinueGame"
27
- class="d-flex justify-end"
28
- ><v-icon class="icon--error"
29
- >mdi-close-circle</v-icon
30
- >
31
- </v-container>
32
- </v-row>
33
- </v-col>
9
+ <v-container :class="feedbackClass()">
10
+ <v-row class="d-flex justify-center py-3">
11
+ {{ feedback }}
12
+ </v-row>
13
+ <v-row v-if="onFail()" class="d-flex justify-center pb-3">
14
+ <v-btn
15
+ color="primary"
16
+ outlined
17
+ elevation="0"
18
+ @click="onContinueGame"
19
+ >{{ $t('shared.forms.try_again') }}
20
+ </v-btn>
34
21
  </v-row>
35
22
  </v-container>
36
23
  <v-container v-if="render" class="mt-2">
@@ -70,12 +57,9 @@
70
57
  </v-row>
71
58
  </draggable>
72
59
  <v-container class="mt-3">
73
- <v-row
74
- v-if="!onFail() && !onSuccess()"
75
- class="d-flex justify-center"
76
- >
77
- <v-spacer class="col-lg-1" />
60
+ <v-row class="d-flex justify-center">
78
61
  <v-btn
62
+ v-if="!onFail() && !onSuccess()"
79
63
  color="primary"
80
64
  elevation="0"
81
65
  @click="onCheckAnswers"
@@ -87,19 +71,9 @@
87
71
  }}
88
72
  </v-btn>
89
73
  </v-row>
90
- <v-row
91
- v-if="onFail() || onSuccess()"
92
- class="d-flex justify-center"
93
- >
94
- <v-btn
95
- v-if="onFail()"
96
- color="primary"
97
- elevation="0"
98
- text
99
- @click="onContinueGame"
100
- >{{ $t('shared.forms.try_again') }} </v-btn
101
- >&nbsp;&nbsp;
74
+ <v-row class="d-flex justify-end">
102
75
  <v-btn
76
+ v-if="onFail() || onSuccess()"
103
77
  color="primary"
104
78
  elevation="0"
105
79
  @click="onReset"
@@ -109,29 +83,28 @@
109
83
  </v-row>
110
84
  </v-container>
111
85
  </v-container>
112
- <div v-if="!render">
86
+ <v-container v-if="!render" class="mt-2">
113
87
  <draggable
114
88
  v-model="block.metadata.config.answer"
115
89
  :disabled="disabled"
116
- class="d-flex flex-column mb-6"
90
+ class="d-flex flex-column"
117
91
  group="cards"
118
92
  v-bind="dragOptions"
119
93
  @change="onDragChange"
120
94
  >
121
95
  <v-row
122
- class="justify-center align-center"
123
96
  v-for="index in block.metadata.config.answer.length"
124
97
  :key="'sortable_' + index"
125
98
  >
126
- <v-col cols="1" v-if="graded">
99
+ <v-col cols="1" md="1" class="d-flex justify-end pa-0">
127
100
  <v-icon v-if="success[index - 1]" color="success"
128
- >mdi-check-bold
101
+ >mdi-check-circle
129
102
  </v-icon>
130
103
  <v-icon v-if="fail[index - 1]" color="error"
131
- >mdi-close</v-icon
104
+ >mdi-close-circle</v-icon
132
105
  >
133
106
  </v-col>
134
- <v-col cols="11">
107
+ <v-col cols="10">
135
108
  <v-card
136
109
  :class="
137
110
  'pa-2 flex-fill container-outline ' +
@@ -147,7 +120,7 @@
147
120
  </v-col>
148
121
  </v-row>
149
122
  </draggable>
150
- </div>
123
+ </v-container>
151
124
  </div>
152
125
  </template>
153
126
 
@@ -177,12 +150,7 @@ export default {
177
150
  }
178
151
  if (_.isEmpty(this.block.metadata.config.feedback_correct)) {
179
152
  this.block.metadata.config.feedback_correct = this.$t(
180
- 'windward.games.components.settings.bucket_game.form.feedback.correct_default'
181
- )
182
- }
183
- if (_.isEmpty(this.block.metadata.config.feedback_incorrect)) {
184
- this.block.metadata.config.feedback_incorrect = this.$t(
185
- 'windward.games.components.settings.bucket_game.form.feedback.incorrect_default'
153
+ 'windward.games.components.settings.sorting_game.default_feedback_correct'
186
154
  )
187
155
  }
188
156
  if (_.isEmpty(this.block.metadata.config.answer)) {
@@ -201,7 +169,6 @@ export default {
201
169
  feedback: 'feedback here',
202
170
  success: [],
203
171
  fail: [],
204
- graded: false,
205
172
  seed: 123,
206
173
  answer: [],
207
174
  }
@@ -266,7 +233,6 @@ export default {
266
233
  },
267
234
  onReset() {
268
235
  this.disabled = false
269
- this.graded = false
270
236
  this.success = []
271
237
  this.fail = []
272
238
  this.input = this.shuffle(
@@ -277,7 +243,6 @@ export default {
277
243
  },
278
244
  onContinueGame() {
279
245
  this.disabled = false
280
- this.graded = false
281
246
  this.success = []
282
247
  this.fail = []
283
248
  this.feedback = this.block.metadata.config.feedback_default
@@ -334,19 +299,26 @@ export default {
334
299
  this.emitCompleted()
335
300
  }
336
301
  if (this.onFail()) {
337
- this.feedback = this.block.metadata.config.feedback_incorrect
302
+ this.feedback = this.$t(
303
+ 'windward.games.components.content.blocks.sorting_game.incorrect_feedback'
304
+ )
338
305
  }
339
- this.graded = true
340
306
  this.seed = Math.floor(Math.random() * 100)
341
307
  },
342
308
  sortableStateClass(index) {
309
+ let classValue = ''
343
310
  if (this.success[index - 1]) {
344
- return 'sortable--success'
311
+ classValue += 'sortable--success '
345
312
  }
346
313
  if (this.fail[index - 1]) {
347
- return 'sortable--error'
314
+ classValue += 'sortable--error '
348
315
  }
349
- return ''
316
+ if (this.disabled) {
317
+ classValue += 'sortable-default '
318
+ } else if (!this.disabled) {
319
+ classValue += 'sortable-grab '
320
+ }
321
+ return classValue
350
322
  },
351
323
  iconClass(index) {
352
324
  if (this.success[index - 1] || this.fail[index - 1]) {
@@ -361,11 +333,9 @@ export default {
361
333
  <style scoped>
362
334
  .container-feedback-success {
363
335
  border: 4px solid var(--v-success-base);
364
- color: var(--v-success-base);
365
336
  }
366
337
  .container-feedback-error {
367
338
  border: 4px solid var(--v-error-base);
368
- color: var(--v-error-base);
369
339
  }
370
340
  .sortable--error {
371
341
  background-color: var(--v-error-base);
@@ -375,6 +345,12 @@ export default {
375
345
  background-color: var(--v-success-base);
376
346
  color: white;
377
347
  }
348
+ .sortable-grab {
349
+ cursor: grab;
350
+ }
351
+ .sortable-default {
352
+ cursor: default;
353
+ }
378
354
  .icon-inner {
379
355
  color: white;
380
356
  }