@windward/core 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 (113) hide show
  1. package/.editorconfig +13 -0
  2. package/.eslintrc.js +11 -0
  3. package/.prettierrc +4 -0
  4. package/README.md +86 -0
  5. package/babel.config.js +1 -0
  6. package/components/Content/Blocks/Accordion.vue +133 -0
  7. package/components/Content/Blocks/ClickableIcons.vue +98 -0
  8. package/components/Content/Blocks/Feedback.vue +323 -0
  9. package/components/Content/Blocks/FeedbackTemplates/FeedbackQuestionLikert.vue +95 -0
  10. package/components/Content/Blocks/FeedbackTemplates/FeedbackQuestionOpenResponse.vue +45 -0
  11. package/components/Content/Blocks/FeedbackTemplates/FeedbackQuestionTrueFalse.vue +55 -0
  12. package/components/Content/Blocks/Image.vue +116 -0
  13. package/components/Content/Blocks/Math.vue +87 -0
  14. package/components/Content/Blocks/Tab.vue +89 -0
  15. package/components/Content/Blocks/Table.vue +68 -0
  16. package/components/Content/Blocks/UserUpload/DisplayUserFilesTable.vue +157 -0
  17. package/components/Content/Blocks/UserUpload/ManageDataTableUserFiles.vue +68 -0
  18. package/components/Content/Blocks/UserUpload.vue +240 -0
  19. package/components/Content/Blocks/Video.vue +245 -0
  20. package/components/Navigation/Items/CourseGlossaryToolNav.vue +39 -0
  21. package/components/Navigation/Items/GlossaryNav.vue +32 -0
  22. package/components/Navigation/Items/UserUploadNav.vue +35 -0
  23. package/components/Settings/AccordionSettings.vue +153 -0
  24. package/components/Settings/ClickableIconsSettings.vue +189 -0
  25. package/components/Settings/FeedbackSettings.vue +92 -0
  26. package/components/Settings/ImageSettings.vue +124 -0
  27. package/components/Settings/MathSettings.vue +81 -0
  28. package/components/Settings/TabSettings.vue +139 -0
  29. package/components/Settings/TextEditorSettings.vue +249 -0
  30. package/components/Settings/UserUploadSettings.vue +151 -0
  31. package/components/Settings/VideoSettings.vue +699 -0
  32. package/components/utils/ContentViewer.vue +69 -0
  33. package/components/utils/MathExpressionEditor.vue +294 -0
  34. package/components/utils/MathLiveWrapper.vue +86 -0
  35. package/components/utils/TinyMCEWrapper.vue +103 -0
  36. package/components/utils/glossary/CourseGlossary.vue +284 -0
  37. package/components/utils/glossary/CourseGlossaryForm.vue +106 -0
  38. package/components/utils/glossary/GlossaryToolTip.vue +87 -0
  39. package/config/tinymce.config.js +136 -0
  40. package/helpers/GlossaryHelper.ts +137 -0
  41. package/helpers/GlossaryTerm.ts +31 -0
  42. package/helpers/MathHelper.ts +236 -0
  43. package/helpers/tinymce/plugin.ts +83 -0
  44. package/i18n/en-US/components/content/blocks/feedback.ts +28 -0
  45. package/i18n/en-US/components/content/blocks/image.ts +5 -0
  46. package/i18n/en-US/components/content/blocks/index.ts +15 -0
  47. package/i18n/en-US/components/content/blocks/tab.ts +4 -0
  48. package/i18n/en-US/components/content/blocks/table.ts +4 -0
  49. package/i18n/en-US/components/content/blocks/user_upload.ts +12 -0
  50. package/i18n/en-US/components/content/blocks/video.ts +53 -0
  51. package/i18n/en-US/components/content/index.ts +5 -0
  52. package/i18n/en-US/components/index.ts +12 -0
  53. package/i18n/en-US/components/navigation/image.ts +4 -0
  54. package/i18n/en-US/components/navigation/index.ts +7 -0
  55. package/i18n/en-US/components/navigation/user_upload.ts +3 -0
  56. package/i18n/en-US/components/settings/clickable_icon.ts +9 -0
  57. package/i18n/en-US/components/settings/image.ts +1 -0
  58. package/i18n/en-US/components/settings/index.ts +13 -0
  59. package/i18n/en-US/components/settings/text_editor.ts +7 -0
  60. package/i18n/en-US/components/settings/user_upload.ts +11 -0
  61. package/i18n/en-US/components/settings/video.ts +13 -0
  62. package/i18n/en-US/components/utils/index.ts +5 -0
  63. package/i18n/en-US/components/utils/tiny_mce_wrapper.ts +7 -0
  64. package/i18n/en-US/index.ts +16 -0
  65. package/i18n/en-US/modules/index.ts +5 -0
  66. package/i18n/en-US/pages/glossary.ts +7 -0
  67. package/i18n/en-US/pages/index.ts +7 -0
  68. package/i18n/en-US/pages/user_upload.ts +3 -0
  69. package/i18n/en-US/shared/content_blocks.ts +20 -0
  70. package/i18n/en-US/shared/index.ts +11 -0
  71. package/i18n/en-US/shared/menu.ts +3 -0
  72. package/i18n/en-US/shared/permission.ts +15 -0
  73. package/i18n/en-US/shared/settings.ts +15 -0
  74. package/index.js +15 -0
  75. package/jest.config.js +15 -0
  76. package/models/SurveyResult.ts +8 -0
  77. package/models/SurveyTemplate.ts +8 -0
  78. package/models/UserFileAsset.ts +12 -0
  79. package/package.json +48 -0
  80. package/pages/glossary.vue +31 -0
  81. package/pages/userUpload.vue +204 -0
  82. package/plugin.js +299 -0
  83. package/test/Components/Content/Blocks/Accordion.spec.js +21 -0
  84. package/test/Components/Content/Blocks/ClickableIcons.spec.js +21 -0
  85. package/test/Components/Content/Blocks/Feedback.spec.js +31 -0
  86. package/test/Components/Content/Blocks/FeedbackTemplates/FeedbackQuestionLikert.spec.js +23 -0
  87. package/test/Components/Content/Blocks/FeedbackTemplates/FeedbackQuestionOpenResponse.spec.js +23 -0
  88. package/test/Components/Content/Blocks/FeedbackTemplates/FeedbackQuestionTrueFalse.spec.js +23 -0
  89. package/test/Components/Content/Blocks/Image.spec.js +34 -0
  90. package/test/Components/Content/Blocks/Math.spec.js +34 -0
  91. package/test/Components/Content/Blocks/Tab.spec.js +20 -0
  92. package/test/Components/Content/Blocks/Table.spec.js +21 -0
  93. package/test/Components/Content/Blocks/UserUpload.spec.js +25 -0
  94. package/test/Components/Content/Blocks/Video.spec.js +112 -0
  95. package/test/Components/Settings/AccordionSettings.spec.js +45 -0
  96. package/test/Components/Settings/ClickableIconsSettings.spec.js +20 -0
  97. package/test/Components/Settings/FeedbackSettings.spec.js +20 -0
  98. package/test/Components/Settings/ImageSettings.spec.js +20 -0
  99. package/test/Components/Settings/MathSettings.spec.js +20 -0
  100. package/test/Components/Settings/TabSettings.spec.js +45 -0
  101. package/test/Components/Settings/UserUploadSettings.spec.js +20 -0
  102. package/test/__mocks__/componentsMock.js +83 -0
  103. package/test/__mocks__/contentBlockMock.js +119 -0
  104. package/test/__mocks__/contentSettingsMock.js +54 -0
  105. package/test/__mocks__/fileMock.js +1 -0
  106. package/test/__mocks__/helpersMock.js +53 -0
  107. package/test/__mocks__/modelMock.js +82 -0
  108. package/test/__mocks__/styleMock.js +1 -0
  109. package/test/helpers/GlossaryHelper.spec.js +227 -0
  110. package/test/helpers/MathHelper.spec.js +128 -0
  111. package/test/mocks.js +140 -0
  112. package/tsconfig.json +15 -0
  113. package/utils/index.js +18 -0
@@ -0,0 +1,7 @@
1
+ export default {
2
+ glossary: 'Glossary',
3
+ Text_editor: 'Editor',
4
+ verified_terms: 'verified terms',
5
+ unverified_terms: 'unverified terms',
6
+ no_glossary: 'No glossary Terms detected',
7
+ }
@@ -0,0 +1,11 @@
1
+ export default {
2
+ accept_multiple: 'Multiple Files',
3
+ accept_types: 'Allowed File Types',
4
+ types: {
5
+ all: 'All File Types',
6
+ all_image: 'Images - .jpg, .png, .gif',
7
+ all_word: 'Documents - .doc and .docx',
8
+ all_excel: 'Spreadsheets - .xls and .xlsx',
9
+ all_zip: 'Compressed - .zip',
10
+ },
11
+ }
@@ -0,0 +1,13 @@
1
+ export default {
2
+ title: 'Video Title',
3
+ sources: 'Sources',
4
+ playback: 'Playback',
5
+ no_sources: 'No Sources Configured',
6
+ default_filename: 'Video',
7
+ playlist: 'Videos in Playlist',
8
+ playlist_name: 'Name in Playlist',
9
+ playlist_name_source_required:
10
+ 'Select a source before naming this playlist item',
11
+ playlist_add: 'Add a playlist item',
12
+ playlist_remove: 'Remove this playlist item',
13
+ }
@@ -0,0 +1,5 @@
1
+ import tiny_mce_wrapper from './tiny_mce_wrapper'
2
+
3
+ export default {
4
+ tiny_mce_wrapper,
5
+ }
@@ -0,0 +1,7 @@
1
+ export default {
2
+ glossary: 'Glossary',
3
+ term: 'Glossary Term',
4
+ alternate_forms: 'Alternate Forms',
5
+ definition: 'definition',
6
+ related_terms: 'related terms',
7
+ }
@@ -0,0 +1,16 @@
1
+ import pages from './pages/index'
2
+ import components from './components/index'
3
+ import shared from './shared/index'
4
+ import modules from './modules/index'
5
+
6
+ export default {
7
+ windward: {
8
+ core: {
9
+ name: 'Windward Core',
10
+ pages,
11
+ components,
12
+ shared,
13
+ modules,
14
+ },
15
+ },
16
+ }
@@ -0,0 +1,5 @@
1
+ // import example from './example'
2
+
3
+ export default {
4
+ // example,
5
+ }
@@ -0,0 +1,7 @@
1
+ export default {
2
+ title: 'Course Glossary',
3
+ term: 'Term',
4
+ related_term: 'Related Term',
5
+ definition: 'definition',
6
+ alternate_forms: 'Alternate Forms',
7
+ }
@@ -0,0 +1,7 @@
1
+ import user_upload from './user_upload'
2
+ import glossary from './glossary'
3
+
4
+ export default {
5
+ user_upload,
6
+ glossary,
7
+ }
@@ -0,0 +1,3 @@
1
+ export default {
2
+ title: 'User Upload Overview',
3
+ }
@@ -0,0 +1,20 @@
1
+ export default {
2
+ title: {
3
+ assessment: 'Assessment',
4
+ video: 'Video / Audio',
5
+ default_table: 'Default Table',
6
+ tab: 'Tab',
7
+ rich_text: 'Rich Text',
8
+ math: 'Math',
9
+ accordion: 'Accordion',
10
+ image: 'Image',
11
+ user_upload: 'User Upload',
12
+ clickable_icons: 'Clickable Icons',
13
+ feedback: 'Feedback',
14
+ },
15
+ grouping: {
16
+ basic: 'Basic Components',
17
+ multimedia: 'Multimedia Files',
18
+ placeholder: 'Enter text here',
19
+ },
20
+ }
@@ -0,0 +1,11 @@
1
+ import content_blocks from './content_blocks'
2
+ import settings from './settings'
3
+ import menu from './menu'
4
+ import permission from './permission'
5
+
6
+ export default {
7
+ content_blocks,
8
+ settings,
9
+ menu,
10
+ permission,
11
+ }
@@ -0,0 +1,3 @@
1
+ export default {
2
+ course_glossary: 'Course Glossary',
3
+ }
@@ -0,0 +1,15 @@
1
+ export default {
2
+ type_title: {
3
+ 'plugin->windward->core->organization->course->user->feedback':
4
+ 'Feedback access for the current user',
5
+ 'plugin->windward->core->organization->course->user->userUpload':
6
+ 'User upload block access for the current user',
7
+ },
8
+
9
+ type_description: {
10
+ 'plugin->windward->core->organization->course->user->feedback':
11
+ 'The current users access to the feedback block',
12
+ 'plugin->windward->core->organization->course->user->userUpload':
13
+ 'The current users access to the user upload block',
14
+ },
15
+ }
@@ -0,0 +1,15 @@
1
+ export default {
2
+ title: {
3
+ assessment: 'Assessment Settings',
4
+ image: 'Image Settings',
5
+ user_upload: 'User Upload Settings',
6
+ tab_settings: 'Tab Settings',
7
+ text_editor: 'Text Editor Settings',
8
+ clickable_icons: 'Clickable Icons Settings',
9
+ accordion: 'Accordion Settings',
10
+ video: 'Video Settings',
11
+ table: 'Table Settings',
12
+ math: 'Math Settings',
13
+ feedback: 'Feedback Settings'
14
+ },
15
+ }
package/index.js ADDED
@@ -0,0 +1,15 @@
1
+ // Entrypoint for npm
2
+ import MathHelper from './helpers/MathHelper'
3
+
4
+ import ContentViewer from './components/utils/ContentViewer.vue'
5
+ import MathExpressionEditor from './components/utils/MathExpressionEditor.vue'
6
+ import MathLiveWrapper from './components/utils/MathLiveWrapper.vue'
7
+ import TinyMCEWrapper from './components/utils/TinyMCEWrapper.vue'
8
+
9
+ export {
10
+ MathHelper,
11
+ ContentViewer,
12
+ MathExpressionEditor,
13
+ MathLiveWrapper,
14
+ TinyMCEWrapper,
15
+ }
package/jest.config.js ADDED
@@ -0,0 +1,15 @@
1
+ module.exports = {
2
+ moduleNameMapper: {
3
+ '^@/(.*)$': '<rootDir>/$1',
4
+ '^vue$': 'vue/dist/vue.common.js',
5
+ '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
6
+ '<rootDir>/test/__mocks__/fileMock.js',
7
+ '\\.(css|less)$': '<rootDir>/test/__mocks__/styleMock.js',
8
+ },
9
+ moduleFileExtensions: ['ts', 'js', 'vue', 'json'],
10
+ transform: {
11
+ '^.+\\.ts$': 'ts-jest',
12
+ '^.+\\.js$': 'babel-jest',
13
+ '.*\\.(vue)$': 'vue-jest',
14
+ },
15
+ }
@@ -0,0 +1,8 @@
1
+ // @ts-ignore
2
+ import Model from '~/models/Model'
3
+
4
+ export default class SurveyResult extends Model {
5
+ resource() {
6
+ return 'feedback'
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ // @ts-ignore
2
+ import Model from '~/models/Model'
3
+
4
+ export default class SurveyTemplate extends Model {
5
+ resource() {
6
+ return 'feedback/templates'
7
+ }
8
+ }
@@ -0,0 +1,12 @@
1
+ import Model from '~/models/Model'
2
+
3
+ export default class UserFileAsset extends Model {
4
+ get required(): string[] {
5
+ return []
6
+ }
7
+
8
+ // Set the resource route of the model
9
+ resource() {
10
+ return 'user-files'
11
+ }
12
+ }
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@windward/core",
3
+ "version": "0.0.1",
4
+ "description": "Windward UI Core Plugins",
5
+ "main": "plugin.js",
6
+ "scripts": {
7
+ "test": "jest",
8
+ "lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .",
9
+ "build": "vue-cli-service build --target lib --name WindwardUIPluginCore plugin.js"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+ssh://git@bitbucket.org/mindedge/windward-ui-plugin-core.git"
14
+ },
15
+ "author": "Jacob Rogaishio",
16
+ "license": "MIT",
17
+ "homepage": "https://bitbucket.org/mindedge/windward-ui-plugin-core#readme",
18
+ "dependencies": {
19
+ "@mindedge/vuetify-player": "^0.2.0",
20
+ "@tinymce/tinymce-vue": "^3.2.8",
21
+ "eslint": "^8.11.0",
22
+ "lodash": "^4.17.21",
23
+ "mathlive": "^0.73.7",
24
+ "mathml-to-latex": "^1.2.0",
25
+ "prettier": "^2.6.0"
26
+ },
27
+ "devDependencies": {
28
+ "@babel/preset-env": "^7.16.11",
29
+ "@nuxtjs/axios": "^5.13.6",
30
+ "@types/lodash": "^4.14.180",
31
+ "@vue/cli-plugin-babel": "^5.0.4",
32
+ "@vue/cli-plugin-typescript": "^5.0.4",
33
+ "@vue/cli-service": "^5.0.4",
34
+ "@vue/test-utils": "^1.1.3",
35
+ "babel-core": "^7.0.0-bridge.0",
36
+ "babel-jest": "^26.6.3",
37
+ "eslint-config-prettier": "^8.5.0",
38
+ "eslint-plugin-nuxt": "^3.2.0",
39
+ "eslint-plugin-prettier": "^4.0.0",
40
+ "jest": "^26.6.3",
41
+ "ts-jest": "^26.5.6",
42
+ "typescript": "^4.6.3",
43
+ "vue": "^2.6.14",
44
+ "vue-api-query": "^1.11.0",
45
+ "vue-jest": "^3.0.7",
46
+ "vuetify": "^2.6.4"
47
+ }
48
+ }
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <v-row justify="center" align="center">
3
+ <v-col cols="10">
4
+ <div class="d-flex mb-5">
5
+ <h1 class="mr-auto flex-grow-1">
6
+ {{ $t('windward.core.pages.glossary.title') }}
7
+ </h1>
8
+ </div>
9
+
10
+ <v-spacer class="mt-5 mb-5" />
11
+ <CourseGlossary />
12
+ </v-col>
13
+ </v-row>
14
+ </template>
15
+
16
+ <script>
17
+ import { CourseGlossary } from '../utils/index'
18
+ export default {
19
+ name: 'Glossary',
20
+ middleware: ['auth', 'privilege'],
21
+ components: { CourseGlossary },
22
+ layout: 'authenticated',
23
+ meta: {
24
+ privilege: {
25
+ 'windward.organization.course.contentBlock': {
26
+ readable: true,
27
+ },
28
+ },
29
+ },
30
+ }
31
+ </script>
@@ -0,0 +1,204 @@
1
+ <template>
2
+ <v-container>
3
+ <h1>{{ $t('windward.core.pages.user_upload.title') }}</h1>
4
+ <v-divider class="mt-5 mb-5" />
5
+ <v-data-table
6
+ :headers="headers"
7
+ :items="uploadpages"
8
+ :search="search"
9
+ class="elevation-1"
10
+ >
11
+ <template #top>
12
+ <v-toolbar flat>
13
+ <CourseSectionSwitch
14
+ @change="load($event)"
15
+ ></CourseSectionSwitch>
16
+ <v-spacer></v-spacer>
17
+ <v-text-field
18
+ v-model="search"
19
+ class="ml-5 flex-grow-1"
20
+ append-icon="mdi-magnify"
21
+ :label="$t('shared.forms.search')"
22
+ single-line
23
+ hide-details
24
+ ></v-text-field>
25
+ </v-toolbar>
26
+ </template>
27
+
28
+ <template #item="{ index, item }">
29
+ <tr>
30
+ <td>{{ item.last_name }}</td>
31
+ <td>{{ item.first_name }}</td>
32
+ <td
33
+ v-for="(block, blockIndex) in item.uploadBlocks"
34
+ :key="blockIndex"
35
+ class="grade-column"
36
+ >
37
+ <ManageDataTableUserFiles
38
+ v-model="block.assets"
39
+ :enrollment="block.enrollment"
40
+ ></ManageDataTableUserFiles>
41
+ </td>
42
+ </tr>
43
+ </template>
44
+ </v-data-table>
45
+ </v-container>
46
+ </template>
47
+
48
+ <script>
49
+ import { mapGetters } from 'vuex'
50
+ import _ from 'lodash'
51
+ import Course from '~/models/Course'
52
+ import CourseSection from '~/models/CourseSection'
53
+ import UserFileAsset from '../models/UserFileAsset'
54
+
55
+ import CourseSectionSwitch from '~/components/Course/CourseSectionSwitch.vue'
56
+ import ManageDataTableUserFiles from '../components/Content/Blocks/UserUpload/ManageDataTableUserFiles.vue'
57
+
58
+ export default {
59
+ name: 'PluginUserUploadPage',
60
+ middleware: ['auth', 'privilege'],
61
+ components: { CourseSectionSwitch, ManageDataTableUserFiles },
62
+ layout: 'authenticated',
63
+ meta: {
64
+ privilege: {
65
+ 'windward.organization.course.section.user': {
66
+ writable: true,
67
+ },
68
+ },
69
+ },
70
+ data() {
71
+ return {
72
+ search: '',
73
+ contentPages: [],
74
+ enrollments: [],
75
+ userUploads: [],
76
+ defaultHeaders: [
77
+ {
78
+ text: this.$t('shared.forms.last_name'),
79
+ align: 'start',
80
+ sortable: true,
81
+ value: 'last_name',
82
+ },
83
+ {
84
+ text: this.$t('shared.forms.first_name'),
85
+ align: 'start',
86
+ sortable: true,
87
+ value: 'first_name',
88
+ },
89
+ ],
90
+ }
91
+ },
92
+ async fetch() {
93
+ // Get all content pages that have a user upload block in them
94
+ this.contentPages = await new Course(this.course)
95
+ .content()
96
+ .with('content.blocks')
97
+ .where('content.blocks.tag', 'plugin-core-user-upload')
98
+ .get()
99
+
100
+ await this.load(this.enrollment.course_section_id)
101
+ },
102
+ computed: {
103
+ ...mapGetters({
104
+ course: 'course/get',
105
+ enrollment: 'enrollment/get',
106
+ }),
107
+ headers() {
108
+ const headers = _.cloneDeep(this.defaultHeaders)
109
+
110
+ for (const block of this.uploadBlocks) {
111
+ headers.push({
112
+ text: block.content.name,
113
+ align: 'start',
114
+ sortable: true,
115
+ value: ('block_' + block.id).replace(/-/g, '_'),
116
+ })
117
+ }
118
+
119
+ return headers
120
+ },
121
+ uploadBlocks() {
122
+ const blocks = []
123
+ for (const page of this.contentPages) {
124
+ for (const block of page.content.blocks) {
125
+ const blockClone = _.cloneDeep(block)
126
+ const content = _.cloneDeep(page.content)
127
+
128
+ delete content.blocks
129
+ blockClone.content = content
130
+ blocks.push(blockClone)
131
+ }
132
+ }
133
+
134
+ return blocks
135
+ },
136
+ uploadpages() {
137
+ // This will map all the uploads to a user & content block for display
138
+ // Currently the enrollments / blocks / uploads are all unlinked
139
+ const items = []
140
+
141
+ for (const enrollment of this.enrollments) {
142
+ const uploadList = []
143
+
144
+ const user = {
145
+ course_user_id: enrollment.id,
146
+ last_name: enrollment.user.last_name,
147
+ first_name: enrollment.user.first_name,
148
+ }
149
+
150
+ for (const block of this.uploadBlocks) {
151
+ const key = ('block_' + block.id).replace(/-/g, '_')
152
+
153
+ const assets = this.userUploads.find((f) => {
154
+ // Only get the relevant block for the relevant user
155
+ return (
156
+ f.content_block_id === block.id &&
157
+ f.course_user_id === user.course_user_id
158
+ )
159
+ })
160
+
161
+ // Store if they uploaded or not for easier sorting
162
+ user[key] = typeof assets !== 'undefined'
163
+
164
+ // Store the grade value to put into an array for easier loops
165
+ uploadList.push({
166
+ block,
167
+ enrollment,
168
+ assets: assets || {}, // Object or empty so dot notation doesn't break
169
+ })
170
+ }
171
+
172
+ // Add the uploads
173
+ // Append the full grade array at the end for easier display
174
+ user.uploadBlocks = uploadList
175
+
176
+ items.push(user)
177
+ }
178
+
179
+ return items
180
+ },
181
+ },
182
+ mounted() {},
183
+ methods: {
184
+ async load(sectionId) {
185
+ // Load all users in this course
186
+ this.enrollments = await new Course(this.course)
187
+ .enrollments()
188
+ .with('user')
189
+ .where('course_section_id', sectionId)
190
+ .get()
191
+
192
+ this.userUploads = await new UserFileAsset()
193
+ .for(new CourseSection({ id: sectionId }))
194
+ .get()
195
+ },
196
+ },
197
+ }
198
+ </script>
199
+
200
+ <style scoped>
201
+ .block-column {
202
+ min-width: 10em;
203
+ }
204
+ </style>