@windward/integrations 0.17.0 → 0.19.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.
Files changed (80) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/components/Content/Blocks/ExternalIntegration/LtiConsumer.vue +3 -3
  3. package/components/Content/Blocks/ExternalIntegration/ScormConsumer.vue +34 -0
  4. package/components/ExternalIntegration/Driver/Lti1p1/ManageConsumer.vue +10 -8
  5. package/components/ExternalIntegration/Driver/Lti1p1/ManageConsumers.vue +2 -2
  6. package/components/ExternalIntegration/Driver/Lti1p1/ManageProvider.vue +8 -5
  7. package/components/ExternalIntegration/Driver/Lti1p1/ManageProviders.vue +3 -2
  8. package/components/ExternalIntegration/Driver/Lti1p3/ManageConsumer.vue +8 -6
  9. package/components/ExternalIntegration/Driver/Lti1p3/ManageConsumers.vue +2 -2
  10. package/components/ExternalIntegration/Driver/Lti1p3/ManageProvider.vue +27 -5
  11. package/components/ExternalIntegration/Driver/Lti1p3/ManageProviders.vue +4 -3
  12. package/components/ExternalIntegration/Driver/Lti1p3/ViewConsumer.vue +6 -5
  13. package/components/ExternalIntegration/Driver/ManageScorm.vue +45 -0
  14. package/components/ExternalIntegration/Driver/Scorm/ManageConsumer.vue +76 -0
  15. package/components/ExternalIntegration/Driver/Scorm/ManageConsumers.vue +233 -0
  16. package/components/ExternalIntegration/Driver/Scorm/ManageProvider.vue +475 -0
  17. package/components/ExternalIntegration/Driver/Scorm/ManageProviders.vue +299 -0
  18. package/components/Integration/Driver/LoginSamlButton.vue +119 -0
  19. package/components/Integration/Driver/ManageSaml.vue +327 -0
  20. package/components/LLM/GenerateContent/BlockQuestionGenerateButton.vue +34 -3
  21. package/components/SecretField.vue +99 -19
  22. package/components/Settings/ExternalIntegration/LtiConsumerSettings.vue +2 -2
  23. package/components/Settings/ExternalIntegration/ManageCourseIntegrationSettings.vue +6 -6
  24. package/components/Settings/ExternalIntegration/ScormConsumerSettings.vue +42 -0
  25. package/config/integration.config.js +2 -0
  26. package/helpers/Driver/SamlSso.ts +12 -0
  27. package/helpers/ExternalIntegration/ScormHelper.ts +155 -0
  28. package/i18n/en-US/components/external_integration/driver/lti1p3.ts +4 -1
  29. package/i18n/en-US/components/external_integration/driver/scorm.ts +14 -0
  30. package/i18n/en-US/components/external_integration/index.ts +3 -1
  31. package/i18n/en-US/components/integration/driver.ts +23 -0
  32. package/i18n/en-US/components/llm/generate_content/generate_questions.ts +7 -0
  33. package/i18n/en-US/pages/course/external_integration/index.ts +1 -1
  34. package/i18n/en-US/pages/login/index.ts +4 -0
  35. package/i18n/en-US/pages/login/lti.ts +2 -0
  36. package/i18n/en-US/pages/login/saml.ts +7 -0
  37. package/i18n/en-US/pages/login/scorm.ts +28 -0
  38. package/i18n/en-US/shared/content_blocks.ts +1 -0
  39. package/i18n/en-US/shared/settings.ts +1 -0
  40. package/i18n/es-ES/components/external_integration/driver/lti1p3.ts +4 -1
  41. package/i18n/es-ES/components/external_integration/driver/scorm.ts +15 -0
  42. package/i18n/es-ES/components/external_integration/index.ts +3 -1
  43. package/i18n/es-ES/components/integration/driver.ts +23 -0
  44. package/i18n/es-ES/components/llm/generate_content/generate_questions.ts +7 -0
  45. package/i18n/es-ES/pages/course/external_integration/index.ts +1 -1
  46. package/i18n/es-ES/pages/login/index.ts +4 -0
  47. package/i18n/es-ES/pages/login/lti.ts +2 -0
  48. package/i18n/es-ES/pages/login/saml.ts +7 -0
  49. package/i18n/es-ES/pages/login/scorm.ts +29 -0
  50. package/i18n/es-ES/shared/content_blocks.ts +1 -0
  51. package/i18n/es-ES/shared/settings.ts +1 -0
  52. package/i18n/sv-SE/components/external_integration/driver/lti1p3.ts +4 -1
  53. package/i18n/sv-SE/components/external_integration/driver/scorm.ts +14 -0
  54. package/i18n/sv-SE/components/external_integration/index.ts +3 -1
  55. package/i18n/sv-SE/components/integration/driver.ts +23 -0
  56. package/i18n/sv-SE/components/llm/generate_content/generate_questions.ts +7 -0
  57. package/i18n/sv-SE/pages/course/external_integration/index.ts +1 -1
  58. package/i18n/sv-SE/pages/login/index.ts +4 -0
  59. package/i18n/sv-SE/pages/login/lti.ts +2 -0
  60. package/i18n/sv-SE/pages/login/saml.ts +7 -0
  61. package/i18n/sv-SE/pages/login/scorm.ts +29 -0
  62. package/i18n/sv-SE/shared/content_blocks.ts +2 -1
  63. package/i18n/sv-SE/shared/settings.ts +1 -0
  64. package/jest.config.js +3 -0
  65. package/models/Auth/Saml.ts +21 -0
  66. package/models/ExternalIntegration/{LtiConsumer.ts → Consumer.ts} +2 -2
  67. package/models/ExternalIntegration/{LtiProvider.ts → Provider.ts} +2 -2
  68. package/package.json +2 -1
  69. package/pages/course/externalIntegration/index.vue +4 -0
  70. package/pages/login/scorm/error.vue +102 -0
  71. package/pages/login/scorm/promptEmail.vue +180 -0
  72. package/plugin.js +128 -7
  73. package/test/Components/ExternalIntegration/ManageScorm.spec.js +19 -0
  74. package/test/Components/ExternalIntegration/Scorm/ManageConsumer.spec.js +19 -0
  75. package/test/Components/ExternalIntegration/Scorm/ManageConsumers.spec.js +19 -0
  76. package/test/Components/ExternalIntegration/Scorm/ManageProvider.spec.js +19 -0
  77. package/test/Components/ExternalIntegration/Scorm/ManageProviders.spec.js +19 -0
  78. package/test/__mocks__/componentsMock.js +81 -1
  79. package/test/mocks.js +12 -0
  80. package/test/setup.js +1 -0
@@ -0,0 +1,76 @@
1
+ <template>
2
+ <div>Not implemented</div>
3
+ </template>
4
+
5
+ <script>
6
+ import _ from 'lodash'
7
+ import { mapGetters } from 'vuex'
8
+ import Consumer from '../../../../models/ExternalIntegration/Consumer'
9
+ import TextEditor from '~/components/Text/TextEditor.vue'
10
+ import FormVue from '~/components/Core/Form'
11
+
12
+ export default {
13
+ name: 'ManageLti1p1ConsumerDriver',
14
+ components: { TextEditor },
15
+ extends: FormVue,
16
+ props: {
17
+ value: {
18
+ type: [Consumer, null],
19
+ required: false,
20
+ default: null,
21
+ },
22
+ },
23
+ emits: ['update:consumer'],
24
+ meta: {
25
+ privilege: {
26
+ '': {
27
+ writable: true,
28
+ },
29
+ },
30
+ },
31
+ data() {
32
+ return {}
33
+ },
34
+ computed: {
35
+ ...mapGetters({
36
+ organization: 'organization/get',
37
+ course: 'course/get',
38
+ }),
39
+ },
40
+ created() {
41
+ if (_.isEmpty(this.value)) {
42
+ this.consumer = new Consumer(this.consumer)
43
+ } else {
44
+ this.consumer = new Consumer(_.cloneDeep(this.value))
45
+ }
46
+ },
47
+ mounted() {
48
+ if (
49
+ !this.$PermissionService.userHasAccessTo(
50
+ 'plugin.windward.integrations.course.externalIntegration',
51
+ 'writable'
52
+ )
53
+ ) {
54
+ // Display an angry error that they can't view this driver
55
+ this.$dialog.error(this.$t('shared.error.description_401'), {
56
+ duration: null,
57
+ action: {
58
+ text: this.$t('shared.forms.close'),
59
+ onClick: (_e, toastObject) => {
60
+ toastObject.goAway(0)
61
+ },
62
+ },
63
+ })
64
+
65
+ // eslint-disable-next-line no-console
66
+ console.error('You do not have access to this consumer!')
67
+
68
+ // Return so we don't even attempt loading
69
+ return false
70
+ }
71
+
72
+ this.render = true
73
+ },
74
+ methods: {},
75
+ }
76
+ </script>
@@ -0,0 +1,233 @@
1
+ <template>
2
+ <div>
3
+ <DialogBox
4
+ color="primary"
5
+ action-save
6
+ action-save-new
7
+ @click:save="onSaved"
8
+ @click:save-new="onSaved"
9
+ >
10
+ <template #title>{{
11
+ $t(
12
+ 'windward.integrations.components.external_integration.driver.scorm.new'
13
+ )
14
+ }}</template>
15
+ <template #trigger>{{
16
+ $t(
17
+ 'windward.integrations.components.external_integration.driver.scorm.new'
18
+ )
19
+ }}</template>
20
+ <template #form="{ on, attrs }"
21
+ ><ManageConsumer v-bind="attrs" v-on="on"></ManageConsumer
22
+ ></template>
23
+ </DialogBox>
24
+
25
+ <v-data-table
26
+ :headers="headers"
27
+ :items="consumers"
28
+ :items-per-page="10"
29
+ class="elevation-1"
30
+ >
31
+ <template #[`item.description`]="{ item }">
32
+ {{ item.description.replace(/(<([^>]+)>)/gi, '').trim() }}
33
+ </template>
34
+
35
+ <template #[`item.enabled`]="{ item }">
36
+ <v-icon :color="item.enabled ? 'success' : 'error'"
37
+ >{{ item.enabled ? 'mdi-check' : 'mdi-close' }}
38
+ </v-icon>
39
+ <span v-if="!item.enabled" class="sr-only">{{
40
+ $t('shared.forms.enabled')
41
+ }}</span>
42
+ </template>
43
+
44
+ <template #[`item.created_at`]="{ item }">
45
+ {{ $d(new Date(item.created_at), 'long') }}
46
+ </template>
47
+ <template #[`item.actions`]="{ index, item }">
48
+ <SpeedDial
49
+ direction="left"
50
+ color="primary"
51
+ transition="slide-x-reverse-transition"
52
+ >
53
+ <v-btn
54
+ color="error"
55
+ outlined
56
+ elevation="0"
57
+ class="outlined"
58
+ @click="onConfirmDelete(item)"
59
+ >
60
+ {{ $t('shared.forms.delete') }}
61
+ <span class="sr-only">{{
62
+ $t('shared.forms.delete')
63
+ }}</span>
64
+ </v-btn>
65
+ <DialogBox
66
+ color="primary"
67
+ outlined
68
+ :class-prop="'outlined'"
69
+ action-save
70
+ @click:save="onSaved"
71
+ >
72
+ <template #title>{{
73
+ $t(
74
+ 'windward.integrations.components.external_integration.driver.scorm.edit'
75
+ )
76
+ }}</template>
77
+ <template #trigger>
78
+ {{ $t('shared.forms.edit') }}
79
+ <span class="sr-only">{{
80
+ $t(
81
+ 'windward.integrations.components.external_integration.driver.scorm.edit'
82
+ )
83
+ }}</span>
84
+ </template>
85
+ <template #form="{ on, attrs }"
86
+ ><ManageConsumer
87
+ v-model="consumers[index]"
88
+ v-bind="attrs"
89
+ v-on="on"
90
+ ></ManageConsumer
91
+ ></template>
92
+ </DialogBox>
93
+ </SpeedDial>
94
+ </template>
95
+ </v-data-table>
96
+ </div>
97
+ </template>
98
+
99
+ <script>
100
+ import _ from 'lodash'
101
+ import { mapGetters } from 'vuex'
102
+ import Consumer from '../../../../models/ExternalIntegration/Consumer'
103
+ import ManageConsumer from './ManageConsumer.vue'
104
+ import Course from '~/models/Course'
105
+ import Organization from '~/models/Organization'
106
+ import DialogBox from '~/components/Core/DialogBox.vue'
107
+ import SpeedDial from '~/components/Core/SpeedDial.vue'
108
+
109
+ export default {
110
+ name: 'ManageScormConsumersDriver',
111
+ components: { DialogBox, ManageConsumer, SpeedDial },
112
+ data() {
113
+ return {
114
+ consumers: [],
115
+ headers: [
116
+ {
117
+ text: this.$t(
118
+ 'windward.integrations.components.external_integration.target_url'
119
+ ),
120
+ value: 'target',
121
+ },
122
+ {
123
+ text: this.$t('shared.forms.name'),
124
+ value: 'name',
125
+ },
126
+ {
127
+ text: this.$t('shared.forms.description'),
128
+ value: 'description',
129
+ },
130
+ {
131
+ text: this.$t('shared.forms.enabled'),
132
+ value: 'enabled',
133
+ },
134
+ { text: this.$t('shared.forms.created'), value: 'created_at' },
135
+ {
136
+ text: this.$t('shared.forms.actions'),
137
+ value: 'actions',
138
+ sortable: false,
139
+ },
140
+ ],
141
+ }
142
+ },
143
+
144
+ async fetch() {
145
+ if (
146
+ !this.$PermissionService.userHasAccessTo(
147
+ 'plugin.windward.integrations.course.externalIntegration',
148
+ 'readable'
149
+ ) ||
150
+ _.isEmpty(this.organization.id) ||
151
+ _.isEmpty(this.course.id)
152
+ ) {
153
+ // Display an angry error that they can't view this driver
154
+ this.$dialog.error(this.$t('shared.error.description_401'), {
155
+ duration: null,
156
+ action: {
157
+ text: this.$t('shared.forms.close'),
158
+ onClick: (_e, toastObject) => {
159
+ toastObject.goAway(0)
160
+ },
161
+ },
162
+ })
163
+ if (_.isEmpty(this.organization.id) || _.isEmpty(this.course.id)) {
164
+ // eslint-disable-next-line no-console
165
+ console.error(
166
+ 'Cannot load external integrations because organization or course is not set!'
167
+ )
168
+ } else {
169
+ // eslint-disable-next-line no-console
170
+ console.error(
171
+ 'You do not have access to this external integration!'
172
+ )
173
+ }
174
+
175
+ // Return so we don't even attempt loading
176
+ return false
177
+ }
178
+
179
+ await this.loadConsumers()
180
+ },
181
+ computed: {
182
+ ...mapGetters({
183
+ organization: 'organization/get',
184
+ course: 'course/get',
185
+ }),
186
+ },
187
+ methods: {
188
+ onSaved() {
189
+ this.loadConsumers()
190
+ },
191
+ async loadConsumers() {
192
+ this.consumers = await new Consumer()
193
+ .for(
194
+ new Organization({ id: this.organization.id }),
195
+ new Course({ id: this.course.id })
196
+ )
197
+ .where('version', '1.1')
198
+ .get()
199
+ },
200
+ onConfirmDelete(consumer) {
201
+ this.$dialog.show(this.$t('shared.forms.confirm_delete_text'), {
202
+ icon: 'mdi-help',
203
+ duration: null,
204
+ action: [
205
+ {
206
+ text: this.$t('shared.forms.cancel'),
207
+ onClick: (_e, toastObject) => {
208
+ toastObject.goAway(0)
209
+ },
210
+ },
211
+ {
212
+ text: this.$t('shared.forms.confirm'),
213
+ // router navigation
214
+ onClick: (_e, toastObject) => {
215
+ this.deleteConsumer(consumer)
216
+ toastObject.goAway(0)
217
+ },
218
+ },
219
+ ],
220
+ })
221
+ },
222
+ async deleteConsumer(consumer) {
223
+ try {
224
+ await consumer.delete()
225
+ this.loadConsumers()
226
+ } catch (error) {
227
+ this.$dialog.error(this.$t('shared.response.error'))
228
+ console.error('Error deleting consumer', error)
229
+ }
230
+ },
231
+ },
232
+ }
233
+ </script>