@windward/core 0.15.0 → 0.17.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.
@@ -2,8 +2,7 @@ export default {
2
2
  title: {
3
3
  assessment: 'Configuración de evaluación',
4
4
  open_response: 'Abrir configuración de respuesta',
5
- open_response_collate:
6
- 'Abrir configuración de clasificación de respuestas',
5
+ open_response_collate: 'Abrir configuración de descarga de respuesta',
7
6
  image: 'Configuración de imagen',
8
7
  user_upload: 'Configuración de carga del usuario',
9
8
  file_download: 'Configuración de descarga de archivos',
@@ -10,7 +10,7 @@ export default {
10
10
 
11
11
  content_mismatch: 'Innehållet matchar inte frågetyp.',
12
12
  content_mismatch_support:
13
- 'Det aktuella innehållet är inte lämpligt för den här typen av frågor. Överväg att lägga till mer specifika exempel eller jämförbara objekt.',
13
+ 'Vänligen lägg till mer text, exempel eller förklaringar till detta avsnitt. Vi rekommenderar minst 50 ord av relevant innehåll för att generera lämpliga frågor.',
14
14
 
15
15
  llm_unavailable: 'Frågegenerering tillfälligt otillgänglig.',
16
16
  llm_unavailable_support:
@@ -22,4 +22,14 @@ export default {
22
22
  },
23
23
  button_label: 'Generera fråga',
24
24
  selected_pages: 'Vald sida',
25
+ ai_assistance: 'AI-hjälp',
26
+ blooms: {
27
+ blooms_taxonomy: 'Blooms taxonominivå',
28
+ none: 'Ingen vald',
29
+ remember: 'Komma ihåg',
30
+ understand: 'Förstå',
31
+ apply: 'Tillämpas',
32
+ analyze: 'Analysera',
33
+ evaluate: 'Utvärdera',
34
+ },
25
35
  }
@@ -8,7 +8,7 @@ export default {
8
8
  math: 'Math',
9
9
  accordion: 'Accordion',
10
10
  open_response: 'Öppet svar',
11
- open_response_collate: 'Öppna svarssortering',
11
+ open_response_collate: 'Öppna svar Ladda ner',
12
12
  image: 'Bild',
13
13
  user_upload: 'User Upload',
14
14
  clickable_icons: 'Klickbara ikoner',
@@ -2,7 +2,7 @@ export default {
2
2
  title: {
3
3
  assessment: 'Bedömningsinställningar',
4
4
  open_response: 'Öppna svarsinställningar',
5
- open_response_collate: 'Öppna inställningar för svarssortering',
5
+ open_response_collate: 'Öppna inställningar för nedladdning av svar',
6
6
  image: 'Bildinställningar',
7
7
  user_upload: 'Användaruppladdningsinställningar',
8
8
  file_download: 'Filnedladdningsinställningar',
@@ -0,0 +1,9 @@
1
+ // @ts-ignore
2
+ import BaseModel from './BaseModel'
3
+
4
+ export default class Activity extends BaseModel {
5
+ // Set the resource route of the model
6
+ resource() {
7
+ return 'activities'
8
+ }
9
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windward/core",
3
- "version": "0.15.0",
3
+ "version": "0.17.0",
4
4
  "description": "Windward UI Core Plugins",
5
5
  "main": "plugin.js",
6
6
  "scripts": {
@@ -1,5 +1,8 @@
1
1
  <template>
2
2
  <v-row justify="center" align="center">
3
+ <v-col cols="12">
4
+ <Breadcrumbs :items="breadcrumbPath"></Breadcrumbs>
5
+ </v-col>
3
6
  <v-col cols="12">
4
7
  <v-alert
5
8
  v-if="
@@ -27,10 +30,12 @@
27
30
  </template>
28
31
 
29
32
  <script>
33
+ import { mapGetters } from 'vuex'
30
34
  import { CourseGlossary } from '../utils/index'
35
+ import Breadcrumbs from '~/components/Core/Breadcrumbs.vue'
31
36
  export default {
32
37
  name: 'Glossary',
33
- components: { CourseGlossary },
38
+ components: { CourseGlossary, Breadcrumbs },
34
39
  layout: 'course',
35
40
  middleware: ['auth', 'privilege'],
36
41
  meta: {
@@ -43,5 +48,29 @@ export default {
43
48
  },
44
49
  },
45
50
  },
51
+ computed: {
52
+ ...mapGetters({
53
+ course: 'course/get',
54
+ enrollment: 'enrollment/get',
55
+ }),
56
+ breadcrumbPath() {
57
+ return [
58
+ {
59
+ href:
60
+ '/course/' +
61
+ this.course.id +
62
+ '/section/' +
63
+ this.enrollment.course_section_id,
64
+ id: '',
65
+ text: this.course.name,
66
+ },
67
+ {
68
+ href: this.$route.path,
69
+ id: '',
70
+ text: this.$t('windward.core.pages.glossary.title'),
71
+ },
72
+ ]
73
+ },
74
+ },
46
75
  }
47
76
  </script>
@@ -1,48 +1,53 @@
1
1
  <template>
2
- <v-container>
3
- <h2>{{ $t('windward.core.pages.user_upload.title') }}</h2>
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>
2
+ <v-row>
3
+ <v-col cols="12">
4
+ <Breadcrumbs :items="breadcrumbPath"></Breadcrumbs>
5
+ </v-col>
6
+ <v-col cols="12">
7
+ <h2>{{ $t('windward.core.pages.user_upload.title') }}</h2>
8
+ <v-divider class="mt-5 mb-5" />
9
+ <v-data-table
10
+ :headers="headers"
11
+ :items="uploadpages"
12
+ :search="search"
13
+ class="elevation-1"
14
+ >
15
+ <template #top>
16
+ <v-toolbar flat>
17
+ <CourseSectionSwitch
18
+ @change="load($event)"
19
+ ></CourseSectionSwitch>
20
+ <v-spacer></v-spacer>
21
+ <v-text-field
22
+ v-model="search"
23
+ class="ml-5 flex-grow-1"
24
+ append-icon="mdi-magnify"
25
+ :label="$t('shared.forms.search')"
26
+ single-line
27
+ hide-details
28
+ ></v-text-field>
29
+ </v-toolbar>
30
+ </template>
31
+
32
+ <template #item="{ index, item }">
33
+ <tr>
34
+ <td>{{ item.last_name }}</td>
35
+ <td>{{ item.first_name }}</td>
36
+ <td
37
+ v-for="(block, blockIndex) in item.uploadBlocks"
38
+ :key="blockIndex"
39
+ class="grade-column"
40
+ >
41
+ <ManageDataTableUserFiles
42
+ v-model="block.assets"
43
+ :enrollment="block.enrollment"
44
+ ></ManageDataTableUserFiles>
45
+ </td>
46
+ </tr>
47
+ </template>
48
+ </v-data-table>
49
+ </v-col>
50
+ </v-row>
46
51
  </template>
47
52
 
48
53
  <script>
@@ -51,14 +56,14 @@ import _ from 'lodash'
51
56
  import Course from '~/models/Course'
52
57
  import CourseSection from '~/models/CourseSection'
53
58
  import UserFileAsset from '../models/UserFileAsset'
54
-
59
+ import Breadcrumbs from '~/components/Core/Breadcrumbs.vue'
55
60
  import CourseSectionSwitch from '~/components/Course/CourseSectionSwitch.vue'
56
61
  import ManageDataTableUserFiles from '../components/Content/Blocks/UserUpload/ManageDataTableUserFiles.vue'
57
62
 
58
63
  export default {
59
64
  name: 'PluginUserUploadPage',
60
65
  middleware: ['auth', 'privilege'],
61
- components: { CourseSectionSwitch, ManageDataTableUserFiles },
66
+ components: { CourseSectionSwitch, ManageDataTableUserFiles, Breadcrumbs },
62
67
  layout: 'course',
63
68
  meta: {
64
69
  privilege: {
@@ -178,6 +183,24 @@ export default {
178
183
 
179
184
  return items
180
185
  },
186
+ breadcrumbPath() {
187
+ return [
188
+ {
189
+ href:
190
+ '/course/' +
191
+ this.course.id +
192
+ '/section/' +
193
+ this.enrollment.course_section_id,
194
+ id: '',
195
+ text: this.course.name,
196
+ },
197
+ {
198
+ href: this.$route.path,
199
+ id: '',
200
+ text: this.$t('windward.core.pages.user_upload.title'),
201
+ },
202
+ ]
203
+ },
181
204
  },
182
205
  mounted() {},
183
206
  methods: {
package/plugin.js CHANGED
@@ -216,7 +216,7 @@ export default {
216
216
  tag: 'core-open-response-collate',
217
217
  template: OpenResponseCollate,
218
218
  metadata: {
219
- icon: 'mdi-text-long',
219
+ icon: 'mdi-cloud-download',
220
220
  name: 'windward.core.shared.content_blocks.title.open_response_collate',
221
221
  grouping: 'components.content.blocks.group.basic',
222
222
  },
package/utils/index.js CHANGED
@@ -7,7 +7,7 @@ import TinyMCEWrapper from '../components/utils/TinyMCEWrapper.vue'
7
7
  import MathExpressionEditor from '../components/utils/MathExpressionEditor'
8
8
  import CourseGlossary from '../components/utils/glossary/CourseGlossary.vue'
9
9
  import CourseGlossaryForm from '../components/utils/glossary/CourseGlossaryForm.vue'
10
- import GenerateAIQuestionButton from '../components/Content/Blocks/GenerateAIQuestionButton.vue'
10
+ import GenerateAIQuestionButton from '../components/utils/GenerateAIQuestionButton.vue'
11
11
 
12
12
  export {
13
13
  MathHelper,
@@ -1,139 +0,0 @@
1
- <template>
2
- <div>
3
- <v-row>
4
- <v-col cols="12" class="d-flex justify-end pb-1">
5
- <v-btn
6
- elevation="0"
7
- color="secondary"
8
- class="mb-1 btn-selector"
9
- :loading="isLoading"
10
- :disabled="isLoading"
11
- @click="generateAIQuestion"
12
- >
13
- <v-icon class="pr-1" v-if="!isLoading">mdi-magic-staff</v-icon>
14
- {{ $t('windward.core.components.content.blocks.generate_questions.button_label') }}
15
- <template v-slot:loader>
16
- <v-progress-circular indeterminate size="23"></v-progress-circular>
17
- </template>
18
- </v-btn>
19
- </v-col>
20
- <v-col cols="12" class="d-flex justify-end pt-0">
21
- <v-select
22
- v-model="selectedContent"
23
- :items="flattenedContent"
24
- class="btn-selector"
25
- outlined
26
- hide-details
27
- dense
28
- :label="$t('windward.core.components.content.blocks.generate_questions.selected_pages')"
29
- item-text="content.name"
30
- return-object
31
- ></v-select>
32
- </v-col>
33
- </v-row>
34
- </div>
35
- </template>
36
-
37
- <script>
38
- import AssessmentQuestion from '~/models/AssessmentQuestion'
39
- import Course from '~/models/Course'
40
- import Assessment from '~/models/Assessment'
41
- import Content from '~/models/Content'
42
- import { mapGetters } from 'vuex'
43
- import _ from 'lodash'
44
- import Crypto from '~/helpers/Crypto'
45
-
46
- export default {
47
- name: 'GenerateAIQuestionButton',
48
- props: {
49
- course: { type: Object, required: true },
50
- content: { type: Object, required: true },
51
- block: { type: Object, required: true },
52
- questionType: { type: String, required: true },
53
- },
54
- data() {
55
- return {
56
- isLoading: false,
57
- selectedContent: '',
58
- }
59
- },
60
- computed: {
61
- ...mapGetters({
62
- contentTree: 'content/getTree',
63
- }),
64
- flattenedContent() {
65
- let cloneContentTree = _.cloneDeep(this.contentTree)
66
- const homepage = this.$ContentService.getHomepage()
67
- if (!_.isEmpty(homepage)) {
68
- cloneContentTree.unshift(homepage)
69
- }
70
- let fullTree = []
71
- // flatten content tree to get nested children pages
72
- cloneContentTree.forEach((content) => {
73
- fullTree.push(content)
74
- if (content.children.length > 0) {
75
- fullTree = fullTree.concat(_.flatten(content.children))
76
- }
77
- })
78
- //
79
- if (_.isEmpty(this.selectedContent)) {
80
- // returns array so hold here to pluck out below
81
- const currentPage = fullTree.filter(
82
- (contentPage) => contentPage.id === this.content.id
83
- )
84
- this.selectedContent = currentPage[0] ? currentPage[0] : ''
85
- }
86
- return fullTree
87
- },
88
- },
89
- methods: {
90
- async generateAIQuestion() {
91
- this.isLoading = true
92
- try {
93
- const response = await AssessmentQuestion.custom(
94
- new Course(this.course),
95
- new Content(this.selectedContent),
96
- new Assessment({ id: this.block.id }),
97
- new AssessmentQuestion(),
98
- `suggest/${this.questionType}`
99
- ).get()
100
-
101
- if (response && response.length > 0) {
102
- const generatedQuestion = response[0]
103
- this.$emit('click:generate', generatedQuestion)
104
- }
105
- } catch (error) {
106
- const errorMessage = error.response?.data?.error?.message || 'assessment.error.technical'
107
- const errorType = errorMessage.split('.').pop()
108
- const basePath = 'windward.core.components.content.blocks.generate_questions.error'
109
-
110
- let errorText = this.$t(`${basePath}.${errorType}`) + '\n\n' +
111
- this.$t(`${basePath}.${errorType}_support`)
112
-
113
- if (errorType === 'technical') {
114
- const errorCode = error.response?.data?.error?.details?.error_type || 'UNKNOWN'
115
- errorText = errorText.replace('[ERROR_CODE]', errorCode)
116
- }
117
-
118
- this.$dialog.error(
119
- errorText,
120
- {
121
- duration: 5000,
122
- keepOnHover: true,
123
- singleton: true,
124
- type: 'error'
125
- }
126
- )
127
- } finally {
128
- this.isLoading = false
129
- }
130
- },
131
- },
132
- }
133
- </script>
134
-
135
- <style scoped>
136
- .btn-selector {
137
- width: 100%;
138
- }
139
- </style>