@windward/integrations 0.0.8 → 0.0.9
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/components/ExternalIntegration/Driver/Lti1p1/ManageProvider.vue +9 -6
- package/components/ExternalIntegration/Driver/Lti1p1/ManageProviders.vue +6 -5
- package/components/ExternalIntegration/Driver/Lti1p3/ManageProvider.vue +445 -0
- package/components/ExternalIntegration/Driver/Lti1p3/ManageProviders.vue +259 -0
- package/components/ExternalIntegration/Driver/ManageLti1p3.vue +45 -0
- package/components/Integration/Driver/ManageAtutor.vue +15 -0
- package/components/Integration/JobLog.vue +98 -0
- package/components/Integration/JobTable.vue +15 -1
- package/i18n/en-US/components/external_integration/driver/lti1p3.ts +13 -0
- package/i18n/en-US/components/external_integration/index.ts +2 -1
- package/i18n/en-US/components/integration/driver.ts +1 -0
- package/i18n/en-US/components/integration/job.ts +3 -0
- package/models/ExternalIntegration/{Lti1p1Provider.ts → LtiProvider.ts} +2 -2
- package/package.json +1 -1
- package/pages/admin/importCourse.vue +1 -1
- package/pages/admin/vendors.vue +3 -2
- package/pages/course/externalIntegration/index.vue +4 -3
- package/plugin.js +48 -1
- package/test/Components/ExternalIntegration/Lti1p3/ManageProvider.spec.js +19 -0
- package/test/Components/ExternalIntegration/Lti1p3/ManageProviders.spec.js +19 -0
- package/test/Components/ExternalIntegration/ManageLti1p3.spec.js +19 -0
- package/test/Components/Integration/JobLog.spec.js +22 -0
- package/test/Components/Integration/JobTable.spec.js +23 -0
- package/test/__mocks__/componentsMock.js +12 -0
- package/test/mocks.js +12 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<Dialog
|
|
4
|
+
color="primary"
|
|
5
|
+
action-save
|
|
6
|
+
action-save-new
|
|
7
|
+
@click:save="onSaved"
|
|
8
|
+
>
|
|
9
|
+
<template #title>{{
|
|
10
|
+
$t(
|
|
11
|
+
'windward.integrations.components.external_integration.driver.lti1p1.new'
|
|
12
|
+
)
|
|
13
|
+
}}</template>
|
|
14
|
+
<template #trigger>{{ $t('shared.forms.new') }}</template>
|
|
15
|
+
<template #form="{ on, attrs }"
|
|
16
|
+
><ManageProvider v-bind="attrs" v-on="on"></ManageProvider
|
|
17
|
+
></template>
|
|
18
|
+
</Dialog>
|
|
19
|
+
|
|
20
|
+
<v-data-table
|
|
21
|
+
:headers="headers"
|
|
22
|
+
:items="providers"
|
|
23
|
+
:items-per-page="10"
|
|
24
|
+
class="elevation-1"
|
|
25
|
+
>
|
|
26
|
+
<template #[`item.target`]="{ item }">
|
|
27
|
+
<ProviderTargetViewer
|
|
28
|
+
class="field--target text-truncate"
|
|
29
|
+
:target="item.target"
|
|
30
|
+
></ProviderTargetViewer>
|
|
31
|
+
</template>
|
|
32
|
+
<template #[`item.metadata.tool_public_keyset_url`]="{ item }">
|
|
33
|
+
<SecretField
|
|
34
|
+
v-model="item.metadata.tool_public_keyset_url"
|
|
35
|
+
:hidden="false"
|
|
36
|
+
></SecretField>
|
|
37
|
+
</template>
|
|
38
|
+
<template #[`item.metadata.tool_oidc_auth_endpoint`]="{ item }">
|
|
39
|
+
<SecretField
|
|
40
|
+
v-model="item.metadata.tool_oidc_auth_endpoint"
|
|
41
|
+
:hidden="false"
|
|
42
|
+
></SecretField>
|
|
43
|
+
</template>
|
|
44
|
+
<template #[`item.url`]="{ item }">
|
|
45
|
+
<SecretField v-model="item.url" :hidden="false"></SecretField>
|
|
46
|
+
</template>
|
|
47
|
+
|
|
48
|
+
<template #[`item.enabled`]="{ item }">
|
|
49
|
+
<v-icon :color="item.enabled ? 'success' : 'error'"
|
|
50
|
+
>{{ item.enabled ? 'mdi-check' : 'mdi-close' }}
|
|
51
|
+
</v-icon>
|
|
52
|
+
<span v-if="!item.enabled" class="sr-only">{{
|
|
53
|
+
$t('shared.forms.enabled')
|
|
54
|
+
}}</span>
|
|
55
|
+
</template>
|
|
56
|
+
|
|
57
|
+
<template #[`item.grade_sync`]="{ item }">
|
|
58
|
+
<v-icon :color="item.grade_sync ? 'success' : 'error'"
|
|
59
|
+
>{{ item.grade_sync ? 'mdi-check' : 'mdi-close' }}
|
|
60
|
+
</v-icon>
|
|
61
|
+
<span v-if="!item.grade_sync" class="sr-only">{{
|
|
62
|
+
$t(
|
|
63
|
+
'windward.integrations.components.external_integration.grade_sync'
|
|
64
|
+
)
|
|
65
|
+
}}</span>
|
|
66
|
+
</template>
|
|
67
|
+
|
|
68
|
+
<template #[`item.created_at`]="{ item }">
|
|
69
|
+
{{ $d(new Date(item.created_at), 'short') }}
|
|
70
|
+
</template>
|
|
71
|
+
<template #[`item.actions`]="{ index, item }">
|
|
72
|
+
<Dialog color="primary" action-save @click:save="onSaved">
|
|
73
|
+
<template #title>{{
|
|
74
|
+
$t(
|
|
75
|
+
'windward.integrations.components.external_integration.driver.lti1p3.edit'
|
|
76
|
+
)
|
|
77
|
+
}}</template>
|
|
78
|
+
<template #trigger>
|
|
79
|
+
<v-icon small>mdi-pencil</v-icon>
|
|
80
|
+
<span class="sr-only">{{
|
|
81
|
+
$t(
|
|
82
|
+
'windward.integrations.components.external_integration.driver.lti1p3.edit'
|
|
83
|
+
)
|
|
84
|
+
}}</span>
|
|
85
|
+
</template>
|
|
86
|
+
<template #form="{ on, attrs }"
|
|
87
|
+
><ManageProvider
|
|
88
|
+
v-model="providers[index]"
|
|
89
|
+
v-bind="attrs"
|
|
90
|
+
v-on="on"
|
|
91
|
+
></ManageProvider
|
|
92
|
+
></template>
|
|
93
|
+
</Dialog>
|
|
94
|
+
|
|
95
|
+
<v-btn icon>
|
|
96
|
+
<v-icon @click="onConfirmDelete(item)"> mdi-delete </v-icon>
|
|
97
|
+
<span class="sr-only">{{ $t('shared.forms.delete') }}</span>
|
|
98
|
+
</v-btn>
|
|
99
|
+
</template>
|
|
100
|
+
</v-data-table>
|
|
101
|
+
</div>
|
|
102
|
+
</template>
|
|
103
|
+
|
|
104
|
+
<script>
|
|
105
|
+
import _ from 'lodash'
|
|
106
|
+
import { mapGetters } from 'vuex'
|
|
107
|
+
import LtiProvider from '../../../../models/ExternalIntegration/LtiProvider'
|
|
108
|
+
import SecretField from '../../../SecretField.vue'
|
|
109
|
+
import ProviderTargetViewer from '../../ProviderTargetViewer.vue'
|
|
110
|
+
import ManageProvider from './ManageProvider.vue'
|
|
111
|
+
import Dialog from '~/components/Dialog.vue'
|
|
112
|
+
import Organization from '~/models/Organization'
|
|
113
|
+
import Course from '~/models/Course'
|
|
114
|
+
|
|
115
|
+
export default {
|
|
116
|
+
name: 'ManageLti1p1ProvidersDriver',
|
|
117
|
+
components: { SecretField, Dialog, ManageProvider, ProviderTargetViewer },
|
|
118
|
+
data() {
|
|
119
|
+
return {
|
|
120
|
+
providers: [],
|
|
121
|
+
headers: [
|
|
122
|
+
{
|
|
123
|
+
text: this.$t(
|
|
124
|
+
'windward.integrations.components.external_integration.target'
|
|
125
|
+
),
|
|
126
|
+
value: 'target',
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
text: this.$t(
|
|
130
|
+
'windward.integrations.components.external_integration.driver.lti1p3.tool_public_keyset_url'
|
|
131
|
+
),
|
|
132
|
+
value: 'metadata.tool_public_keyset_url',
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
text: this.$t(
|
|
136
|
+
'windward.integrations.components.external_integration.driver.lti1p3.tool_oidc_auth_endpoint'
|
|
137
|
+
),
|
|
138
|
+
value: 'metadata.tool_oidc_auth_endpoint',
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
text: this.$t(
|
|
142
|
+
'windward.integrations.components.external_integration.launch_url'
|
|
143
|
+
),
|
|
144
|
+
value: 'url',
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
text: this.$t('shared.forms.enabled'),
|
|
148
|
+
value: 'enabled',
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
text: this.$t(
|
|
152
|
+
'windward.integrations.components.external_integration.grade_sync'
|
|
153
|
+
),
|
|
154
|
+
value: 'grade_sync',
|
|
155
|
+
},
|
|
156
|
+
{ text: this.$t('shared.forms.created'), value: 'created_at' },
|
|
157
|
+
{
|
|
158
|
+
text: this.$t('shared.forms.actions'),
|
|
159
|
+
value: 'actions',
|
|
160
|
+
sortable: false,
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
async fetch() {
|
|
167
|
+
if (
|
|
168
|
+
!this.$PermissionService.userHasAccessTo(
|
|
169
|
+
'plugin.windward.integrations.course.externalIntegration',
|
|
170
|
+
'readable'
|
|
171
|
+
) ||
|
|
172
|
+
_.isEmpty(this.organization.id) ||
|
|
173
|
+
_.isEmpty(this.course.id)
|
|
174
|
+
) {
|
|
175
|
+
// Display an angry error that they can't view this driver
|
|
176
|
+
this.$dialog.error(this.$t('shared.error.description_401'), {
|
|
177
|
+
duration: null,
|
|
178
|
+
action: {
|
|
179
|
+
text: this.$t('shared.forms.close'),
|
|
180
|
+
onClick: (_e, toastObject) => {
|
|
181
|
+
toastObject.goAway(0)
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
})
|
|
185
|
+
if (_.isEmpty(this.organization.id) || _.isEmpty(this.course.id)) {
|
|
186
|
+
// eslint-disable-next-line no-console
|
|
187
|
+
console.error(
|
|
188
|
+
'Cannot load external integrations because organization or course is not set!'
|
|
189
|
+
)
|
|
190
|
+
} else {
|
|
191
|
+
// eslint-disable-next-line no-console
|
|
192
|
+
console.error(
|
|
193
|
+
'You do not have access to this external integration!'
|
|
194
|
+
)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Return so we don't even attempt loading
|
|
198
|
+
return false
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
await this.loadProviders()
|
|
202
|
+
},
|
|
203
|
+
computed: {
|
|
204
|
+
...mapGetters({
|
|
205
|
+
organization: 'organization/get',
|
|
206
|
+
course: 'course/get',
|
|
207
|
+
}),
|
|
208
|
+
},
|
|
209
|
+
methods: {
|
|
210
|
+
onSaved() {
|
|
211
|
+
this.loadProviders()
|
|
212
|
+
},
|
|
213
|
+
async loadProviders() {
|
|
214
|
+
this.providers = await new LtiProvider()
|
|
215
|
+
.for(
|
|
216
|
+
new Organization({ id: this.organization.id }),
|
|
217
|
+
new Course({ id: this.course.id })
|
|
218
|
+
)
|
|
219
|
+
.where('version', '1.3')
|
|
220
|
+
.get()
|
|
221
|
+
},
|
|
222
|
+
onConfirmDelete(provider) {
|
|
223
|
+
this.$dialog.show(this.$t('shared.forms.confirm_delete_text'), {
|
|
224
|
+
icon: 'mdi-help',
|
|
225
|
+
duration: null,
|
|
226
|
+
action: [
|
|
227
|
+
{
|
|
228
|
+
text: this.$t('shared.forms.cancel'),
|
|
229
|
+
onClick: (_e, toastObject) => {
|
|
230
|
+
toastObject.goAway(0)
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
text: this.$t('shared.forms.confirm'),
|
|
235
|
+
// router navigation
|
|
236
|
+
onClick: (_e, toastObject) => {
|
|
237
|
+
this.deleteProvider(provider)
|
|
238
|
+
toastObject.goAway(0)
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
],
|
|
242
|
+
})
|
|
243
|
+
},
|
|
244
|
+
async deleteProvider(provider) {
|
|
245
|
+
await provider.delete()
|
|
246
|
+
this.$dialog.success(this.$t('shared.response.deleted'))
|
|
247
|
+
// Reload providers now that we deleted one
|
|
248
|
+
this.loadProviders()
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
}
|
|
252
|
+
</script>
|
|
253
|
+
|
|
254
|
+
<style scoped>
|
|
255
|
+
.field--target {
|
|
256
|
+
max-width: 15em;
|
|
257
|
+
display: inline-block;
|
|
258
|
+
}
|
|
259
|
+
</style>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<v-expansion-panels v-model="panel">
|
|
4
|
+
<v-expansion-panel>
|
|
5
|
+
<v-expansion-panel-header>
|
|
6
|
+
{{
|
|
7
|
+
$t(
|
|
8
|
+
'windward.integrations.components.external_integration.provider_panel_title'
|
|
9
|
+
)
|
|
10
|
+
}}
|
|
11
|
+
</v-expansion-panel-header>
|
|
12
|
+
<v-expansion-panel-content>
|
|
13
|
+
<ManageProviders></ManageProviders>
|
|
14
|
+
</v-expansion-panel-content>
|
|
15
|
+
</v-expansion-panel>
|
|
16
|
+
<v-expansion-panel>
|
|
17
|
+
<v-expansion-panel-header>
|
|
18
|
+
{{
|
|
19
|
+
$t(
|
|
20
|
+
'windward.integrations.components.external_integration.consumer_panel_title'
|
|
21
|
+
)
|
|
22
|
+
}}
|
|
23
|
+
</v-expansion-panel-header>
|
|
24
|
+
<v-expansion-panel-content>
|
|
25
|
+
<!-- <ManageConsumers></ManageConsumers>-->
|
|
26
|
+
</v-expansion-panel-content>
|
|
27
|
+
</v-expansion-panel>
|
|
28
|
+
</v-expansion-panels>
|
|
29
|
+
</div>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<script>
|
|
33
|
+
import ManageProviders from './Lti1p3/ManageProviders.vue'
|
|
34
|
+
/* import ManageConsumers from './Lti1p3/ManageConsumers.vue' */
|
|
35
|
+
|
|
36
|
+
export default {
|
|
37
|
+
name: 'ManageLti1p3Driver',
|
|
38
|
+
components: { ManageProviders },
|
|
39
|
+
data() {
|
|
40
|
+
return {
|
|
41
|
+
panel: 0,
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
}
|
|
45
|
+
</script>
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
/>
|
|
17
17
|
|
|
18
18
|
<v-text-field
|
|
19
|
+
ref="atutor_url"
|
|
19
20
|
v-model="integration.metadata.config.url"
|
|
20
21
|
:label="
|
|
21
22
|
$t(
|
|
@@ -27,6 +28,7 @@
|
|
|
27
28
|
'windward.integrations.components.integration.driver.atutor.url_hint'
|
|
28
29
|
)
|
|
29
30
|
"
|
|
31
|
+
:rules="urlValidation"
|
|
30
32
|
></v-text-field>
|
|
31
33
|
<v-text-field
|
|
32
34
|
v-model="integration.metadata.config.username"
|
|
@@ -47,6 +49,7 @@
|
|
|
47
49
|
></v-text-field>
|
|
48
50
|
|
|
49
51
|
<v-text-field
|
|
52
|
+
ref="aws-url"
|
|
50
53
|
v-model="integration.metadata.config.aws_secure_url"
|
|
51
54
|
:label="
|
|
52
55
|
$t(
|
|
@@ -58,6 +61,7 @@
|
|
|
58
61
|
'windward.integrations.components.integration.driver.atutor.aws_secure_url_hint'
|
|
59
62
|
)
|
|
60
63
|
"
|
|
64
|
+
:rules="urlValidation"
|
|
61
65
|
></v-text-field>
|
|
62
66
|
|
|
63
67
|
<v-switch
|
|
@@ -100,6 +104,17 @@ export default {
|
|
|
100
104
|
// integration: { metadata: {...} } The integration object to write to. Defined and loaded in ManageBase.vue
|
|
101
105
|
errorMessage: '',
|
|
102
106
|
testConnectionLoading: false,
|
|
107
|
+
urlValidation: [
|
|
108
|
+
(value) => {
|
|
109
|
+
if (value && value.slice(-1) === '/') {
|
|
110
|
+
return this.$t(
|
|
111
|
+
'windward.integrations.components.integration.driver.remove_slash'
|
|
112
|
+
)
|
|
113
|
+
} else {
|
|
114
|
+
return true
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
],
|
|
103
118
|
}
|
|
104
119
|
},
|
|
105
120
|
methods: {
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<v-btn color="primary" outlined @click="onViewLog()">
|
|
4
|
+
<v-icon>mdi-note-search</v-icon>
|
|
5
|
+
</v-btn>
|
|
6
|
+
<Dialog v-model="logDialog" :trigger="false">
|
|
7
|
+
<template #title>{{
|
|
8
|
+
$t('windward.integrations.components.integration.job.view_log')
|
|
9
|
+
}}</template>
|
|
10
|
+
<template #form>
|
|
11
|
+
<v-progress-circular v-if="loading" size="128" indeterminate />
|
|
12
|
+
<div v-if="!loading">
|
|
13
|
+
<SearchField v-model="search" hide-filters></SearchField>
|
|
14
|
+
|
|
15
|
+
<v-alert
|
|
16
|
+
v-for="logItem in filteredLog"
|
|
17
|
+
:key="logItem.id"
|
|
18
|
+
:type="logItem.level"
|
|
19
|
+
>
|
|
20
|
+
{{ logItem.message }}
|
|
21
|
+
</v-alert>
|
|
22
|
+
|
|
23
|
+
<p v-if="filteredLog.length === 0">
|
|
24
|
+
{{
|
|
25
|
+
$t(
|
|
26
|
+
'windward.integrations.components.integration.job.log_no_results'
|
|
27
|
+
)
|
|
28
|
+
}}
|
|
29
|
+
</p>
|
|
30
|
+
</div>
|
|
31
|
+
</template>
|
|
32
|
+
</Dialog>
|
|
33
|
+
</div>
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<script>
|
|
37
|
+
import { mapGetters } from 'vuex'
|
|
38
|
+
import SearchField from '~/components/SearchField.vue'
|
|
39
|
+
import Organization from '../../models/Organization'
|
|
40
|
+
|
|
41
|
+
export default {
|
|
42
|
+
components: { SearchField },
|
|
43
|
+
name: 'IntegrationJobLog',
|
|
44
|
+
props: {
|
|
45
|
+
id: { type: String, required: true },
|
|
46
|
+
},
|
|
47
|
+
data() {
|
|
48
|
+
return {
|
|
49
|
+
search: {},
|
|
50
|
+
loading: true,
|
|
51
|
+
log: [],
|
|
52
|
+
logDialog: false,
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
computed: {
|
|
56
|
+
...mapGetters({
|
|
57
|
+
organization: 'organization/get',
|
|
58
|
+
}),
|
|
59
|
+
filteredLog() {
|
|
60
|
+
if (!this.search.term || this.search.term.length < 3) {
|
|
61
|
+
return this.log
|
|
62
|
+
}
|
|
63
|
+
const filtered = this.log.filter((item) => {
|
|
64
|
+
return item.message
|
|
65
|
+
.toLowerCase()
|
|
66
|
+
.includes(this.search.term.toLowerCase())
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
return filtered
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
methods: {
|
|
73
|
+
async onViewLog() {
|
|
74
|
+
this.logDialog = true
|
|
75
|
+
this.log = []
|
|
76
|
+
|
|
77
|
+
const job = await new Organization({
|
|
78
|
+
id: this.organization.id,
|
|
79
|
+
})
|
|
80
|
+
.integrationJobs()
|
|
81
|
+
.with('log')
|
|
82
|
+
.find(this.id)
|
|
83
|
+
|
|
84
|
+
this.log = job.log
|
|
85
|
+
this.loading = false
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
}
|
|
89
|
+
</script>
|
|
90
|
+
|
|
91
|
+
<style scoped>
|
|
92
|
+
.col-progress {
|
|
93
|
+
min-width: 200px;
|
|
94
|
+
}
|
|
95
|
+
.col-details {
|
|
96
|
+
max-width: 100px;
|
|
97
|
+
}
|
|
98
|
+
</style>
|
|
@@ -42,7 +42,14 @@
|
|
|
42
42
|
<th class="text-left">
|
|
43
43
|
{{
|
|
44
44
|
$t(
|
|
45
|
-
'windward.integrations.components.integration.job.
|
|
45
|
+
'windward.integrations.components.integration.job.started'
|
|
46
|
+
)
|
|
47
|
+
}}
|
|
48
|
+
</th>
|
|
49
|
+
<th class="text-left">
|
|
50
|
+
{{
|
|
51
|
+
$t(
|
|
52
|
+
'windward.integrations.components.integration.job.view_log'
|
|
46
53
|
)
|
|
47
54
|
}}
|
|
48
55
|
</th>
|
|
@@ -119,6 +126,9 @@
|
|
|
119
126
|
{{ jobDetails(item) }}
|
|
120
127
|
</td>
|
|
121
128
|
<td>{{ $d(new Date(item.created_at), 'long') }}</td>
|
|
129
|
+
<td>
|
|
130
|
+
<JobLog :id="item.id"></JobLog>
|
|
131
|
+
</td>
|
|
122
132
|
</tr>
|
|
123
133
|
</tbody>
|
|
124
134
|
</template>
|
|
@@ -132,9 +142,11 @@ import _ from 'lodash'
|
|
|
132
142
|
import { mapGetters } from 'vuex'
|
|
133
143
|
import Vendor from '../../models/Vendor'
|
|
134
144
|
import Organization from '../../models/Organization'
|
|
145
|
+
import JobLog from './JobLog.vue'
|
|
135
146
|
|
|
136
147
|
export default {
|
|
137
148
|
name: 'IntegrationJobs',
|
|
149
|
+
components: { JobLog },
|
|
138
150
|
props: {
|
|
139
151
|
channel: { type: String, required: true },
|
|
140
152
|
event: { type: String, required: true },
|
|
@@ -145,6 +157,8 @@ export default {
|
|
|
145
157
|
vendors: [],
|
|
146
158
|
orgIntegrations: [],
|
|
147
159
|
jobs: [],
|
|
160
|
+
log: [],
|
|
161
|
+
logDialog: false,
|
|
148
162
|
}
|
|
149
163
|
},
|
|
150
164
|
async fetch() {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
key: 'Key',
|
|
3
|
+
tool_public_keyset_url: 'Tool Keyset Url',
|
|
4
|
+
tool_oidc_auth_endpoint: 'Tool OpenID Connect Endpoint',
|
|
5
|
+
platform_public_keyset_url: 'Platform Keyset Url',
|
|
6
|
+
platform_oidc_auth_endpoint: 'Platform OpenID Connect Endpoint',
|
|
7
|
+
platform_client_id: 'Platform Client ID',
|
|
8
|
+
platform_deployment_id: 'Platform Deployment ID',
|
|
9
|
+
parameter_name: 'Custom Parameter Name',
|
|
10
|
+
value: 'Value',
|
|
11
|
+
new: 'New LTI Link',
|
|
12
|
+
edit: 'Edit LTI Link',
|
|
13
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import lti1p1 from './driver/lti1p1'
|
|
2
|
+
import lti1p3 from './driver/lti1p3'
|
|
2
3
|
import providerTarget from './provider_target'
|
|
3
4
|
export default {
|
|
4
|
-
driver: { lti1p1 },
|
|
5
|
+
driver: { lti1p1, lti1p3 },
|
|
5
6
|
provider_target: providerTarget,
|
|
6
7
|
|
|
7
8
|
provider_panel_title: 'Provider (Students incoming to Windward)',
|
|
@@ -8,6 +8,9 @@ export default {
|
|
|
8
8
|
progress: 'Progress',
|
|
9
9
|
created: 'Created',
|
|
10
10
|
details: 'Details',
|
|
11
|
+
started: 'Date started',
|
|
12
|
+
view_log: 'View Log',
|
|
13
|
+
log_no_results: 'No results found',
|
|
11
14
|
job_details: {
|
|
12
15
|
none: 'No details available',
|
|
13
16
|
import_course: "Importing Course Id {0} '{1}'",
|
|
@@ -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 LtiProvider 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-integrations/lti/
|
|
11
|
+
return 'external-integrations/lti/providers'
|
|
12
12
|
}
|
|
13
13
|
}
|
package/package.json
CHANGED
|
@@ -164,13 +164,13 @@
|
|
|
164
164
|
<script>
|
|
165
165
|
import _ from 'lodash'
|
|
166
166
|
import { mapGetters } from 'vuex'
|
|
167
|
-
import Course from '~/models/Course'
|
|
168
167
|
import Organization from '../../models/Organization'
|
|
169
168
|
import OrganizationIntegration from '../../models/OrganizationIntegration'
|
|
170
169
|
import RemoteOrganization from '../../models/RemoteOrganization'
|
|
171
170
|
import RemoteCourse from '../../models/RemoteCourse'
|
|
172
171
|
import RemoteContent from '../../models/RemoteContent'
|
|
173
172
|
import IntegrationJobTable from '../../components/Integration/JobTable.vue'
|
|
173
|
+
import Course from '~/models/Course'
|
|
174
174
|
|
|
175
175
|
export default {
|
|
176
176
|
name: 'PluginIntegrationsAdminImportCoursePage',
|
package/pages/admin/vendors.vue
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
+
<Breadcrumbs></Breadcrumbs>
|
|
3
4
|
<v-row justify="center" align="center">
|
|
4
5
|
<v-col cols="12">
|
|
5
6
|
<div class="d-flex mb-5">
|
|
@@ -150,14 +151,14 @@
|
|
|
150
151
|
<script>
|
|
151
152
|
import _ from 'lodash'
|
|
152
153
|
import { mapGetters } from 'vuex'
|
|
153
|
-
|
|
154
|
+
import Breadcrumbs from '~/components/Breadcrumbs.vue'
|
|
154
155
|
import Dialog from '~/components/Dialog.vue'
|
|
155
156
|
import Organization from '../../models/Organization'
|
|
156
157
|
import IntegrationJobTable from '../../components/Integration/JobTable.vue'
|
|
157
158
|
|
|
158
159
|
export default {
|
|
159
160
|
name: 'PluginIntegrationsAdminVendorsPage',
|
|
160
|
-
components: { Dialog, IntegrationJobTable },
|
|
161
|
+
components: { Dialog, IntegrationJobTable, Breadcrumbs },
|
|
161
162
|
layout: 'authenticated',
|
|
162
163
|
meta: {
|
|
163
164
|
privilege: {
|
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
<v-tabs-items v-model="tab">
|
|
39
39
|
<v-tab-item> <ManageLti1p1></ManageLti1p1> </v-tab-item>
|
|
40
40
|
<v-tab-item>
|
|
41
|
-
<
|
|
41
|
+
<ManageLti1p3 />
|
|
42
|
+
<!-- <p class="ma-5">LTI 1.3 Not yet implemented</p>-->
|
|
42
43
|
</v-tab-item>
|
|
43
44
|
<v-tab-item>
|
|
44
45
|
<p class="ma-5">SCORM 1.2 Not yet implemented</p>
|
|
@@ -49,10 +50,10 @@
|
|
|
49
50
|
|
|
50
51
|
<script>
|
|
51
52
|
import ManageLti1p1 from '../../../components/ExternalIntegration/Driver/ManageLti1p1.vue'
|
|
52
|
-
|
|
53
|
+
import ManageLti1p3 from '../../../components/ExternalIntegration/Driver/ManageLti1p3.vue'
|
|
53
54
|
export default {
|
|
54
55
|
name: 'PluginIntegrationsExternalIntegrationIndexPage',
|
|
55
|
-
components: { ManageLti1p1 },
|
|
56
|
+
components: { ManageLti1p1, ManageLti1p3 },
|
|
56
57
|
layout: 'authenticated',
|
|
57
58
|
meta: {
|
|
58
59
|
privilege: {
|