@windward/integrations 0.18.0 → 0.19.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.
- package/CHANGELOG.md +22 -0
- package/components/Content/Blocks/ExternalIntegration/LtiConsumer.vue +3 -3
- package/components/Content/Blocks/ExternalIntegration/ScormConsumer.vue +34 -0
- package/components/ExternalIntegration/Driver/Lti1p1/ManageConsumer.vue +10 -8
- package/components/ExternalIntegration/Driver/Lti1p1/ManageConsumers.vue +2 -2
- package/components/ExternalIntegration/Driver/Lti1p1/ManageProvider.vue +8 -5
- package/components/ExternalIntegration/Driver/Lti1p1/ManageProviders.vue +3 -2
- package/components/ExternalIntegration/Driver/Lti1p3/ManageConsumer.vue +8 -6
- package/components/ExternalIntegration/Driver/Lti1p3/ManageConsumers.vue +2 -2
- package/components/ExternalIntegration/Driver/Lti1p3/ManageProvider.vue +27 -5
- package/components/ExternalIntegration/Driver/Lti1p3/ManageProviders.vue +4 -3
- package/components/ExternalIntegration/Driver/Lti1p3/ViewConsumer.vue +6 -5
- package/components/ExternalIntegration/Driver/ManageScorm.vue +45 -0
- package/components/ExternalIntegration/Driver/Scorm/ManageConsumer.vue +76 -0
- package/components/ExternalIntegration/Driver/Scorm/ManageConsumers.vue +233 -0
- package/components/ExternalIntegration/Driver/Scorm/ManageProvider.vue +475 -0
- package/components/ExternalIntegration/Driver/Scorm/ManageProviders.vue +299 -0
- package/components/FileImport/FileImportMenu.vue +8 -1
- package/components/LLM/GenerateContent/BlockQuestionGenerateButton.vue +34 -3
- package/components/SecretField.vue +57 -34
- package/components/Settings/ExternalIntegration/LtiConsumerSettings.vue +2 -2
- package/components/Settings/ExternalIntegration/ManageCourseIntegrationSettings.vue +6 -6
- package/components/Settings/ExternalIntegration/ScormConsumerSettings.vue +42 -0
- package/helpers/ExternalIntegration/ScormHelper.ts +155 -0
- package/i18n/en-US/components/external_integration/driver/lti1p3.ts +4 -1
- package/i18n/en-US/components/external_integration/driver/scorm.ts +14 -0
- package/i18n/en-US/components/external_integration/index.ts +3 -1
- package/i18n/en-US/components/llm/generate_content/generate_questions.ts +7 -0
- package/i18n/en-US/pages/course/external_integration/index.ts +1 -1
- package/i18n/en-US/pages/login/index.ts +2 -0
- package/i18n/en-US/pages/login/lti.ts +2 -0
- package/i18n/en-US/pages/login/scorm.ts +28 -0
- package/i18n/en-US/shared/content_blocks.ts +1 -0
- package/i18n/en-US/shared/permission.ts +15 -3
- package/i18n/en-US/shared/settings.ts +1 -0
- package/i18n/es-ES/components/external_integration/driver/lti1p3.ts +4 -1
- package/i18n/es-ES/components/external_integration/driver/scorm.ts +15 -0
- package/i18n/es-ES/components/external_integration/index.ts +3 -1
- package/i18n/es-ES/components/llm/generate_content/generate_questions.ts +7 -0
- package/i18n/es-ES/pages/course/external_integration/index.ts +1 -1
- package/i18n/es-ES/pages/login/index.ts +2 -0
- package/i18n/es-ES/pages/login/lti.ts +2 -0
- package/i18n/es-ES/pages/login/scorm.ts +29 -0
- package/i18n/es-ES/shared/content_blocks.ts +1 -0
- package/i18n/es-ES/shared/permission.ts +15 -3
- package/i18n/es-ES/shared/settings.ts +1 -0
- package/i18n/sv-SE/components/external_integration/driver/lti1p3.ts +4 -1
- package/i18n/sv-SE/components/external_integration/driver/scorm.ts +14 -0
- package/i18n/sv-SE/components/external_integration/index.ts +3 -1
- package/i18n/sv-SE/components/llm/generate_content/generate_questions.ts +7 -0
- package/i18n/sv-SE/pages/course/external_integration/index.ts +1 -1
- package/i18n/sv-SE/pages/login/index.ts +2 -0
- package/i18n/sv-SE/pages/login/lti.ts +2 -0
- package/i18n/sv-SE/pages/login/scorm.ts +29 -0
- package/i18n/sv-SE/shared/content_blocks.ts +2 -1
- package/i18n/sv-SE/shared/permission.ts +15 -3
- package/i18n/sv-SE/shared/settings.ts +1 -0
- package/models/ExternalIntegration/{LtiConsumer.ts → Consumer.ts} +2 -2
- package/models/ExternalIntegration/{LtiProvider.ts → Provider.ts} +2 -2
- package/package.json +2 -1
- package/pages/course/externalIntegration/index.vue +4 -0
- package/pages/login/scorm/error.vue +102 -0
- package/pages/login/scorm/promptEmail.vue +180 -0
- package/plugin.js +111 -7
- package/test/Components/ExternalIntegration/ManageScorm.spec.js +19 -0
- package/test/Components/ExternalIntegration/Scorm/ManageConsumer.spec.js +19 -0
- package/test/Components/ExternalIntegration/Scorm/ManageConsumers.spec.js +19 -0
- package/test/Components/ExternalIntegration/Scorm/ManageProvider.spec.js +19 -0
- package/test/Components/ExternalIntegration/Scorm/ManageProviders.spec.js +19 -0
- package/test/mocks.js +12 -0
|
@@ -4,6 +4,8 @@ export default {
|
|
|
4
4
|
missing_title: 'Fälten nedan saknas:',
|
|
5
5
|
error_title: 'Fel nedan uppstod:',
|
|
6
6
|
error: {
|
|
7
|
+
invalid_launch_request: 'Startbegäran var ogiltig',
|
|
8
|
+
tool_disabled: 'Detta LTI-paket är inaktiverat',
|
|
7
9
|
unknown: 'Ett okänt kommunikationsfel inträffade',
|
|
8
10
|
organization: 'Ogiltig organisation',
|
|
9
11
|
tool: 'Ogiltigt verktygs-id',
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
scorm_error: 'SCORM-fel',
|
|
3
|
+
email_required: 'E-postadress krävs för att fortsätta',
|
|
4
|
+
launch_error: 'SCORM-paketet misslyckades med att starta',
|
|
5
|
+
missing_title: 'Fälten nedan saknas:',
|
|
6
|
+
error_title: 'Felen nedan inträffade:',
|
|
7
|
+
enter_email:
|
|
8
|
+
'Ange din e-postadress nedan för att slutföra kontokonfigurationen. Din e-postadress kommer endast att användas för att underlätta kursrelaterad kommunikation, såsom frågor om kursinnehåll och teknisk support.',
|
|
9
|
+
privacy_policy: 'För mer information, se vår integritetspolicy.',
|
|
10
|
+
error: {
|
|
11
|
+
missing_data:
|
|
12
|
+
'Kunde inte ladda på grund av saknade data. Student-ID och/eller studentnamn saknas.',
|
|
13
|
+
missing_api: 'Kunde inte komma åt LMS SCORM API.',
|
|
14
|
+
invalid_launch_request: 'Startbegäran var ogiltig',
|
|
15
|
+
tool_disabled: 'Detta SCORM-paket är inaktiverat',
|
|
16
|
+
unknown: 'Ett okänt kommunikationsfel inträffade',
|
|
17
|
+
organization: 'Ogiltig organisation',
|
|
18
|
+
tool: 'Ogiltigt verktygs-ID',
|
|
19
|
+
tool_organization:
|
|
20
|
+
'Det här verktyget tillhör inte den här organisationen',
|
|
21
|
+
oauth: 'Ogiltig OAuth. Kontrollera din nyckel och hemlighet.',
|
|
22
|
+
},
|
|
23
|
+
missing: {
|
|
24
|
+
course_id: 'Kurs-ID saknas eller är ogiltigt.',
|
|
25
|
+
course_name: 'Kursnamnet saknas.',
|
|
26
|
+
callback: 'SCORM-återanropet saknas.',
|
|
27
|
+
state: 'SCORM-verifieringsstatus saknas.',
|
|
28
|
+
},
|
|
29
|
+
}
|
|
@@ -5,9 +5,15 @@ export default {
|
|
|
5
5
|
'plugin->windward->integrations->organization->jobs':
|
|
6
6
|
'Organisationsintegrationsjobb',
|
|
7
7
|
'plugin->windward->integrations->organization->integration':
|
|
8
|
-
'Organisationsintegrationer',
|
|
9
|
-
'plugin->windward->integrations->
|
|
10
|
-
|
|
8
|
+
'Organisationsintegrationer (läsåtkomst krävs för att använda aktiverade integrationer)',
|
|
9
|
+
'plugin->windward->integrations->organization':
|
|
10
|
+
'Fjärråtkomst till organisationen',
|
|
11
|
+
'plugin->windward->integrations->course': 'Fjärrkursåtkomst',
|
|
12
|
+
'plugin->windward->integrations->content': 'Fjärråtkomst till innehåll',
|
|
13
|
+
'plugin->windward->integrations->file':
|
|
14
|
+
'Filintegrationer Visa/Hantera fjärrfiler',
|
|
15
|
+
'plugin->windward->integrations->course->file':
|
|
16
|
+
'Importera filintegrationer till kurs (skrivåtkomst krävs för import)',
|
|
11
17
|
'plugin->windward->integrations->course->externalIntegration':
|
|
12
18
|
'Externa integrationer (LTI / SCORM / etc)',
|
|
13
19
|
'plugin->windward->integrations->ai':
|
|
@@ -31,10 +37,16 @@ export default {
|
|
|
31
37
|
'Få tillgång till integrationsjobb i den nuvarande organisationen',
|
|
32
38
|
'plugin->windward->integrations->organization->integration':
|
|
33
39
|
'Få åtkomst till och hantera integrationer i den nuvarande organisationen',
|
|
40
|
+
'plugin->windward->integrations->organization':
|
|
41
|
+
'Åtkomst till och hantering av fjärrorganisationer för import',
|
|
34
42
|
'plugin->windward->integrations->course':
|
|
35
43
|
'Åtkomst till och hantera kursimport',
|
|
36
44
|
'plugin->windward->integrations->content':
|
|
37
45
|
'Åtkomst till och hantera innehållsimport',
|
|
46
|
+
'plugin->windward->integrations->file':
|
|
47
|
+
'Åtkomst till och hantering av fjärrfiler via deras integration. Denna behörighet låter dig se tillgängliga filer på fjärrtjänster som Google Drive, Dropbox, ResourceSpace etc.',
|
|
48
|
+
'plugin->windward->integrations->course->file':
|
|
49
|
+
'Importera filer från en fjärrfilintegration till en specifik kurs',
|
|
38
50
|
'plugin->windward->integrations->course->externalIntegration':
|
|
39
51
|
'Få åtkomst till och hantera externa integrationer som LTI och SCORM',
|
|
40
52
|
},
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// @ts-ignore
|
|
2
2
|
import Model from '~/models/Model'
|
|
3
3
|
|
|
4
|
-
export default class
|
|
4
|
+
export default class Consumer extends Model {
|
|
5
5
|
get required(): string[] {
|
|
6
6
|
return []
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
// Set the resource route of the model
|
|
10
10
|
resource() {
|
|
11
|
-
return 'external-
|
|
11
|
+
return 'external-integration-consumers'
|
|
12
12
|
}
|
|
13
13
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// @ts-ignore
|
|
2
2
|
import Model from '~/models/Model'
|
|
3
3
|
|
|
4
|
-
export default class
|
|
4
|
+
export default class Provider extends Model {
|
|
5
5
|
get required(): string[] {
|
|
6
6
|
return []
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
// Set the resource route of the model
|
|
10
10
|
resource() {
|
|
11
|
-
return 'external-
|
|
11
|
+
return 'external-integration-providers'
|
|
12
12
|
}
|
|
13
13
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@windward/integrations",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.1",
|
|
4
4
|
"description": "Windward UI Plugin Integrations for 3rd Party Systems",
|
|
5
5
|
"main": "plugin.js",
|
|
6
6
|
"scripts": {
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"@windward/core": "^0.8.0",
|
|
26
26
|
"canvas-confetti": "^1.6.0",
|
|
27
27
|
"eslint": "^8.11.0",
|
|
28
|
+
"jwt-decode": "^4.0.0",
|
|
28
29
|
"laravel-echo": "^1.15.0",
|
|
29
30
|
"prettier": "^2.6.0",
|
|
30
31
|
"pusher-js": "^8.0.1"
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-container>
|
|
3
|
+
<v-divider />
|
|
4
|
+
<v-row>
|
|
5
|
+
<v-col cols="12" md="6" offset-md="3">
|
|
6
|
+
<h1 class="text-center mt-5">
|
|
7
|
+
{{
|
|
8
|
+
$t(
|
|
9
|
+
'windward.integrations.pages.login.scorm.launch_error'
|
|
10
|
+
)
|
|
11
|
+
}}
|
|
12
|
+
</h1>
|
|
13
|
+
<v-alert
|
|
14
|
+
v-if="error.length === 0 && missing.length === 0"
|
|
15
|
+
type="error"
|
|
16
|
+
class="mt-5"
|
|
17
|
+
>
|
|
18
|
+
<strong>{{
|
|
19
|
+
$t(
|
|
20
|
+
'windward.integrations.pages.login.scorm.error.unknown'
|
|
21
|
+
)
|
|
22
|
+
}}</strong>
|
|
23
|
+
</v-alert>
|
|
24
|
+
<v-alert v-if="missing.length" type="warning" class="mt-5">
|
|
25
|
+
<strong>{{
|
|
26
|
+
$t(
|
|
27
|
+
'windward.integrations.pages.login.scorm.missing_title'
|
|
28
|
+
)
|
|
29
|
+
}}</strong>
|
|
30
|
+
<ul>
|
|
31
|
+
<li v-for="missingItem in missing" :key="missingItem">
|
|
32
|
+
{{
|
|
33
|
+
$t(
|
|
34
|
+
'windward.integrations.pages.login.scorm.missing.' +
|
|
35
|
+
missingItem
|
|
36
|
+
)
|
|
37
|
+
}}
|
|
38
|
+
</li>
|
|
39
|
+
</ul>
|
|
40
|
+
</v-alert>
|
|
41
|
+
<v-alert v-if="error.length" type="error" class="mt-5">
|
|
42
|
+
<strong>{{
|
|
43
|
+
$t(
|
|
44
|
+
'windward.integrations.pages.login.scorm.error_title'
|
|
45
|
+
)
|
|
46
|
+
}}</strong>
|
|
47
|
+
<ul>
|
|
48
|
+
<li v-for="errorItem in error" :key="errorItem">
|
|
49
|
+
{{
|
|
50
|
+
$t(
|
|
51
|
+
'windward.integrations.pages.login.scorm.error.' +
|
|
52
|
+
errorItem
|
|
53
|
+
)
|
|
54
|
+
}}
|
|
55
|
+
</li>
|
|
56
|
+
</ul>
|
|
57
|
+
</v-alert>
|
|
58
|
+
</v-col>
|
|
59
|
+
</v-row>
|
|
60
|
+
</v-container>
|
|
61
|
+
</template>
|
|
62
|
+
|
|
63
|
+
<script>
|
|
64
|
+
import _ from 'lodash'
|
|
65
|
+
export default {
|
|
66
|
+
name: 'PluginIntegrationsLoginScormErrorPage',
|
|
67
|
+
layout: 'default',
|
|
68
|
+
data() {
|
|
69
|
+
return {
|
|
70
|
+
missing: [],
|
|
71
|
+
error: [],
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
async fetch() {},
|
|
75
|
+
computed: {},
|
|
76
|
+
mounted() {
|
|
77
|
+
// Get the missing url parameters to display
|
|
78
|
+
if (!_.isEmpty(_.get(this.$route, 'query.missing', ''))) {
|
|
79
|
+
this.missing = _.get(this.$route, 'query.missing', '')
|
|
80
|
+
.split(',')
|
|
81
|
+
.map((v) => v.trim())
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Get the error url parameters to display
|
|
85
|
+
if (!_.isEmpty(_.get(this.$route, 'query.error', ''))) {
|
|
86
|
+
this.error = _.get(this.$route, 'query.error', '')
|
|
87
|
+
.split(',')
|
|
88
|
+
.map((v) => v.trim())
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Set the appropriate locale
|
|
92
|
+
if (!_.isEmpty(_.get(this.$route, 'query.locale', ''))) {
|
|
93
|
+
const locale = _.get(this.$route, 'query.locale', '')
|
|
94
|
+
|
|
95
|
+
if (this.$i18n.locales.includes(locale)) {
|
|
96
|
+
this.$i18n.setLocale(locale)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
methods: {},
|
|
101
|
+
}
|
|
102
|
+
</script>
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-container>
|
|
3
|
+
<v-divider />
|
|
4
|
+
<v-row v-if="error">
|
|
5
|
+
<v-col cols="12" lg="6" offset-lg="3">
|
|
6
|
+
<v-alert type="error" class="mt-5 text-center">
|
|
7
|
+
<strong>{{ error }}</strong>
|
|
8
|
+
</v-alert>
|
|
9
|
+
</v-col>
|
|
10
|
+
</v-row>
|
|
11
|
+
|
|
12
|
+
<div v-if="error === null">
|
|
13
|
+
<v-row>
|
|
14
|
+
<v-col cols="12" lg="6" offset-lg="3">
|
|
15
|
+
<h2 class="text-center my-5">
|
|
16
|
+
{{
|
|
17
|
+
$t(
|
|
18
|
+
'windward.integrations.pages.login.scorm.email_required'
|
|
19
|
+
)
|
|
20
|
+
}}
|
|
21
|
+
</h2>
|
|
22
|
+
|
|
23
|
+
<v-card>
|
|
24
|
+
<v-card-text>
|
|
25
|
+
<v-row>
|
|
26
|
+
<v-col v-if="course.icon" cols="4">
|
|
27
|
+
<v-img :src="course.icon" />
|
|
28
|
+
</v-col>
|
|
29
|
+
<v-col :cols="course.icon ? 8 : 12">
|
|
30
|
+
<p>
|
|
31
|
+
<strong>{{ course.name }}</strong>
|
|
32
|
+
</p>
|
|
33
|
+
<p>
|
|
34
|
+
{{
|
|
35
|
+
$t(
|
|
36
|
+
'windward.integrations.pages.login.scorm.enter_email'
|
|
37
|
+
)
|
|
38
|
+
}}
|
|
39
|
+
</p>
|
|
40
|
+
<p>
|
|
41
|
+
<a
|
|
42
|
+
:href="privacyPolicyUrl"
|
|
43
|
+
target="_blank"
|
|
44
|
+
>{{
|
|
45
|
+
$t(
|
|
46
|
+
'windward.integrations.pages.login.scorm.privacy_policy'
|
|
47
|
+
)
|
|
48
|
+
}}</a
|
|
49
|
+
>
|
|
50
|
+
</p>
|
|
51
|
+
</v-col>
|
|
52
|
+
</v-row>
|
|
53
|
+
|
|
54
|
+
<v-row>
|
|
55
|
+
<v-col cols="12">
|
|
56
|
+
<v-form
|
|
57
|
+
ref="form"
|
|
58
|
+
v-model="formValid"
|
|
59
|
+
lazy-validation
|
|
60
|
+
@submit.prevent="onSubmit"
|
|
61
|
+
>
|
|
62
|
+
<v-text-field
|
|
63
|
+
v-model="email"
|
|
64
|
+
:label="$t('shared.forms.email')"
|
|
65
|
+
:rules="
|
|
66
|
+
$Validation.getRule('email')
|
|
67
|
+
"
|
|
68
|
+
/>
|
|
69
|
+
<v-btn
|
|
70
|
+
color="primary"
|
|
71
|
+
:disabled="!formValid"
|
|
72
|
+
@click="onSubmit"
|
|
73
|
+
>
|
|
74
|
+
{{ $t('shared.forms.continue') }}
|
|
75
|
+
</v-btn>
|
|
76
|
+
</v-form>
|
|
77
|
+
</v-col>
|
|
78
|
+
</v-row>
|
|
79
|
+
</v-card-text>
|
|
80
|
+
</v-card>
|
|
81
|
+
</v-col>
|
|
82
|
+
</v-row>
|
|
83
|
+
<v-divider class="my-8" />
|
|
84
|
+
</div>
|
|
85
|
+
</v-container>
|
|
86
|
+
</template>
|
|
87
|
+
|
|
88
|
+
<script>
|
|
89
|
+
import _ from 'lodash'
|
|
90
|
+
import Uuid from '~/helpers/Uuid'
|
|
91
|
+
|
|
92
|
+
export default {
|
|
93
|
+
components: {},
|
|
94
|
+
name: 'PluginIntegrationsLoginScormErrorPage',
|
|
95
|
+
layout: 'default',
|
|
96
|
+
data() {
|
|
97
|
+
return {
|
|
98
|
+
loaded: false,
|
|
99
|
+
formValid: false,
|
|
100
|
+
email: null,
|
|
101
|
+
callback: null,
|
|
102
|
+
state: null,
|
|
103
|
+
course: {
|
|
104
|
+
id: null,
|
|
105
|
+
name: null,
|
|
106
|
+
icon: null,
|
|
107
|
+
},
|
|
108
|
+
privacyPolicyUrl: 'https://www.mindedge.com/privacy-policy/',
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
async fetch() {},
|
|
112
|
+
computed: {
|
|
113
|
+
error() {
|
|
114
|
+
if (!this.loaded) {
|
|
115
|
+
return null
|
|
116
|
+
} else if (!Uuid.test(this.course.id)) {
|
|
117
|
+
return this.$t(
|
|
118
|
+
'windward.integrations.pages.login.scorm.missing.course_id'
|
|
119
|
+
)
|
|
120
|
+
} else if (this.course.name === null) {
|
|
121
|
+
return this.$t(
|
|
122
|
+
'windward.integrations.pages.login.scorm.missing.course_name'
|
|
123
|
+
)
|
|
124
|
+
} else if (!this.callback) {
|
|
125
|
+
return this.$t(
|
|
126
|
+
'windward.integrations.pages.login.scorm.missing.callback'
|
|
127
|
+
)
|
|
128
|
+
} else if (!this.state) {
|
|
129
|
+
return this.$t(
|
|
130
|
+
'windward.integrations.pages.login.scorm.missing.state'
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
return null
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
mounted() {
|
|
137
|
+
// Get the state url parameter to callback with. This is just the encrypted payload from earlier
|
|
138
|
+
this.state = _.get(this.$route, 'query.state', null)
|
|
139
|
+
|
|
140
|
+
// Get the data url parameter to display course information
|
|
141
|
+
if (!_.isEmpty(_.get(this.$route, 'query.data', ''))) {
|
|
142
|
+
try {
|
|
143
|
+
const data = JSON.parse(
|
|
144
|
+
atob(_.get(this.$route, 'query.data', ''))
|
|
145
|
+
)
|
|
146
|
+
this.course.id = data.id
|
|
147
|
+
this.course.name = data.name
|
|
148
|
+
this.course.icon = data.icon
|
|
149
|
+
this.callback = data.callback
|
|
150
|
+
} catch (e) {
|
|
151
|
+
console.error('Could not parse course data', e)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Set the appropriate locale
|
|
156
|
+
if (!_.isEmpty(_.get(this.$route, 'query.locale', ''))) {
|
|
157
|
+
const locale = _.get(this.$route, 'query.locale', '')
|
|
158
|
+
|
|
159
|
+
if (this.$i18n.locales.includes(locale)) {
|
|
160
|
+
this.$i18n.setLocale(locale)
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
this.loaded = true
|
|
165
|
+
},
|
|
166
|
+
methods: {
|
|
167
|
+
onSubmit() {
|
|
168
|
+
if (this.email) {
|
|
169
|
+
let url = this.callback
|
|
170
|
+
url += '?state=' + this.state
|
|
171
|
+
url += '&email=' + btoa(this.email.trim())
|
|
172
|
+
|
|
173
|
+
console.log('Redirecting to ', url)
|
|
174
|
+
// Redirect back to the callback url
|
|
175
|
+
window.location = url
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
}
|
|
180
|
+
</script>
|
package/plugin.js
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
|
+
import _ from 'lodash'
|
|
1
2
|
import locales from './i18n'
|
|
2
3
|
|
|
3
4
|
import AdminVendorsPage from './pages/admin/vendors.vue'
|
|
4
5
|
import AdminImportCoursePage from './pages/admin/importCourse.vue'
|
|
5
6
|
import ExternalIntegrationIndexPage from './pages/course/externalIntegration/index.vue'
|
|
6
7
|
import LoginLtiErrorPage from './pages/login/lti/error.vue'
|
|
8
|
+
import LoginScormErrorPage from './pages/login/scorm/error.vue'
|
|
9
|
+
import LoginScormPromptEmailPage from './pages/login/scorm/promptEmail.vue'
|
|
10
|
+
|
|
7
11
|
import IntegrationHelper from './helpers/IntegrationHelper'
|
|
12
|
+
import ExternalIntegrationScormHelper from './helpers/ExternalIntegration/ScormHelper'
|
|
8
13
|
|
|
9
14
|
import LtiConsumerBlock from './components/Content/Blocks/ExternalIntegration/LtiConsumer'
|
|
10
15
|
import LtiConsumerBlockSettings from './components/Settings/ExternalIntegration/LtiConsumerSettings'
|
|
16
|
+
|
|
17
|
+
import ScormConsumerBlock from './components/Content/Blocks/ExternalIntegration/ScormConsumer'
|
|
18
|
+
import ScormConsumerBlockSettings from './components/Settings/ExternalIntegration/ScormConsumerSettings'
|
|
19
|
+
|
|
11
20
|
import ManageCourseIntegrationSettings from './components/Settings/ExternalIntegration/ManageCourseIntegrationSettings'
|
|
12
21
|
|
|
13
22
|
import FileImportMenu from './components/FileImport/FileImportMenu.vue'
|
|
@@ -27,14 +36,75 @@ export default {
|
|
|
27
36
|
name: 'windward.integrations.name',
|
|
28
37
|
version: null,
|
|
29
38
|
hooks: {
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
'update:enrollment': (app, enrollment = {}) => {
|
|
40
|
+
// If this tracking is for a SCORM enrollment then tell the service to emit the progess back to the host LMS
|
|
41
|
+
if (
|
|
42
|
+
enrollment &&
|
|
43
|
+
_.get(enrollment, 'metadata.integration.type', '') ===
|
|
44
|
+
'scorm' &&
|
|
45
|
+
_.get(enrollment, 'course_progress.id', null) !== null
|
|
46
|
+
) {
|
|
47
|
+
try {
|
|
48
|
+
app.$ExternalIntegrationScorm.trackEnrollment(enrollment)
|
|
49
|
+
} catch (e) {
|
|
50
|
+
console.error('Cannot track updated SCORM progress', e)
|
|
51
|
+
}
|
|
52
|
+
} else if (
|
|
53
|
+
enrollment &&
|
|
54
|
+
_.get(enrollment, 'metadata.integration.type', '') ===
|
|
55
|
+
'scorm' &&
|
|
56
|
+
_.get(enrollment, 'course_progress.id', null) === null
|
|
57
|
+
) {
|
|
58
|
+
console.error(
|
|
59
|
+
'Could not push initial data to host LMS. The enrollment is missing progress.'
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
'load:enrollment': (app, enrollment = {}) => {
|
|
64
|
+
// If this tracking is for a SCORM enrollment then tell the service to emit the progess back to the host LMS
|
|
65
|
+
if (
|
|
66
|
+
enrollment &&
|
|
67
|
+
_.get(enrollment, 'metadata.integration.type', '') ===
|
|
68
|
+
'scorm' &&
|
|
69
|
+
_.get(enrollment, 'course_progress.id', null) !== null
|
|
70
|
+
) {
|
|
71
|
+
try {
|
|
72
|
+
app.$ExternalIntegrationScorm.trackEnrollment(enrollment)
|
|
73
|
+
} catch (e) {
|
|
74
|
+
console.error('Cannot track SCORM progress', e)
|
|
75
|
+
}
|
|
76
|
+
} else if (
|
|
77
|
+
enrollment &&
|
|
78
|
+
_.get(enrollment, 'metadata.integration.type', '') ===
|
|
79
|
+
'scorm' &&
|
|
80
|
+
_.get(enrollment, 'course_progress.id', null) === null
|
|
81
|
+
) {
|
|
82
|
+
console.error(
|
|
83
|
+
'Could not push initial data to host LMS. The enrollment is missing progress.'
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
'update:tracking': (app, courseUserTracking = {}) => {
|
|
88
|
+
const enrollment = _.get(
|
|
89
|
+
app,
|
|
90
|
+
"store.getters['enrollment/get']",
|
|
91
|
+
null
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
// If this tracking is for a SCORM enrollment then tell the service to emit the progess back to the host LMS
|
|
95
|
+
if (
|
|
96
|
+
enrollment &&
|
|
97
|
+
_.get(enrollment, 'metadata.integration.type', '') === 'scorm'
|
|
98
|
+
) {
|
|
99
|
+
try {
|
|
100
|
+
app.$ExternalIntegrationScorm.trackProgress(
|
|
101
|
+
courseUserTracking
|
|
102
|
+
)
|
|
103
|
+
} catch (e) {
|
|
104
|
+
console.error('Cannot track SCORM progress', e)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
32
107
|
},
|
|
33
|
-
beforeDestroy: () => {},
|
|
34
|
-
beforeNavigate: () => {},
|
|
35
|
-
onNavigate: () => {},
|
|
36
|
-
onLoad: (_page) => {},
|
|
37
|
-
onContent: () => {},
|
|
38
108
|
},
|
|
39
109
|
i18n: locales.messages,
|
|
40
110
|
pages: [
|
|
@@ -66,6 +136,20 @@ export default {
|
|
|
66
136
|
name: 'PluginIntegrationsLoginLtiErrorPage',
|
|
67
137
|
template: LoginLtiErrorPage,
|
|
68
138
|
},
|
|
139
|
+
{
|
|
140
|
+
page: 'scorm-error',
|
|
141
|
+
path: '/login/scorm/error',
|
|
142
|
+
i18n: 'windward.integrations.pages.login.scorm.scorm_error',
|
|
143
|
+
name: 'PluginIntegrationsLoginScormErrorPage',
|
|
144
|
+
template: LoginScormErrorPage,
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
page: 'scorm-prompt-email',
|
|
148
|
+
path: '/login/scorm/prompt-email',
|
|
149
|
+
i18n: 'windward.integrations.pages.login.scorm.scorm_prompt_email',
|
|
150
|
+
name: 'PluginIntegrationsLoginScormPromptEmailPage',
|
|
151
|
+
template: LoginScormPromptEmailPage,
|
|
152
|
+
},
|
|
69
153
|
],
|
|
70
154
|
components: {
|
|
71
155
|
userLogin: [
|
|
@@ -195,6 +279,16 @@ export default {
|
|
|
195
279
|
'windward.integrations.shared.content_blocks.grouping.integrations',
|
|
196
280
|
},
|
|
197
281
|
},
|
|
282
|
+
/*{
|
|
283
|
+
tag: 'windward-integrations-scorm-consumer',
|
|
284
|
+
template: ScormConsumerBlock,
|
|
285
|
+
metadata: {
|
|
286
|
+
icon: 'mdi-shield-link-variant-outline',
|
|
287
|
+
name: 'windward.integrations.shared.content_blocks.title.scorm_consumer',
|
|
288
|
+
grouping:
|
|
289
|
+
'windward.integrations.shared.content_blocks.grouping.integrations',
|
|
290
|
+
},
|
|
291
|
+
},*/
|
|
198
292
|
],
|
|
199
293
|
contentBlockSetting: [
|
|
200
294
|
{
|
|
@@ -206,6 +300,15 @@ export default {
|
|
|
206
300
|
name: 'windward.integrations.shared.settings.title.lti_consumer',
|
|
207
301
|
},
|
|
208
302
|
},
|
|
303
|
+
{
|
|
304
|
+
tag: 'windward-integrations-scorm-consumer-settings',
|
|
305
|
+
template: ScormConsumerBlockSettings,
|
|
306
|
+
context: ['block.windward-integrations-scorm-consumer'],
|
|
307
|
+
metadata: {
|
|
308
|
+
icon: 'mdi-cog',
|
|
309
|
+
name: 'windward.integrations.shared.settings.title.scorm_consumer',
|
|
310
|
+
},
|
|
311
|
+
},
|
|
209
312
|
],
|
|
210
313
|
courseSetting: [
|
|
211
314
|
{
|
|
@@ -268,5 +371,6 @@ export default {
|
|
|
268
371
|
},
|
|
269
372
|
services: {
|
|
270
373
|
Integration: IntegrationHelper,
|
|
374
|
+
ExternalIntegrationScorm: ExternalIntegrationScormHelper,
|
|
271
375
|
},
|
|
272
376
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { shallowMount } from '@vue/test-utils'
|
|
2
|
+
|
|
3
|
+
import Vue from 'vue'
|
|
4
|
+
import Vuetify from 'vuetify'
|
|
5
|
+
import { defaultMocks } from '@/test/mocks'
|
|
6
|
+
|
|
7
|
+
import ManageScorm from '@/components/ExternalIntegration/Driver/ManageScorm.vue'
|
|
8
|
+
|
|
9
|
+
Vue.use(Vuetify)
|
|
10
|
+
|
|
11
|
+
describe('ManageScorm', () => {
|
|
12
|
+
test('ManageScorm is a Vue instance', () => {
|
|
13
|
+
const wrapper = shallowMount(ManageScorm, {
|
|
14
|
+
vuetify: new Vuetify(),
|
|
15
|
+
mocks: defaultMocks,
|
|
16
|
+
})
|
|
17
|
+
expect(wrapper.vm).toBeTruthy()
|
|
18
|
+
})
|
|
19
|
+
})
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { shallowMount } from '@vue/test-utils'
|
|
2
|
+
|
|
3
|
+
import Vue from 'vue'
|
|
4
|
+
import Vuetify from 'vuetify'
|
|
5
|
+
import { defaultMocks } from '@/test/mocks'
|
|
6
|
+
|
|
7
|
+
import ManageConsumer from '@/components/ExternalIntegration/Driver/Lti1p1/ManageConsumer.vue'
|
|
8
|
+
|
|
9
|
+
Vue.use(Vuetify)
|
|
10
|
+
|
|
11
|
+
describe('ManageConsumer', () => {
|
|
12
|
+
test('ManageConsumer is a Vue instance', () => {
|
|
13
|
+
const wrapper = shallowMount(ManageConsumer, {
|
|
14
|
+
vuetify: new Vuetify(),
|
|
15
|
+
mocks: defaultMocks,
|
|
16
|
+
})
|
|
17
|
+
expect(wrapper.vm).toBeTruthy()
|
|
18
|
+
})
|
|
19
|
+
})
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { shallowMount } from '@vue/test-utils'
|
|
2
|
+
|
|
3
|
+
import Vue from 'vue'
|
|
4
|
+
import Vuetify from 'vuetify'
|
|
5
|
+
import { defaultMocks } from '@/test/mocks'
|
|
6
|
+
|
|
7
|
+
import ManageConsumers from '@/components/ExternalIntegration/Driver/Scorm/ManageConsumers.vue'
|
|
8
|
+
|
|
9
|
+
Vue.use(Vuetify)
|
|
10
|
+
|
|
11
|
+
describe('ManageConsumers', () => {
|
|
12
|
+
test('ManageConsumers is a Vue instance', () => {
|
|
13
|
+
const wrapper = shallowMount(ManageConsumers, {
|
|
14
|
+
vuetify: new Vuetify(),
|
|
15
|
+
mocks: defaultMocks,
|
|
16
|
+
})
|
|
17
|
+
expect(wrapper.vm).toBeTruthy()
|
|
18
|
+
})
|
|
19
|
+
})
|