@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
package/.editorconfig ADDED
@@ -0,0 +1,13 @@
1
+ # editorconfig.org
2
+ root = true
3
+
4
+ [*]
5
+ indent_style = space
6
+ indent_size = 4
7
+ end_of_line = lf
8
+ charset = utf-8
9
+ trim_trailing_whitespace = true
10
+ insert_final_newline = true
11
+
12
+ [*.md]
13
+ trim_trailing_whitespace = false
package/.eslintrc.js ADDED
@@ -0,0 +1,11 @@
1
+ module.exports = {
2
+ root: true,
3
+ env: {
4
+ browser: true,
5
+ node: true,
6
+ },
7
+ extends: ['plugin:nuxt/recommended', 'plugin:prettier/recommended'],
8
+ plugins: [],
9
+ // add your custom rules here
10
+ rules: {},
11
+ }
package/.prettierrc ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "semi": false,
3
+ "singleQuote": true
4
+ }
package/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # Windward UI Plugin Library
2
+
3
+ Windward game plugin implements components and models required for windward games
4
+
5
+ ## Getting Started Locally with npm
6
+
7
+ **Software Requirements**:
8
+
9
+ - Node v16+, npm v8+
10
+
11
+ Clone the windward-ui-plugin-games repository
12
+
13
+ ```
14
+ $ cd windward-ui-plugin-games
15
+ $ npm install
16
+ $ npm link
17
+ ```
18
+
19
+ Clone the windward-ui repository and follow README to setup
20
+
21
+ Link to Windward ui repo
22
+
23
+ ```
24
+ $ cd windward-ui
25
+ $ npm install
26
+ $ cd node_modules
27
+ $ npm link @mindedge/windward-ui-plugin-games
28
+ $ npm run dev
29
+ ```
30
+
31
+ Your Repos are linked at this point and you are ready to start developing windward plugins
32
+
33
+ ## Code of Conduct
34
+
35
+ In order to ensure that the Windward community is welcoming to all we follow the same code of conduct as [Laravel](https://laravel.com/docs/contributions#code-of-conduct).
36
+
37
+ ## Security Vulnerabilities
38
+
39
+ If you discover a security vulnerability within Windward, please create a ticket on this repository and tag it as "security"
40
+
41
+ ## License
42
+
43
+ Windward LMS is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
@@ -0,0 +1 @@
1
+ module.exports = { presets: ["@babel/preset-env"] };
@@ -0,0 +1,295 @@
1
+ <template>
2
+ <div>
3
+ <v-data-table
4
+ :headers="tableHeaders"
5
+ :items="items"
6
+ sort-by="calories"
7
+ class="elevation-1"
8
+ >
9
+ <template #top>
10
+ <v-toolbar flat>
11
+ <v-toolbar-title> {{ title }}</v-toolbar-title>
12
+ <v-divider class="mx-4" inset vertical></v-divider>
13
+ <v-spacer></v-spacer>
14
+ <v-btn color="primary" dark class="mb-2" @click="addNew">
15
+ {{
16
+ $t(
17
+ 'plugin.games.components.content.crud_table.add_row'
18
+ )
19
+ }}
20
+ </v-btn>
21
+ &nbsp;
22
+ <v-dialog
23
+ v-model="dialog"
24
+ max-width="500px"
25
+ v-if="useModal"
26
+ >
27
+ <template #activator="{ on, attrs }">
28
+ <v-btn
29
+ color="primary"
30
+ dark
31
+ class="mb-2"
32
+ v-bind="attrs"
33
+ v-on="on"
34
+ >
35
+ {{
36
+ $t(
37
+ 'plugin.games.components.content.crud_table.new_item'
38
+ )
39
+ }}
40
+ </v-btn>
41
+ </template>
42
+ <v-card>
43
+ <v-card-title>
44
+ <span class="text-h5">{{ formTitle }}</span>
45
+ </v-card-title>
46
+
47
+ <v-card-text>
48
+ <v-container>
49
+ <v-row>
50
+ <v-col
51
+ v-for="(header, index) in headers"
52
+ :key="index"
53
+ cols="12"
54
+ sm="6"
55
+ md="4"
56
+ >
57
+ <v-text-field
58
+ v-model="
59
+ editedItem[
60
+ headers[index].value
61
+ ]
62
+ "
63
+ :label="headers[index].text"
64
+ ></v-text-field>
65
+ </v-col>
66
+ </v-row>
67
+ </v-container>
68
+ </v-card-text>
69
+
70
+ <v-card-actions>
71
+ <v-spacer></v-spacer>
72
+ <v-btn
73
+ color="blue darken-1"
74
+ text
75
+ @click="close"
76
+ >
77
+ {{ $t('shared.forms.cancel') }}
78
+ </v-btn>
79
+ <v-btn color="blue darken-1" text @click="save">
80
+ {{ $t('shared.forms.save') }}
81
+ </v-btn>
82
+ </v-card-actions>
83
+ </v-card>
84
+ </v-dialog>
85
+ <v-dialog v-model="dialogDelete" max-width="500px">
86
+ <v-card>
87
+ <v-card-title class="text-h5">
88
+ {{ $t('shared.forms.confirm_delete_text') }}
89
+ </v-card-title>
90
+ <v-card-actions>
91
+ <v-spacer></v-spacer>
92
+ <v-btn
93
+ color="blue darken-1"
94
+ text
95
+ @click="closeDelete"
96
+ >{{ $t('shared.forms.cancel') }}
97
+ </v-btn>
98
+ <v-btn
99
+ color="blue darken-1"
100
+ text
101
+ @click="deleteItemConfirm"
102
+ >{{ $t('shared.forms.confirm') }}
103
+ </v-btn>
104
+ <v-spacer></v-spacer>
105
+ </v-card-actions>
106
+ </v-card>
107
+ </v-dialog>
108
+ </v-toolbar>
109
+ </template>
110
+
111
+ <template #body="props">
112
+ <draggable
113
+ v-model="items"
114
+ tag="tbody"
115
+ :disabled="!allowDrag"
116
+ :move="onMoveCallback"
117
+ :clone="onCloneCallback"
118
+ @end="onDropCallback"
119
+ >
120
+ <DataTableRowHandler
121
+ v-model="editedItem"
122
+ v-for="(item, index) in props.items"
123
+ :editedItemId="editedItem.id"
124
+ :headers="tableHeaders"
125
+ :key="index"
126
+ :item="item"
127
+ @input="onDropCallback"
128
+ >
129
+ <template #item.actions="{ item }">
130
+ <v-btn outlined v-if="useModal">
131
+ <span class="sr-only">
132
+ {{ $t('shared.forms.edit') }}</span
133
+ >
134
+ <v-icon
135
+ small
136
+ class="mr-2"
137
+ @click="editItem(item)"
138
+ >
139
+ mdi-pencil
140
+ </v-icon>
141
+ </v-btn>
142
+ <v-btn outlined>
143
+ <span class="sr-only">
144
+ {{ $t('shared.forms.delete') }}</span
145
+ >
146
+ <v-icon small @click="deleteItem(item)">
147
+ mdi-delete
148
+ </v-icon>
149
+ </v-btn>
150
+ </template>
151
+ <template #no-data>
152
+ <div>{{ $t('shared.forms.no_data') }}</div>
153
+ </template>
154
+ </DataTableRowHandler>
155
+ </draggable>
156
+ </template>
157
+ </v-data-table>
158
+ <slot></slot>
159
+ </div>
160
+ </template>
161
+
162
+ <script>
163
+ import draggable from 'vuedraggable'
164
+ import DataTableRowHandler from './DataTableRowHandler'
165
+ import _ from 'lodash'
166
+ export default {
167
+ components: { DataTableRowHandler, draggable },
168
+ props: {
169
+ title: { type: String, required: false, default: 'CRUD' },
170
+ headers: { type: Array, required: true, default: [] },
171
+ defaultItem: { type: Object, required: true, default: {} },
172
+ allowDrag: { type: Boolean, required: false, default: false },
173
+ useModal: { type: Boolean, required: false, default: false },
174
+ data: { type: Array, required: true, default: [] },
175
+ maxItems: { type: Number, required: false, default: null },
176
+ },
177
+ data: () => ({
178
+ dialog: false,
179
+ dialogDelete: false,
180
+ items: [],
181
+ editedIndex: -1,
182
+ editedItem: {},
183
+ }),
184
+
185
+ computed: {
186
+ formTitle() {
187
+ return this.editedIndex === -1 ? 'New Item' : 'Edit Item'
188
+ },
189
+ tableHeaders() {
190
+ let new_headers = JSON.parse(JSON.stringify(this.headers))
191
+ new_headers.push({
192
+ text: 'Actions',
193
+ value: 'actions',
194
+ sortable: false,
195
+ })
196
+ return new_headers
197
+ },
198
+ },
199
+
200
+ watch: {
201
+ dialog(val) {
202
+ val || this.close()
203
+ },
204
+ dialogDelete(val) {
205
+ val || this.closeDelete()
206
+ },
207
+ },
208
+ mounted() {
209
+ this.items = _.cloneDeep(this.data)
210
+ this.editedItem = _.cloneDeep(this.defaultItem)
211
+ },
212
+ created() {},
213
+
214
+ methods: {
215
+ editItem(item) {
216
+ this.editedIndex = this.items.indexOf(item)
217
+ this.editedItem = Object.assign({}, item)
218
+ this.dialog = true
219
+ },
220
+
221
+ deleteItem(item) {
222
+ this.editedIndex = this.items.indexOf(item)
223
+ this.editedItem = Object.assign({}, item)
224
+ this.dialogDelete = true
225
+ },
226
+
227
+ deleteItemConfirm() {
228
+ this.items.splice(this.editedIndex, 1)
229
+ this.data.splice(this.editedIndex, 1)
230
+ this.closeDelete()
231
+ },
232
+ addNew() {
233
+ if (this.maxItems && this.maxItems > this.items.length) {
234
+ const addObj = _.cloneDeep(this.defaultItem)
235
+ addObj.id = this.items.length + 1
236
+ this.items.push(addObj)
237
+ this.$emit('input', this.items)
238
+ }
239
+
240
+ if (this.maxItems === null) {
241
+ const addObj = _.cloneDeep(this.defaultItem)
242
+ addObj.id = this.items.length + 1
243
+ this.items.push(addObj)
244
+ this.$emit('input', this.items)
245
+ }
246
+ },
247
+
248
+ close() {
249
+ this.dialog = false
250
+ this.$nextTick(() => {
251
+ this.editedItem = Object.assign({}, this.defaultItem)
252
+ this.editedIndex = -1
253
+ })
254
+ },
255
+
256
+ closeDelete() {
257
+ this.dialogDelete = false
258
+ this.$nextTick(() => {
259
+ this.editedItem = Object.assign({}, this.defaultItem)
260
+ this.editedIndex = -1
261
+ })
262
+ },
263
+
264
+ save() {
265
+ if (this.editedIndex > -1) {
266
+ Object.assign(this.items[this.editedIndex], this.editedItem)
267
+ } else {
268
+ this.items.push(this.editedItem)
269
+ }
270
+ this.$emit('input', this.items)
271
+ this.close()
272
+ },
273
+ onCloneCallback(item) {
274
+ // Create a fresh copy of item
275
+ const cloneMe = JSON.parse(JSON.stringify(item))
276
+ return cloneMe
277
+ },
278
+ onMoveCallback(evt, originalEvent) {
279
+ const item = evt.draggedContext.element
280
+ const itemIdx = evt.draggedContext.futureIndex
281
+
282
+ if (item.locked) {
283
+ return false
284
+ }
285
+
286
+ return true
287
+ },
288
+ onDropCallback(evt, originalEvent) {
289
+ this.$emit('input', this.items)
290
+ },
291
+ },
292
+ }
293
+ </script>
294
+
295
+ <style scoped></style>
@@ -0,0 +1,113 @@
1
+ <template>
2
+ <tr>
3
+ <td v-for="(header, index) in headers" :key="index">
4
+ <slot :item="item" :name="columnName(header)">
5
+ <div :style="getAlignment(header)">
6
+ <div>
7
+ <v-color-picker
8
+ v-if="header.type === 'color_picker'"
9
+ v-model="item[header.value]"
10
+ class="ma-2"
11
+ hide-inputs
12
+ ></v-color-picker>
13
+ <v-select
14
+ v-if="header.type === 'select'"
15
+ v-model="item[header.value]"
16
+ :items="header.options"
17
+ :hide-details="true"
18
+ dense
19
+ outlined
20
+ :autofocus="true"
21
+ :label="header.value"
22
+ @input="change"
23
+ >
24
+ </v-select>
25
+ <v-textarea
26
+ v-if="header.type === 'text_area'"
27
+ v-model="item[header.value]"
28
+ :hide-details="true"
29
+ dense
30
+ outlined
31
+ :autofocus="true"
32
+ :label="header.value"
33
+ @input="change"
34
+ >
35
+ <v-icon v-if="header.draggable" slot="prepend"
36
+ >mdi-drag-vertical</v-icon
37
+ >
38
+ </v-textarea>
39
+ <v-text-field
40
+ v-if="!header.type"
41
+ v-model="item[header.value]"
42
+ :hide-details="true"
43
+ dense
44
+ outlined
45
+ :autofocus="true"
46
+ :label="header.value"
47
+ @input="change"
48
+ >
49
+ <v-icon v-if="header.draggable" slot="prepend"
50
+ >mdi-drag-vertical</v-icon
51
+ >
52
+ </v-text-field>
53
+ </div>
54
+ </div>
55
+ </slot>
56
+ </td>
57
+ </tr>
58
+ </template>
59
+
60
+ <script>
61
+ export default {
62
+ name: 'DataTableRowHandler',
63
+ components: {},
64
+ props: {
65
+ itemClass: {
66
+ type: String,
67
+ default: '',
68
+ },
69
+ item: {
70
+ type: Object,
71
+ default: () => {
72
+ return {}
73
+ },
74
+ },
75
+ headers: {
76
+ type: Array,
77
+ default: () => {
78
+ return []
79
+ },
80
+ },
81
+ },
82
+ data() {
83
+ return {}
84
+ },
85
+ computed: {
86
+ getClass() {
87
+ return this.itemClass
88
+ },
89
+ },
90
+ methods: {
91
+ columnName(header) {
92
+ return `item.${header.value}`
93
+ },
94
+ getAlignment(header) {
95
+ const align = header.align ? header.align : 'left'
96
+ return `text-align: ${align}`
97
+ },
98
+ getNonSlotValue(item, header) {
99
+ console.log(item, header)
100
+ const val = item[header.value]
101
+
102
+ if (val) {
103
+ return val
104
+ }
105
+
106
+ return ''
107
+ },
108
+ change(e) {
109
+ this.$emit('input', this.item)
110
+ },
111
+ },
112
+ }
113
+ </script>