@windward/games 0.0.1 → 0.0.3

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 (31) hide show
  1. package/components/content/blocks/dragDrop/BucketGame.vue +4 -4
  2. package/components/content/blocks/dragDrop/SortingGame.vue +1 -1
  3. package/components/content/blocks/flashcards/FlashcardSlides.vue +2 -2
  4. package/components/content/blocks/matchingGame/MatchingGame.vue +2 -2
  5. package/components/content/blocks/multipleChoice/MultipleChoice.vue +565 -0
  6. package/components/content/blocks/multipleChoice/QuestionDialog.vue +276 -0
  7. package/components/content/blocks/quizshowGame/QuizShow.vue +2 -2
  8. package/components/content/blocks/slideshow/SlideShow.vue +2 -2
  9. package/components/content/blocks/wordJumble/Jumble.vue +97 -0
  10. package/components/content/blocks/wordJumble/WordJumble.vue +239 -0
  11. package/components/settings/MultipleChoiceSettingsManager.vue +290 -0
  12. package/components/settings/SortingGameSettingsManager.vue +10 -5
  13. package/components/settings/WordJumbleSettingsManager.vue +293 -0
  14. package/i18n/en-US/components/content/blocks/index.ts +4 -0
  15. package/i18n/en-US/components/content/blocks/matching_game.ts +1 -1
  16. package/i18n/en-US/components/content/blocks/multiple_choice.ts +11 -0
  17. package/i18n/en-US/components/content/blocks/word_jumble.ts +9 -0
  18. package/i18n/en-US/components/settings/index.ts +6 -0
  19. package/i18n/en-US/components/settings/multiple_choice.ts +16 -0
  20. package/i18n/en-US/components/settings/sorting_game.ts +3 -0
  21. package/i18n/en-US/components/settings/word_jumble.ts +11 -0
  22. package/i18n/en-US/shared/content_blocks.ts +2 -0
  23. package/i18n/en-US/shared/settings.ts +2 -0
  24. package/package.json +1 -1
  25. package/plugin.js +42 -0
  26. package/test/blocks/multipleChoice/MultipleChoice.spec.js +26 -0
  27. package/test/blocks/multipleChoice/QuestionDialog.spec.js +26 -0
  28. package/test/blocks/wordJumble/Jumble.spec.js +27 -0
  29. package/test/blocks/wordJumble/WordJumble.spec.js +24 -0
  30. package/test/settings/MultipleChoiceGameManager.spec.js +30 -0
  31. package/test/settings/WordJumbleManager.spec.js +87 -0
@@ -0,0 +1,290 @@
1
+ <template>
2
+ <v-container>
3
+ <div ref="form">
4
+ <v-text-field
5
+ v-model="block.metadata.config.title"
6
+ :counter="50"
7
+ maxlength="50"
8
+ :label="
9
+ $t(
10
+ 'plugin.games.components.settings.multiple_choice.title_placeholder'
11
+ )
12
+ "
13
+ ></v-text-field>
14
+ <v-textarea
15
+ outlined
16
+ auto-grow
17
+ v-model="block.metadata.config.instructions"
18
+ :counter="255"
19
+ maxlength="255"
20
+ :label="
21
+ $t(
22
+ 'plugin.games.components.settings.multiple_choice.instructions'
23
+ )
24
+ "
25
+ ></v-textarea>
26
+ <div>
27
+ <v-container class="pa-0">
28
+ <v-expansion-panels flat>
29
+ <v-expansion-panel>
30
+ <v-expansion-panel-header class="pa-0">
31
+ <h3>
32
+ {{
33
+ $t(
34
+ 'plugin.games.components.settings.multiple_choice.questions'
35
+ )
36
+ }}
37
+ </h3></v-expansion-panel-header
38
+ >
39
+ <v-expansion-panel-content class="ma-0">
40
+ <v-container class="pa-0">
41
+ <draggable
42
+ :list="block.metadata.config.questions"
43
+ :disabled="false"
44
+ class="flex-fill"
45
+ :group="{
46
+ name: 'people',
47
+ pull: 'clone',
48
+ put: false,
49
+ }"
50
+ >
51
+ <v-card
52
+ v-for="(question, index) in block
53
+ .metadata.config.questions"
54
+ :key="index"
55
+ class="pa-2 flex-fill cardOutline"
56
+ elevation="0"
57
+ outlined
58
+ tile
59
+ >
60
+ <v-row
61
+ class="itemHeight"
62
+ :class="cursor"
63
+ >
64
+ <p
65
+ class="text-truncate ma-0 seventy"
66
+ @click="
67
+ onOpenModal(
68
+ $event,
69
+ index
70
+ )
71
+ "
72
+ @mouseover="onHover"
73
+ @mouseleave="onHoverLeave"
74
+ >
75
+ <v-icon class="pl-2"
76
+ >mdi-gesture-tap-hold</v-icon
77
+ >
78
+ {{
79
+ question.body
80
+ ? question.body
81
+ : $t(
82
+ 'plugin.games.components.settings.bucket_game.form.enter_text'
83
+ )
84
+ }}
85
+ </p>
86
+ <v-icon
87
+ class="twenty"
88
+ @click="onDelete(index)"
89
+ >mdi-delete-outline</v-icon
90
+ >
91
+ </v-row>
92
+ </v-card>
93
+ </draggable>
94
+ <v-container class="d-flex justify-center">
95
+ <p
96
+ @mouseover="onHover"
97
+ @mouseleave="onHoverLeave"
98
+ @click="onOpenModal"
99
+ v-on:keyup.enter="onOpenModal"
100
+ class="fullWidth"
101
+ :class="cursor"
102
+ tabindex="0"
103
+ >
104
+ <v-icon class="primary addIcon"
105
+ >mdi-plus</v-icon
106
+ >
107
+ {{
108
+ $t(
109
+ 'plugin.games.components.settings.multiple_choice.add_question'
110
+ )
111
+ }}
112
+ </p>
113
+ </v-container>
114
+ </v-container>
115
+ </v-expansion-panel-content>
116
+ </v-expansion-panel>
117
+ </v-expansion-panels>
118
+ </v-container>
119
+ </div>
120
+ </div>
121
+ <Dialog
122
+ v-model="dialog"
123
+ :trigger="false"
124
+ action-save
125
+ :action-save-new="isNotEditing"
126
+ @click:outside="close"
127
+ @click:close="close"
128
+ @keydown.esc="close"
129
+ >
130
+ <template #title>{{
131
+ $t(
132
+ 'plugin.games.components.settings.multiple_choice.modal_title'
133
+ )
134
+ }}</template>
135
+ <template #form="{ on, attrs }">
136
+ <QuestionDialog
137
+ v-bind="attrs"
138
+ v-on="on"
139
+ @saveAndNew="saveAndNewCalled"
140
+ v-model="block.metadata.config.questions[editingIndex]"
141
+ ></QuestionDialog>
142
+ </template>
143
+ </Dialog>
144
+ </v-container>
145
+ </template>
146
+ <script>
147
+ import BaseContentSettings from '~/components/Content/Tool/BaseContentSettings.js'
148
+ import draggable from 'vuedraggable'
149
+ import _ from 'lodash'
150
+ import Dialog from '~/components/Dialog.vue'
151
+ import QuestionDialog from '../content/blocks/multipleChoice/QuestionDialog.vue'
152
+
153
+ export default {
154
+ name: 'MultipleChoiceSettingsManager',
155
+ extends: BaseContentSettings,
156
+ components: { draggable, QuestionDialog, Dialog },
157
+ beforeMount() {
158
+ if (_.isEmpty(this.block)) {
159
+ this.block = {}
160
+ }
161
+ if (_.isEmpty(this.block.metadata)) {
162
+ this.block.metadata = {}
163
+ }
164
+ if (_.isEmpty(this.block.metadata.config)) {
165
+ this.block.metadata.config = {}
166
+ }
167
+ if (_.isEmpty(this.block.metadata.config.title)) {
168
+ this.block.metadata.config.title = ''
169
+ }
170
+ if (_.isEmpty(this.block.metadata.config.instructions)) {
171
+ this.block.metadata.config.instructions = ''
172
+ }
173
+ if (_.isEmpty(this.block.metadata.config.questions)) {
174
+ this.block.metadata.config.questions = []
175
+ }
176
+ },
177
+ data() {
178
+ return {
179
+ cursor: null,
180
+ dialog: false,
181
+ emittedQuestion: {},
182
+ editingIndex: null,
183
+ isNotEditing: false,
184
+ }
185
+ },
186
+ mounted() {
187
+ this.emittedQuestion = {}
188
+ },
189
+ methods: {
190
+ onOpenModal(event, questionIndex = null) {
191
+ //checks if modal is opening to edit or create new
192
+ if (questionIndex !== null) {
193
+ this.editingIndex = questionIndex
194
+ // bound to saveAndNew so if in editing mode cannot keep creating more questions
195
+ // when left the saveAndNew button it was causing errors
196
+ this.isNotEditing = false
197
+ } else {
198
+ this.block.metadata.config.questions.push({
199
+ answer_options: [
200
+ {
201
+ id: 1,
202
+ value: '',
203
+ correctAnswer: true,
204
+ disabled: false,
205
+ },
206
+ {
207
+ id: 2,
208
+ value: '',
209
+ correctAnswer: false,
210
+ disabled: false,
211
+ },
212
+ ],
213
+ body: '',
214
+ hint: '',
215
+ answer_description: '',
216
+ })
217
+ this.editingIndex =
218
+ this.block.metadata.config.questions.length - 1
219
+ // shows saveAndNew button
220
+ this.isNotEditing = true
221
+ }
222
+ this.dialog = true
223
+ },
224
+ saveAndNewCalled() {
225
+ this.block.metadata.config.questions.push({
226
+ answer_options: [
227
+ {
228
+ id: 1,
229
+ value: '',
230
+ correctAnswer: true,
231
+ disabled: false,
232
+ },
233
+ {
234
+ id: 2,
235
+ value: '',
236
+ correctAnswer: false,
237
+ disabled: false,
238
+ },
239
+ ],
240
+ body: '',
241
+ hint: '',
242
+ answer_description: '',
243
+ })
244
+ this.editingIndex = this.block.metadata.config.questions.length - 1
245
+ },
246
+ onHover(index) {
247
+ this.cursor = 'changePointer'
248
+ },
249
+ onHoverLeave() {
250
+ this.cursor = ''
251
+ },
252
+ onDelete(index) {
253
+ this.block.metadata.config.questions.splice(index, 1)
254
+ },
255
+ close() {
256
+ this.dialog = false
257
+ },
258
+ },
259
+ }
260
+ </script>
261
+ <style lang="scss" scoped>
262
+ .cardOutline {
263
+ border: 2px solid var(--v-primary-base);
264
+ margin-bottom: 8px;
265
+ }
266
+ .itemHeight {
267
+ display: flex;
268
+ align-content: center;
269
+ justify-content: space-between;
270
+ height: 60px;
271
+ }
272
+ .v-expansion-panel-content::v-deep .v-expansion-panel-content__wrap {
273
+ padding: 0 !important;
274
+ }
275
+ .seventy {
276
+ width: 70%;
277
+ height: 100%;
278
+ display: flex;
279
+ align-items: center;
280
+ }
281
+ .twenty {
282
+ width: 20%;
283
+ height: 90%;
284
+ margin-top: 3px;
285
+ border-left: 2px solid var(--v-primary);
286
+ }
287
+ .changePointer {
288
+ cursor: pointer !important;
289
+ }
290
+ </style>
@@ -27,7 +27,13 @@
27
27
  <v-expansion-panels flat>
28
28
  <v-expansion-panel>
29
29
  <v-expansion-panel-header class="pa-0"
30
- ><h3>Sortable Items</h3></v-expansion-panel-header
30
+ ><h3>
31
+ {{
32
+ $t(
33
+ 'plugin.games.components.settings.sorting_game.sortable_items'
34
+ )
35
+ }}
36
+ </h3></v-expansion-panel-header
31
37
  >
32
38
  <v-expansion-panel-content class="ma-0">
33
39
  <v-container class="pa-0">
@@ -178,7 +184,6 @@ export default {
178
184
  return {
179
185
  valid: true,
180
186
  dialog: false,
181
- expansionPanelKey: '0',
182
187
  loading: false,
183
188
  headers: [
184
189
  {
@@ -242,7 +247,7 @@ export default {
242
247
  margin: 1rem;
243
248
  }
244
249
  .cardOutline {
245
- border: solid 2px var(--v-primary);
250
+ border: 2px solid var(--v-primary-base);
246
251
  margin-bottom: 8px;
247
252
  }
248
253
  .fullWidth {
@@ -271,7 +276,7 @@ export default {
271
276
  width: 20%;
272
277
  height: 90%;
273
278
  margin-top: 3px;
274
- border-left: 2px solid var(--v-primary);
279
+ border-left: 2px solid var(--v-primary-base);
275
280
  }
276
281
  .addButton {
277
282
  height: 50%;
@@ -280,7 +285,7 @@ export default {
280
285
  .addIcon {
281
286
  margin-right: 5px;
282
287
  }
283
- .v-expansion-panel-content >>> .v-expansion-panel-content__wrap {
288
+ .v-expansion-panel-content::v-deep .v-expansion-panel-content__wrap {
284
289
  padding: 0 !important;
285
290
  }
286
291
  </style>
@@ -0,0 +1,293 @@
1
+ <template>
2
+ <v-container class="pa-0">
3
+ <v-col>
4
+ <v-row>
5
+ <v-text-field
6
+ v-model="block.metadata.config.title"
7
+ :counter="50"
8
+ :label="
9
+ $t(
10
+ 'plugin.games.components.settings.word_jumble.title_input'
11
+ )
12
+ "
13
+ ref="title"
14
+ ></v-text-field>
15
+ <br />
16
+ <v-textarea
17
+ outlined
18
+ auto-grow
19
+ v-model="block.metadata.config.instructions"
20
+ :label="
21
+ $t(
22
+ 'plugin.games.components.settings.word_jumble.instructions'
23
+ )
24
+ "
25
+ ></v-textarea>
26
+ <br />
27
+ </v-row>
28
+ <v-expansion-panels flat>
29
+ <v-expansion-panel>
30
+ <v-expansion-panel-header class="pa-0">
31
+ <h3>
32
+ {{
33
+ $t(
34
+ 'plugin.games.components.content.blocks.word_jumble.title'
35
+ )
36
+ }}
37
+ </h3>
38
+ </v-expansion-panel-header>
39
+ <v-expansion-panel-content class="ma-0">
40
+ <v-container class="pa-0">
41
+ <draggable
42
+ v-model="block.metadata.config.words"
43
+ class="d-flex flex-column mb-6"
44
+ group="cards"
45
+ >
46
+ <v-card
47
+ v-for="(word, index) in block.metadata
48
+ .config.words"
49
+ :key="index"
50
+ class="pa-2 flex-fill cardOutline"
51
+ elevation="0"
52
+ outlined
53
+ tile
54
+ >
55
+ <v-row class="itemHeight">
56
+ <p
57
+ class="text-truncate pa-0 ma-0 seventy"
58
+ @click="onOpenEditor(index)"
59
+ v-on:keyup.enter="
60
+ onOpenEditor(index)
61
+ "
62
+ @mouseover="onHover"
63
+ @mouseleave="onHoverLeave"
64
+ :class="cursor"
65
+ tabindex="0"
66
+ >
67
+ <v-icon class="pl-2"
68
+ >mdi-gesture-tap-hold</v-icon
69
+ >
70
+ {{
71
+ word.value
72
+ ? word.value
73
+ : $t(
74
+ 'plugin.games.components.settings.word_jumble.click'
75
+ )
76
+ }}
77
+ </p>
78
+ <v-icon
79
+ class="twenty"
80
+ @click="onDelete(index)"
81
+ >mdi-delete-outline</v-icon
82
+ >
83
+ </v-row>
84
+ <v-textarea
85
+ v-if="word.expand"
86
+ outlined
87
+ :autofocus="true"
88
+ class="pt-3"
89
+ v-model="
90
+ block.metadata.config.words[index]
91
+ .value
92
+ "
93
+ :label="
94
+ $t(
95
+ 'plugin.games.components.settings.word_jumble.word_jumble'
96
+ )
97
+ "
98
+ ></v-textarea>
99
+ <v-textarea
100
+ v-if="word.expand"
101
+ outlined
102
+ class="pt-3"
103
+ v-model="
104
+ block.metadata.config.words[index]
105
+ .hint
106
+ "
107
+ :label="
108
+ $t(
109
+ 'plugin.games.components.settings.word_jumble.hint'
110
+ )
111
+ "
112
+ ></v-textarea>
113
+ </v-card>
114
+ </draggable>
115
+ <p
116
+ @mouseover="onHover"
117
+ @mouseleave="onHoverLeave"
118
+ @click="onAddWord"
119
+ v-on:keyup.enter="onAddWord"
120
+ class="fullWidth"
121
+ :class="cursor"
122
+ tabindex="0"
123
+ >
124
+ <v-icon class="primary addIcon"
125
+ >mdi-plus</v-icon
126
+ >
127
+ {{
128
+ $t(
129
+ 'plugin.games.components.settings.word_jumble.add'
130
+ )
131
+ }}
132
+ </p>
133
+ </v-container>
134
+ </v-expansion-panel-content>
135
+ </v-expansion-panel>
136
+ </v-expansion-panels>
137
+ <v-row class="mt-3">
138
+ <v-textarea
139
+ v-model="block.metadata.config.feedback_correct"
140
+ outlined
141
+ auto-grow
142
+ :counter="50"
143
+ :label="
144
+ $t(
145
+ 'plugin.games.components.settings.word_jumble.feedback_correct'
146
+ )
147
+ "
148
+ ref="title"
149
+ ></v-textarea>
150
+ <br />
151
+ <v-textarea
152
+ outlined
153
+ auto-grow
154
+ v-model="block.metadata.config.feedback_incorrect"
155
+ :label="
156
+ $t(
157
+ 'plugin.games.components.settings.word_jumble.feedback_incorrect'
158
+ )
159
+ "
160
+ ></v-textarea>
161
+ <br />
162
+ </v-row>
163
+ </v-col>
164
+ </v-container>
165
+ </template>
166
+ <script>
167
+ import _ from 'lodash'
168
+ import BaseContentSettings from '~/components/Content/Tool/BaseContentSettings.js'
169
+ import draggable from 'vuedraggable'
170
+
171
+ export default {
172
+ name: 'WordJumbleSettings',
173
+ extends: BaseContentSettings,
174
+ components: {
175
+ draggable,
176
+ },
177
+ beforeMount() {
178
+ if (_.isEmpty(this.block)) {
179
+ this.block = {}
180
+ }
181
+ if (_.isEmpty(this.block.metadata)) {
182
+ this.block.metadata = {}
183
+ }
184
+ if (_.isEmpty(this.block.metadata.config)) {
185
+ this.block.metadata.config = {}
186
+ }
187
+ if (_.isEmpty(this.block.metadata.config.title)) {
188
+ this.block.metadata.config.title = ''
189
+ }
190
+ if (_.isEmpty(this.block.metadata.config.instructions)) {
191
+ this.block.metadata.config.instructions = ''
192
+ }
193
+ if (_.isEmpty(this.block.metadata.config.feedback_correct)) {
194
+ this.block.metadata.config.feedback_correct = ''
195
+ }
196
+ if (_.isEmpty(this.block.metadata.config.feedback_incorrect)) {
197
+ this.block.metadata.config.feedback_incorrect = ''
198
+ }
199
+ if (_.isEmpty(this.block.metadata.config.words)) {
200
+ this.block.metadata.config.words = []
201
+ this.onAddWord()
202
+ }
203
+ },
204
+ data() {
205
+ return {
206
+ debounce: null,
207
+ cursor: null,
208
+ }
209
+ },
210
+ methods: {
211
+ onAddWord() {
212
+ let defaultWord = {
213
+ id: this.block.metadata.config.words.length + 1,
214
+ value: '',
215
+ hint: '',
216
+ expand: false,
217
+ }
218
+ this.block.metadata.config.words.push(defaultWord)
219
+ },
220
+ onDelete(index) {
221
+ let startingIndex = 0
222
+ this.block.metadata.config.words.splice(index, 1)
223
+ this.block.metadata.config.words.forEach((element) => {
224
+ startingIndex = startingIndex + 1
225
+ return (element.id = startingIndex)
226
+ })
227
+ },
228
+ onOpenEditor(index) {
229
+ // expands editing area of clicked upon word jumble
230
+ this.block.metadata.config.words[index].expand =
231
+ !this.block.metadata.config.words[index].expand
232
+ this.block.metadata.config.words.forEach((element) => {
233
+ if (index + 1 !== element.id) {
234
+ element.expand = false
235
+ }
236
+ })
237
+ },
238
+ onHover(index) {
239
+ this.cursor = 'changePointer'
240
+ },
241
+ onHoverLeave() {
242
+ this.cursor = ''
243
+ },
244
+ },
245
+ }
246
+ </script>
247
+ <style lang="scss" scoped>
248
+ .v-progress-circular {
249
+ margin: 1rem;
250
+ }
251
+ .cardOutline {
252
+ border: 2px solid var(--v-primary-base);
253
+ margin-bottom: 8px;
254
+ }
255
+ .fullWidth {
256
+ display: flex;
257
+ justify-content: center;
258
+ align-items: center;
259
+ font-weight: bold;
260
+ font-size: 16px;
261
+ }
262
+ .itemHeight {
263
+ display: flex;
264
+ align-content: center;
265
+ justify-content: space-between;
266
+ height: 60px;
267
+ }
268
+ .changePointer {
269
+ cursor: pointer !important;
270
+ }
271
+ .seventy {
272
+ width: 70%;
273
+ height: 100%;
274
+ display: flex;
275
+ align-items: center;
276
+ }
277
+ .twenty {
278
+ width: 20%;
279
+ height: 90%;
280
+ margin-top: 3px;
281
+ border-left: 2px solid var(--v-primary-base);
282
+ }
283
+ .addButton {
284
+ height: 50%;
285
+ width: 50%;
286
+ }
287
+ .addIcon {
288
+ margin-right: 5px;
289
+ }
290
+ .v-expansion-panel-content::v-deep .v-expansion-panel-content__wrap {
291
+ padding: 0 !important;
292
+ }
293
+ </style>
@@ -4,6 +4,8 @@ import flashcard from './flashcard'
4
4
  import matching_game from './matching_game'
5
5
  import quizshow_game from './quizshow_game'
6
6
  import slideshow from './slideshow'
7
+ import multiple_choice from './multiple_choice'
8
+ import word_jumble from './word_jumble'
7
9
 
8
10
  export default {
9
11
  bucket_game,
@@ -12,4 +14,6 @@ export default {
12
14
  matching_game,
13
15
  quizshow_game,
14
16
  slideshow,
17
+ multiple_choice,
18
+ word_jumble,
15
19
  }
@@ -22,5 +22,5 @@ export default {
22
22
  terms: 'Terms',
23
23
  prompts: 'Prompts',
24
24
  click_here: 'Click here to enter text',
25
- image: 'Image'
25
+ image: 'Image',
26
26
  }
@@ -0,0 +1,11 @@
1
+ export default {
2
+ game_title: 'Multiple Choice Game',
3
+ hint: 'View/Reset Hint',
4
+ fifty: '50:50',
5
+ print: 'View Print Version',
6
+ reset: 'Reset Game',
7
+ hint_title: 'Hint',
8
+ answer_description: 'Answer Description',
9
+ total_points: 'Total Points for Course',
10
+ out_of: ' out of ',
11
+ }
@@ -0,0 +1,9 @@
1
+ export default {
2
+ title: 'Word Jumble',
3
+ clue: 'Clue: ',
4
+ check: 'Check Answer',
5
+ reveal: 'Reveal Answer',
6
+ correct: 'That is correct!',
7
+ incorrect: 'That is incorrect',
8
+ feedback: 'Feedback here',
9
+ }