@windward/games 0.0.1

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 (68) hide show
  1. package/.editorconfig +13 -0
  2. package/.eslintrc.js +11 -0
  3. package/.prettierrc +4 -0
  4. package/README.md +43 -0
  5. package/babel.config.js +1 -0
  6. package/components/content/CrudTable.vue +295 -0
  7. package/components/content/DataTableRowHandler.vue +113 -0
  8. package/components/content/DatableEditor.vue +223 -0
  9. package/components/content/blocks/BaseContentBlock.vue +8 -0
  10. package/components/content/blocks/dragDrop/BucketGame.vue +520 -0
  11. package/components/content/blocks/dragDrop/SortingGame.vue +303 -0
  12. package/components/content/blocks/flashcards/CardFace.vue +112 -0
  13. package/components/content/blocks/flashcards/Flashcard.vue +150 -0
  14. package/components/content/blocks/flashcards/FlashcardSlides.vue +121 -0
  15. package/components/content/blocks/matchingGame/MatchingGame.vue +545 -0
  16. package/components/content/blocks/quizshowGame/AnswerPanel.vue +338 -0
  17. package/components/content/blocks/quizshowGame/Gridview.vue +260 -0
  18. package/components/content/blocks/quizshowGame/QuizShow.vue +516 -0
  19. package/components/content/blocks/quizshowGame/feedbackIcons.vue +41 -0
  20. package/components/content/blocks/slideshow/SlideShow.vue +175 -0
  21. package/components/settings/BucketGameSettingsManager.vue +683 -0
  22. package/components/settings/FlashCardSlidesManager.vue +489 -0
  23. package/components/settings/MatchingGameManager.vue +775 -0
  24. package/components/settings/QuizShowSettingsManager.vue +408 -0
  25. package/components/settings/SlideShowManager.vue +248 -0
  26. package/components/settings/SortingGameSettingsManager.vue +286 -0
  27. package/i18n/en-US/components/content/blocks/bucket_game.ts +39 -0
  28. package/i18n/en-US/components/content/blocks/flashcard.ts +5 -0
  29. package/i18n/en-US/components/content/blocks/index.ts +15 -0
  30. package/i18n/en-US/components/content/blocks/matching_game.ts +26 -0
  31. package/i18n/en-US/components/content/blocks/quizshow_game.ts +35 -0
  32. package/i18n/en-US/components/content/blocks/slideshow.ts +13 -0
  33. package/i18n/en-US/components/content/blocks/sorting_game.ts +5 -0
  34. package/i18n/en-US/components/content/crud_table.ts +6 -0
  35. package/i18n/en-US/components/content/index.ts +7 -0
  36. package/i18n/en-US/components/index.ts +9 -0
  37. package/i18n/en-US/components/navigation/index.ts +5 -0
  38. package/i18n/en-US/components/settings/bucket_game.ts +35 -0
  39. package/i18n/en-US/components/settings/flashcard.ts +26 -0
  40. package/i18n/en-US/components/settings/index.ts +13 -0
  41. package/i18n/en-US/components/settings/matching_game.ts +15 -0
  42. package/i18n/en-US/components/settings/quizshow_game.ts +14 -0
  43. package/i18n/en-US/components/settings/slideshow.ts +11 -0
  44. package/i18n/en-US/index.ts +15 -0
  45. package/i18n/en-US/modules/index.ts +5 -0
  46. package/i18n/en-US/pages/index.ts +5 -0
  47. package/i18n/en-US/shared/content_blocks.ts +14 -0
  48. package/i18n/en-US/shared/index.ts +7 -0
  49. package/i18n/en-US/shared/settings.ts +10 -0
  50. package/i18n/en-US.ts +5 -0
  51. package/jest.config.js +18 -0
  52. package/package.json +51 -0
  53. package/plugin.js +150 -0
  54. package/test/blocks/dragDrop/BucketGame.spec.js +26 -0
  55. package/test/blocks/dragDrop/SortingGame.spec.js +47 -0
  56. package/test/blocks/flashcards/CardFace.spec.js +21 -0
  57. package/test/blocks/flashcards/FlashCardSlides.spec.js +24 -0
  58. package/test/blocks/flashcards/Flashcard.spec.js +24 -0
  59. package/test/blocks/matchingGame/MatchingGame.spec.js +26 -0
  60. package/test/blocks/quizShow/quizShow.spec.js +31 -0
  61. package/test/blocks/slideshow/slideshow.spec.js +24 -0
  62. package/test/mocks.js +2 -0
  63. package/test/settings/BucketGameManager.spec.js +125 -0
  64. package/test/settings/FlashCardSlidesManager.spec.js +24 -0
  65. package/test/settings/MatchingGameManager.spec.js +30 -0
  66. package/test/settings/SlideShowManager.spec.js +30 -0
  67. package/test/settings/SortingGameManager.spec.js +71 -0
  68. package/tsconfig.json +20 -0
@@ -0,0 +1,520 @@
1
+ <template>
2
+ <div>
3
+ <div>
4
+ <h1 class="title" aria-label="bucket game title" tabindex="0">
5
+ {{ block.metadata.config.title }}
6
+ </h1>
7
+
8
+ <p tabindex="0">
9
+ {{ block.metadata.config.instructions }}
10
+ </p>
11
+ <h3 v-if="!render" class="d-flex justify-center align-center">
12
+ {{
13
+ $t(
14
+ 'plugin.games.components.content.blocks.bucket_game.cannot'
15
+ )
16
+ }}
17
+ </h3>
18
+ <v-container fluid :class="status" class="pa-0">
19
+ <br />
20
+ <v-row>
21
+ <v-col></v-col>
22
+ <v-col class="d-flex justify-center">{{
23
+ feedback
24
+ ? feedback
25
+ : $t(
26
+ 'plugin.games.components.content.blocks.bucket_game.form.feedback.feedback_here'
27
+ )
28
+ }}</v-col>
29
+ <v-col class="d-flex justify-end pl-4">
30
+ <v-btn
31
+ v-if="
32
+ status === 'successOutline' ||
33
+ status === 'errorOutline'
34
+ "
35
+ class="mr-5"
36
+ :color="
37
+ status == 'successOutline' ? 'success' : 'error'
38
+ "
39
+ @click="continueGame"
40
+ >{{ $t('shared.forms.continue') }}
41
+ </v-btn></v-col
42
+ >
43
+ </v-row>
44
+ <br />
45
+ </v-container>
46
+ <div v-if="render">
47
+ <v-container>
48
+ <draggable
49
+ class="d-flex flex-wrap flex-row justify-center flex-fill"
50
+ :list="mainAnswer"
51
+ :disabled="!allow_drag"
52
+ group="people"
53
+ :move="onMoveCallback"
54
+ >
55
+ <v-row align="center" class="col-md-10">
56
+ <v-card
57
+ class="pa-2 flex-fill"
58
+ outlined
59
+ tile
60
+ v-if="mainAnswer[0]"
61
+ >
62
+ <v-icon>mdi-drag-vertical</v-icon>
63
+
64
+ <span class="text-justify">{{
65
+ mainAnswer[counter].display
66
+ }}</span>
67
+ </v-card>
68
+ </v-row>
69
+ </draggable>
70
+ <br />
71
+
72
+ <v-row
73
+ class="d-flex flex-wrap flex-row justify-center flex-fill"
74
+ >
75
+ <v-row align="center" class="col-md-10">
76
+ <v-card
77
+ v-for="(bucket, bindex) in items"
78
+ :key="'b-v-card-' + bindex"
79
+ class="pa-2 flex-fill bucket"
80
+ min-height="5em"
81
+ outlined
82
+ tile
83
+ :color="
84
+ block.metadata.config.bucket_titles[bindex]
85
+ .color
86
+ "
87
+ >
88
+ <v-card-text class="text-center">
89
+ <draggable
90
+ :key="'bucket - ' + bindex"
91
+ disabled
92
+ group="people"
93
+ v-model="items[bindex]"
94
+ @change="change($event, bindex)"
95
+ :move="checkMove"
96
+ tabindex="0"
97
+ >
98
+ <div class="card_text">
99
+ {{
100
+ block.metadata.config
101
+ .bucket_titles[bindex].title
102
+ }}
103
+ </div>
104
+ </draggable></v-card-text
105
+ >
106
+ </v-card>
107
+ </v-row>
108
+ </v-row>
109
+ </v-container>
110
+ </div>
111
+ </div>
112
+ <div v-if="!render">
113
+ <v-container>
114
+ <draggable
115
+ class="d-flex flex-wrap flex-row justify-center flex-fill"
116
+ :list="block.metadata.config.bucket_answers[startingIndex]"
117
+ disabled="true"
118
+ group="people"
119
+ :move="onMoveCallback"
120
+ >
121
+ <v-row align="center" class="col-md-10">
122
+ <v-card
123
+ class="pa-2 flex-fill"
124
+ outlined
125
+ tile
126
+ v-if="
127
+ block.metadata.config.bucket_answers[
128
+ startingIndex
129
+ ]
130
+ "
131
+ >
132
+ <v-icon>mdi-drag-vertical</v-icon>
133
+
134
+ <span class="text-justify">{{
135
+ block.metadata.config.bucket_answers[
136
+ startingIndex
137
+ ][startingIndex].display
138
+ }}</span>
139
+ </v-card>
140
+ </v-row>
141
+ </draggable>
142
+ <br />
143
+
144
+ <v-row
145
+ class="d-flex flex-wrap flex-row justify-center flex-fill"
146
+ >
147
+ <v-row align="center" class="col-md-10">
148
+ <v-card
149
+ v-for="(bucket, bindex) in block.metadata.config
150
+ .bucket_titles"
151
+ :key="'b-v-card-' + bindex"
152
+ class="pa-2 flex-fill bucket"
153
+ min-height="5em"
154
+ outlined
155
+ tile
156
+ :color="
157
+ block.metadata.config.bucket_titles[bindex]
158
+ .color
159
+ "
160
+ >
161
+ <v-card-text class="text-center">
162
+ <draggable
163
+ :key="'bucket - ' + bindex"
164
+ disabled
165
+ group="people"
166
+ v-model="items[bindex]"
167
+ @change="change($event, bindex)"
168
+ tabindex="0"
169
+ >
170
+ <div class="card_text">
171
+ {{
172
+ block.metadata.config.bucket_titles[
173
+ bindex
174
+ ].title
175
+ }}
176
+ </div>
177
+ </draggable></v-card-text
178
+ >
179
+ </v-card>
180
+ </v-row>
181
+ </v-row>
182
+ </v-container>
183
+ </div>
184
+ <v-container
185
+ class="d-flex flex-wrap flex-row justify-center flex-fill"
186
+ align="end"
187
+ >
188
+ <v-layout>
189
+ <v-flex xs8></v-flex>
190
+ <v-flex xs4>
191
+ <v-row
192
+ align="end"
193
+ tabindex="0"
194
+ :aria-label="
195
+ $t(
196
+ 'plugin.games.components.content.blocks.matching_game.of_complete',
197
+ [completedAmount, totalAmountQuestions]
198
+ )
199
+ "
200
+ >
201
+ <v-col align="end" tabindex="0">
202
+ {{
203
+ $t(
204
+ 'plugin.games.components.content.blocks.matching_game.of_complete_text_area',
205
+ [completedAmount, totalAmountQuestions]
206
+ )
207
+ }}
208
+ <v-progress-linear
209
+ color="primary"
210
+ outlined
211
+ v-model="completedPercent"
212
+ rounded
213
+ height="15"
214
+ ></v-progress-linear>
215
+ <br />
216
+ <v-btn color="primary" outlined @click="onReset"
217
+ >{{ $t('shared.forms.reset') }}
218
+ </v-btn>
219
+ </v-col>
220
+ </v-row>
221
+ </v-flex>
222
+ </v-layout>
223
+ </v-container>
224
+ </div>
225
+ </template>
226
+ <script>
227
+ import draggable from 'vuedraggable'
228
+ import _ from 'lodash'
229
+ import CrudTable from '../../CrudTable'
230
+ import BaseContentBlock from '~/components/Content/Blocks/BaseContentBlock'
231
+
232
+ export default {
233
+ name: 'BucketGame',
234
+ components: { CrudTable, draggable },
235
+ extends: BaseContentBlock,
236
+ beforeMount() {
237
+ if (_.isEmpty(this.block)) {
238
+ this.block = {}
239
+ }
240
+ if (_.isEmpty(this.block.metadata)) {
241
+ this.block.metadata = {}
242
+ }
243
+ if (_.isEmpty(this.block.metadata.config)) {
244
+ this.block.metadata.config = {}
245
+ }
246
+ if (_.isEmpty(this.block.metadata.config.title)) {
247
+ this.block.metadata.config.title = ''
248
+ }
249
+ if (_.isEmpty(this.block.metadata.config.instructions)) {
250
+ this.block.metadata.config.instructions = ''
251
+ }
252
+ if (_.isEmpty(this.block.metadata.config.feedback_correct)) {
253
+ this.block.metadata.config.feedback_correct = ''
254
+ }
255
+ if (_.isEmpty(this.block.metadata.config.feedback_incorrect)) {
256
+ this.block.metadata.config.feedback_incorrect = ''
257
+ }
258
+ if (_.isEmpty(this.block.metadata.config.bucket_titles)) {
259
+ this.block.metadata.config.bucket_titles = []
260
+ }
261
+ if (_.isEmpty(this.block.metadata.config.bucket_answers)) {
262
+ this.block.metadata.config.bucket_answers = []
263
+ }
264
+ if (_.isEmpty(this.block.body)) {
265
+ this.block.body = this.$t(
266
+ 'plugin.games.components.content.blocks.bucket_game.game_title'
267
+ )
268
+ }
269
+ },
270
+ data() {
271
+ return {
272
+ saveState: false,
273
+ instructions: '',
274
+ feedback: '',
275
+ counter: 0,
276
+ headers: [
277
+ {
278
+ text: 'Bucket display text',
279
+ align: 'start',
280
+ sortable: false,
281
+ value: 'display',
282
+ draggable: true,
283
+ },
284
+ { text: 'bucket value', value: 'value', sortable: false },
285
+ { text: 'feedback', value: 'feedback', sortable: false },
286
+ ],
287
+ default_item: {
288
+ id: 0,
289
+ value: '',
290
+ display_value: '',
291
+ feedback: '',
292
+ },
293
+ bucket_titles: [],
294
+ bucket_colors: [],
295
+ items: [],
296
+ dialogDelete: false,
297
+ bucketDeleteIndex: 0,
298
+ status: 'default',
299
+ allow_drag: true,
300
+ mainAnswer: [],
301
+ startingIndex: 0,
302
+ }
303
+ },
304
+ computed: {
305
+ completedAmount() {
306
+ if (this.items) {
307
+ return _.flatten(this.items).length
308
+ }
309
+ },
310
+ totalAmountQuestions() {
311
+ if (this.block.metadata.config.bucket_answers) {
312
+ return _.flatten(this.block.metadata.config.bucket_answers)
313
+ .length
314
+ }
315
+ },
316
+ completedPercent() {
317
+ if (
318
+ this.block.metadata.config.bucket_answers.length > 0 &&
319
+ this.items.length > 0
320
+ ) {
321
+ return (this.completedAmount / this.totalAmountQuestions) * 100
322
+ }
323
+ return 0
324
+ },
325
+ },
326
+ watch: {
327
+ render(newValue) {
328
+ if (newValue) {
329
+ this.setUpGame()
330
+ }
331
+ },
332
+ },
333
+ mounted() {
334
+ if (this.block.metadata.config.bucket_answers.length > 0) {
335
+ this.setMainAnswer()
336
+ }
337
+ if (this.block.metadata.config.bucket_titles.length > 0) {
338
+ this.setUpGame()
339
+ }
340
+ this.status = 'default'
341
+ },
342
+ methods: {
343
+ checkMove() {
344
+ return false
345
+ },
346
+ setUpGame() {
347
+ this.block.metadata.config.bucket_titles.forEach((element) => {
348
+ let index =
349
+ this.block.metadata.config.bucket_titles.indexOf(element)
350
+ this.items[index] = []
351
+ })
352
+ this.mainAnswer = this.setMainAnswer()
353
+ },
354
+ shuffle(array) {
355
+ let currentIndex = array.length,
356
+ randomIndex
357
+
358
+ // While there remain elements to shuffle.
359
+ while (currentIndex !== 0) {
360
+ // Pick a remaining element.
361
+ randomIndex = Math.floor(Math.random() * currentIndex)
362
+ currentIndex--
363
+
364
+ // And swap it with the current element.
365
+ ;[array[currentIndex], array[randomIndex]] = [
366
+ array[randomIndex],
367
+ array[currentIndex],
368
+ ]
369
+ }
370
+
371
+ return array
372
+ },
373
+ setMainAnswer() {
374
+ let result = []
375
+ let temp = {}
376
+ for (const index in this.block.metadata.config.bucket_answers) {
377
+ result[index] = []
378
+ for (const itemIndex in this.block.metadata.config
379
+ .bucket_answers[index]) {
380
+ temp =
381
+ this.block.metadata.config.bucket_answers[index][
382
+ itemIndex
383
+ ]
384
+ temp.bucket_index = index
385
+ result[index].push(temp)
386
+ }
387
+ }
388
+ return this.shuffle(_.flatten(result))
389
+ },
390
+ closeDelete() {
391
+ this.dialogDelete = false
392
+ },
393
+ next() {
394
+ console.log(
395
+ 'index' + this.index,
396
+ 'bucket length' +
397
+ this.block.metadata.config.bucket_answers.length
398
+ )
399
+
400
+ if (
401
+ this.index <
402
+ this.block.metadata.config.bucket_answers.length - 1
403
+ ) {
404
+ this.index = this.index + 1
405
+ } else {
406
+ this.index = 0
407
+ }
408
+ },
409
+ onCloneCallback(item) {
410
+ // Create a fresh copy of item
411
+ const cloneMe = JSON.parse(JSON.stringify(item))
412
+ console.log('cloned')
413
+
414
+ return cloneMe
415
+ },
416
+ onMoveCallback(evt, originalEvent) {
417
+ const item = evt.draggedContext.element
418
+ const itemIdx = evt.draggedContext.futureIndex
419
+ this.items[item.bucket_index].indexOf(item)
420
+
421
+ if (
422
+ this.items[item.bucket_index].indexOf(item) === -1 &&
423
+ this.block.metadata.config.bucket_answers[
424
+ item.bucket_index
425
+ ].indexOf(item) !== -1
426
+ ) {
427
+ return true
428
+ }
429
+
430
+ return false
431
+ },
432
+ onDropCallback(evt, originalEvent) {
433
+ console.log('dropped', evt)
434
+ },
435
+ change(evt, bucket_index) {
436
+ this.allow_drag = false
437
+ if (
438
+ this.items[bucket_index].indexOf(evt.added.element) !== -1 &&
439
+ !_.isEmpty(
440
+ this.block.metadata.config.bucket_answers[bucket_index]
441
+ ) &&
442
+ this.block.metadata.config.bucket_answers[bucket_index].indexOf(
443
+ evt.added.element
444
+ ) !== -1 &&
445
+ this.mainAnswer.length > 0
446
+ ) {
447
+ this.feedback = evt.added.element.feedback
448
+ ? evt.added.element.feedback
449
+ : this.block.metadata.config.feedback_correct
450
+ this.status = 'successOutline'
451
+ } else if (this.mainAnswer.length === 0) {
452
+ this.feedback = this.$t(
453
+ 'plugin.games.components.content.blocks.matching_game.congratulations_feedback'
454
+ )
455
+ } else {
456
+ let items = this.items[bucket_index]
457
+ const indexOfAddedElement = items.indexOf(evt.added.element)
458
+ this.items[bucket_index].splice(indexOfAddedElement, 1)
459
+ this.mainAnswer.push(evt.added.element)
460
+ this.feedback = this.block.metadata.config.feedback_incorrect
461
+ this.status = 'errorOutline'
462
+ }
463
+ },
464
+ continueGame() {
465
+ this.status = 'default'
466
+ this.allow_drag = true
467
+ this.feedback = ''
468
+ },
469
+ onReset() {
470
+ this.items = []
471
+ for (const index in this.block.metadata.config.bucket_answers) {
472
+ this.items[index] = []
473
+ }
474
+ this.status = 'default'
475
+ this.feedback = ''
476
+ this.allow_drag = true
477
+ this.mainAnswer = this.setMainAnswer()
478
+ },
479
+ },
480
+ }
481
+ </script>
482
+ <style scoped>
483
+ .successOutline {
484
+ border: 4px solid var(--v-success-base);
485
+ color: var(--v-success-base);
486
+ }
487
+ .errorOutline {
488
+ border: 4px solid var(--v-error-base);
489
+ color: var(--v-error-base);
490
+ }
491
+ .white-bg {
492
+ background-color: #ffffff;
493
+ }
494
+ .feedback--error {
495
+ background-color: #ff8383;
496
+ color: black;
497
+ }
498
+ .feedback--success {
499
+ background-color: #8cfa54;
500
+ color: black;
501
+ }
502
+ .body {
503
+ background-color: #d8ebfe;
504
+ color: black;
505
+ }
506
+ .title {
507
+ color: #04709f;
508
+ }
509
+ .bucket {
510
+ line-height: 1.1em;
511
+ padding: 0.5em;
512
+ box-shadow: 0px 2px 3px #0000004a;
513
+ transition: 0.5s box-shadow;
514
+ margin: 1%;
515
+ }
516
+ .card_text {
517
+ font-size: large;
518
+ color: black;
519
+ }
520
+ </style>