@windward/integrations 0.0.8 → 0.0.10
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/FileImport/Dropbox.vue +9 -0
- package/components/FileImport/FileImportMenu.vue +111 -0
- package/components/FileImport/GoogleDrive.vue +9 -0
- package/components/FileImport/Resourcespace.vue +202 -0
- package/components/Integration/Driver/ManageAtutor.vue +35 -12
- package/components/Integration/Driver/ManageResourcespace.vue +137 -0
- package/components/Integration/JobLog.vue +281 -0
- package/components/Integration/JobTable.vue +15 -1
- package/components/SecretField.vue +1 -0
- package/config/integration.config.js +2 -0
- package/helpers/Driver/Resourcespace.ts +15 -0
- 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/file_import/index.ts +5 -0
- package/i18n/en-US/components/file_import/resourcespace.ts +4 -0
- package/i18n/en-US/components/index.ts +2 -0
- package/i18n/en-US/components/integration/driver.ts +8 -0
- package/i18n/en-US/components/integration/index.ts +2 -0
- package/i18n/en-US/components/integration/job.ts +1 -0
- package/i18n/en-US/components/integration/job_log.ts +8 -0
- package/i18n/en-US/shared/error.ts +1 -0
- package/i18n/en-US/shared/file.ts +5 -0
- package/i18n/en-US/shared/index.ts +2 -0
- package/models/ExternalIntegration/{Lti1p1Provider.ts → LtiProvider.ts} +2 -2
- package/models/OrganizationIntegration.ts +5 -0
- package/models/RemoteFile.ts +12 -0
- package/package.json +1 -1
- package/pages/admin/importCourse.vue +8 -2
- package/pages/admin/vendors.vue +3 -2
- package/pages/course/externalIntegration/index.vue +4 -3
- package/plugin.js +84 -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/FileImport/Dropbox.spec.js +24 -0
- package/test/Components/FileImport/GoogleDrive.spec.js +24 -0
- package/test/Components/FileImport/Resourcespace.spec.js +24 -0
- package/test/Components/Integration/Driver/ManageAtutor.spec.js +22 -0
- package/test/Components/Integration/Driver/ManageResourcespace.spec.js +22 -0
- package/test/Components/Integration/JobLog.spec.js +22 -0
- package/test/Components/Integration/JobTable.spec.js +23 -0
- package/test/__mocks__/componentsMock.js +24 -0
- package/test/__mocks__/modelMock.js +1 -0
- package/test/mocks.js +12 -0
|
@@ -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: {
|
|
@@ -115,21 +130,29 @@ export default {
|
|
|
115
130
|
},
|
|
116
131
|
async onTestConnection() {
|
|
117
132
|
this.testConnectionLoading = true
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
133
|
+
let response = { result: false }
|
|
134
|
+
try {
|
|
135
|
+
response = await this.testConnection(this.integration.metadata)
|
|
121
136
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
137
|
+
if (response.result) {
|
|
138
|
+
this.errorMessage = ''
|
|
139
|
+
this.$dialog.success(
|
|
140
|
+
this.$t(
|
|
141
|
+
'windward.integrations.shared.error.connect_success'
|
|
142
|
+
)
|
|
127
143
|
)
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
144
|
+
} else {
|
|
145
|
+
this.errorMessage = response.message
|
|
146
|
+
this.$dialog.error(
|
|
147
|
+
this.$t(
|
|
148
|
+
'windward.integrations.shared.error.connect_fail'
|
|
149
|
+
)
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
} catch (e) {
|
|
153
|
+
console.error(e)
|
|
131
154
|
this.$dialog.error(
|
|
132
|
-
this.$t('windward.integrations.shared.error.
|
|
155
|
+
this.$t('windward.integrations.shared.error.unknown')
|
|
133
156
|
)
|
|
134
157
|
}
|
|
135
158
|
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div v-if="!render" class="integration-loading">
|
|
4
|
+
<v-progress-circular size="128" indeterminate />
|
|
5
|
+
</div>
|
|
6
|
+
<div v-if="render">
|
|
7
|
+
<v-row justify="center" align="center" class="mt-5">
|
|
8
|
+
<v-col cols="12">
|
|
9
|
+
<v-switch
|
|
10
|
+
v-model="integration.enabled"
|
|
11
|
+
:label="
|
|
12
|
+
$t(
|
|
13
|
+
'windward.integrations.components.integration.driver.enabled'
|
|
14
|
+
)
|
|
15
|
+
"
|
|
16
|
+
/>
|
|
17
|
+
|
|
18
|
+
<v-text-field
|
|
19
|
+
v-model="integration.metadata.config.url"
|
|
20
|
+
:label="
|
|
21
|
+
$t(
|
|
22
|
+
'windward.integrations.components.integration.driver.resourcespace.url'
|
|
23
|
+
)
|
|
24
|
+
"
|
|
25
|
+
:hint="
|
|
26
|
+
$t(
|
|
27
|
+
'windward.integrations.components.integration.driver.resourcespace.url_hint'
|
|
28
|
+
)
|
|
29
|
+
"
|
|
30
|
+
></v-text-field>
|
|
31
|
+
<v-text-field
|
|
32
|
+
v-model="integration.metadata.config.username"
|
|
33
|
+
:label="
|
|
34
|
+
$t(
|
|
35
|
+
'windward.integrations.components.integration.driver.resourcespace.username'
|
|
36
|
+
)
|
|
37
|
+
"
|
|
38
|
+
></v-text-field>
|
|
39
|
+
<v-text-field
|
|
40
|
+
v-model="integration.metadata.config.key"
|
|
41
|
+
:label="
|
|
42
|
+
$t(
|
|
43
|
+
'windward.integrations.components.integration.driver.resourcespace.key'
|
|
44
|
+
)
|
|
45
|
+
"
|
|
46
|
+
type="password"
|
|
47
|
+
></v-text-field>
|
|
48
|
+
|
|
49
|
+
<v-switch
|
|
50
|
+
v-model="integration.metadata.config.ssl"
|
|
51
|
+
:label="
|
|
52
|
+
$t(
|
|
53
|
+
'windward.integrations.components.integration.driver.ssl_enabled'
|
|
54
|
+
)
|
|
55
|
+
"
|
|
56
|
+
/>
|
|
57
|
+
|
|
58
|
+
<TestConnection
|
|
59
|
+
:disabled="
|
|
60
|
+
!integration.metadata.config.url ||
|
|
61
|
+
!integration.metadata.config.username ||
|
|
62
|
+
!integration.metadata.config.key
|
|
63
|
+
"
|
|
64
|
+
:loading="testConnectionLoading"
|
|
65
|
+
:errors="errorMessage"
|
|
66
|
+
@click="onTestConnection"
|
|
67
|
+
></TestConnection>
|
|
68
|
+
</v-col>
|
|
69
|
+
</v-row>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</template>
|
|
73
|
+
|
|
74
|
+
<script>
|
|
75
|
+
import TestConnection from '../TestConnection.vue'
|
|
76
|
+
import ManageBaseVue from './ManageBase.vue'
|
|
77
|
+
|
|
78
|
+
export default {
|
|
79
|
+
name: 'ManageResourcespaceDriver',
|
|
80
|
+
components: { TestConnection },
|
|
81
|
+
extends: ManageBaseVue,
|
|
82
|
+
data() {
|
|
83
|
+
return {
|
|
84
|
+
// formValid: true|false If this form is "complete" and passed validation on THIS component. Defined and watched in ManageBase.vue
|
|
85
|
+
// render: true|false If we should show the form aka when validation has passed. Defined and managed in ManageBase.vue
|
|
86
|
+
// integration: { metadata: {...} } The integration object to write to. Defined and loaded in ManageBase.vue
|
|
87
|
+
errorMessage: '',
|
|
88
|
+
testConnectionLoading: false,
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
methods: {
|
|
92
|
+
/**
|
|
93
|
+
* Lifecycle event called from ManageBase.vue when async fetch() completes.
|
|
94
|
+
* Once called this.integration will be available containing the integration model (or a new one)
|
|
95
|
+
*/
|
|
96
|
+
onIntegrationLoaded() {
|
|
97
|
+
// Set SSL to enabled by default
|
|
98
|
+
if (_.get(this.integration.metadata.config, 'ssl', null) === null) {
|
|
99
|
+
this.integration.metadata.config.ssl = true
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
async onTestConnection() {
|
|
103
|
+
this.testConnectionLoading = true
|
|
104
|
+
let response = { result: false }
|
|
105
|
+
try {
|
|
106
|
+
response = await this.testConnection(this.integration.metadata)
|
|
107
|
+
|
|
108
|
+
if (response.result) {
|
|
109
|
+
this.errorMessage = ''
|
|
110
|
+
this.$dialog.success(
|
|
111
|
+
this.$t(
|
|
112
|
+
'windward.integrations.shared.error.connect_success'
|
|
113
|
+
)
|
|
114
|
+
)
|
|
115
|
+
} else {
|
|
116
|
+
this.errorMessage = response.message
|
|
117
|
+
this.$dialog.error(
|
|
118
|
+
this.$t(
|
|
119
|
+
'windward.integrations.shared.error.connect_fail'
|
|
120
|
+
)
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
} catch (e) {
|
|
124
|
+
console.error(e)
|
|
125
|
+
this.$dialog.error(
|
|
126
|
+
this.$t('windward.integrations.shared.error.unknown')
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// We will indirectly validate the form via connection tests
|
|
131
|
+
// That way we can 100% confirm that the integration is valid
|
|
132
|
+
this.formValid = response.result
|
|
133
|
+
this.testConnectionLoading = false
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
}
|
|
137
|
+
</script>
|
|
@@ -0,0 +1,281 @@
|
|
|
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(
|
|
9
|
+
'windward.integrations.components.integration.job_log.view_log'
|
|
10
|
+
)
|
|
11
|
+
}}</template>
|
|
12
|
+
<template #form="{ on, attrs }">
|
|
13
|
+
<div v-bind="attrs" v-on="on">
|
|
14
|
+
<v-progress-circular
|
|
15
|
+
v-if="loading"
|
|
16
|
+
size="128"
|
|
17
|
+
indeterminate
|
|
18
|
+
/>
|
|
19
|
+
<div v-if="!loading">
|
|
20
|
+
<SearchField
|
|
21
|
+
v-model="search"
|
|
22
|
+
hide-filters
|
|
23
|
+
></SearchField>
|
|
24
|
+
|
|
25
|
+
<v-alert
|
|
26
|
+
v-for="logItem in filteredLog"
|
|
27
|
+
:key="logItem.id"
|
|
28
|
+
:type="logItem.level"
|
|
29
|
+
:icon="logItemIcon(logItem)"
|
|
30
|
+
class="log-item"
|
|
31
|
+
>
|
|
32
|
+
<p>{{ logItem.message }}</p>
|
|
33
|
+
<div v-if="showDetails(logItem)">
|
|
34
|
+
<v-divider class="mt-1 mb-1" />
|
|
35
|
+
<p
|
|
36
|
+
v-if="
|
|
37
|
+
logItem.context.remote_content &&
|
|
38
|
+
remoteCourse
|
|
39
|
+
"
|
|
40
|
+
>
|
|
41
|
+
{{
|
|
42
|
+
$t(
|
|
43
|
+
'windward.integrations.components.integration.job_log.remote_course_id'
|
|
44
|
+
)
|
|
45
|
+
}}
|
|
46
|
+
{{ remoteCourse.id }}
|
|
47
|
+
</p>
|
|
48
|
+
<p v-if="logItem.context.remote_content">
|
|
49
|
+
{{
|
|
50
|
+
$t(
|
|
51
|
+
'windward.integrations.components.integration.job_log.remote_content_id'
|
|
52
|
+
)
|
|
53
|
+
}}
|
|
54
|
+
{{ logItem.context.remote_content.id }}
|
|
55
|
+
</p>
|
|
56
|
+
<p v-if="logItem.context.remote_url">
|
|
57
|
+
{{
|
|
58
|
+
$t(
|
|
59
|
+
'windward.integrations.components.integration.job_log.remote_url'
|
|
60
|
+
)
|
|
61
|
+
}}
|
|
62
|
+
<v-chip
|
|
63
|
+
:href="
|
|
64
|
+
isUrl(logItem.context.remote_url)
|
|
65
|
+
? logItem.context.remote_url
|
|
66
|
+
: undefined
|
|
67
|
+
"
|
|
68
|
+
label
|
|
69
|
+
target="_blank"
|
|
70
|
+
>
|
|
71
|
+
<span
|
|
72
|
+
class="d-inline-block text-truncate chip-truncate"
|
|
73
|
+
>
|
|
74
|
+
{{ logItem.context.remote_url }}
|
|
75
|
+
</span>
|
|
76
|
+
|
|
77
|
+
<v-icon
|
|
78
|
+
v-if="
|
|
79
|
+
isUrl(
|
|
80
|
+
logItem.context.remote_url
|
|
81
|
+
)
|
|
82
|
+
"
|
|
83
|
+
class="ml-2"
|
|
84
|
+
>
|
|
85
|
+
mdi-launch
|
|
86
|
+
</v-icon>
|
|
87
|
+
</v-chip>
|
|
88
|
+
</p>
|
|
89
|
+
<div v-if="logItem.context.remote_code">
|
|
90
|
+
<p>
|
|
91
|
+
{{
|
|
92
|
+
$t(
|
|
93
|
+
'windward.integrations.components.integration.job_log.remote_code'
|
|
94
|
+
)
|
|
95
|
+
}}
|
|
96
|
+
<v-btn
|
|
97
|
+
icon
|
|
98
|
+
@click="
|
|
99
|
+
onClickCopy(
|
|
100
|
+
logItem.context.remote_code
|
|
101
|
+
)
|
|
102
|
+
"
|
|
103
|
+
><v-icon class="ml-2">
|
|
104
|
+
mdi-content-copy
|
|
105
|
+
</v-icon>
|
|
106
|
+
<span class="sr-only">{{
|
|
107
|
+
$t('shared.forms.copy')
|
|
108
|
+
}}</span>
|
|
109
|
+
</v-btn>
|
|
110
|
+
</p>
|
|
111
|
+
<div class="remote-code grey darken-3">
|
|
112
|
+
<code
|
|
113
|
+
class="grey darken-3"
|
|
114
|
+
v-text="logItem.context.remote_code"
|
|
115
|
+
></code>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
</v-alert>
|
|
120
|
+
|
|
121
|
+
<p v-if="filteredLog.length === 0">
|
|
122
|
+
{{
|
|
123
|
+
$t(
|
|
124
|
+
'windward.integrations.components.integration.job_log.no_results'
|
|
125
|
+
)
|
|
126
|
+
}}
|
|
127
|
+
</p>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
</template>
|
|
131
|
+
</Dialog>
|
|
132
|
+
</div>
|
|
133
|
+
</template>
|
|
134
|
+
|
|
135
|
+
<script>
|
|
136
|
+
import _ from 'lodash'
|
|
137
|
+
import { mapGetters } from 'vuex'
|
|
138
|
+
import SearchField from '~/components/SearchField.vue'
|
|
139
|
+
import Organization from '../../models/Organization'
|
|
140
|
+
|
|
141
|
+
export default {
|
|
142
|
+
name: 'IntegrationJobLog',
|
|
143
|
+
components: { SearchField },
|
|
144
|
+
props: {
|
|
145
|
+
id: { type: String, required: true },
|
|
146
|
+
},
|
|
147
|
+
data() {
|
|
148
|
+
return {
|
|
149
|
+
search: {},
|
|
150
|
+
loading: true,
|
|
151
|
+
job: {},
|
|
152
|
+
log: [],
|
|
153
|
+
logDialog: false,
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
computed: {
|
|
157
|
+
...mapGetters({
|
|
158
|
+
organization: 'organization/get',
|
|
159
|
+
}),
|
|
160
|
+
filteredLog() {
|
|
161
|
+
if (!this.search.term || this.search.term.length < 3) {
|
|
162
|
+
return this.job.log || []
|
|
163
|
+
}
|
|
164
|
+
const filtered = this.job.log.filter((item) => {
|
|
165
|
+
let match = item.message
|
|
166
|
+
.toLowerCase()
|
|
167
|
+
.includes(this.search.term.toLowerCase())
|
|
168
|
+
|
|
169
|
+
// Search the remote course id
|
|
170
|
+
if (!match && _.get(item, 'context.remote_course.id', null)) {
|
|
171
|
+
match = _.get(item, 'context.remote_course.id', '')
|
|
172
|
+
.toString()
|
|
173
|
+
.toLowerCase()
|
|
174
|
+
.includes(this.search.term.toLowerCase())
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Search the remote assessment id
|
|
178
|
+
if (
|
|
179
|
+
!match &&
|
|
180
|
+
_.get(item, 'context.remote_assessment.id', null)
|
|
181
|
+
) {
|
|
182
|
+
match = _.get(item, 'context.remote_assessment.id', '')
|
|
183
|
+
.toString()
|
|
184
|
+
.toLowerCase()
|
|
185
|
+
.includes(this.search.term.toLowerCase())
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Search the remote url
|
|
189
|
+
if (!match && item.context.remote_url) {
|
|
190
|
+
match = item.context.remote_url
|
|
191
|
+
.toLowerCase()
|
|
192
|
+
.includes(this.search.term.toLowerCase())
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Search the remote code
|
|
196
|
+
if (!match && item.context.remote_code) {
|
|
197
|
+
match = item.context.remote_code
|
|
198
|
+
.toLowerCase()
|
|
199
|
+
.includes(this.search.term.toLowerCase())
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return match
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
return filtered
|
|
206
|
+
},
|
|
207
|
+
remoteCourse() {
|
|
208
|
+
return _.get(this.job, 'metadata.import.remote_course', {})
|
|
209
|
+
},
|
|
210
|
+
localCourse() {
|
|
211
|
+
return _.get(this.job, 'metadata.import.local_course', {})
|
|
212
|
+
},
|
|
213
|
+
showDetails() {
|
|
214
|
+
return (item) => {
|
|
215
|
+
return (
|
|
216
|
+
(Array.isArray(item.context) && item.context.length > 0) ||
|
|
217
|
+
!_.isEmpty(item.context)
|
|
218
|
+
)
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
logItemIcon() {
|
|
222
|
+
return (logItem) => {
|
|
223
|
+
const type = _.get(logItem, 'context.type', null)
|
|
224
|
+
if (type === 'missing_file') {
|
|
225
|
+
return 'mdi-file-alert'
|
|
226
|
+
} else if (type === 'converted_file') {
|
|
227
|
+
return 'mdi-file-arrow-left-right'
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return undefined
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
isUrl() {
|
|
234
|
+
return (url) => {
|
|
235
|
+
return /https?:\/\//.test(url)
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
methods: {
|
|
240
|
+
async onViewLog() {
|
|
241
|
+
this.logDialog = true
|
|
242
|
+
this.job = {}
|
|
243
|
+
|
|
244
|
+
const job = await new Organization({
|
|
245
|
+
id: this.organization.id,
|
|
246
|
+
})
|
|
247
|
+
.integrationJobs()
|
|
248
|
+
.with('log')
|
|
249
|
+
.find(this.id)
|
|
250
|
+
|
|
251
|
+
this.job = job
|
|
252
|
+
this.loading = false
|
|
253
|
+
},
|
|
254
|
+
onClickCopy(data) {
|
|
255
|
+
navigator.clipboard.writeText(data)
|
|
256
|
+
this.$dialog.show(this.$t('shared.file.copied'))
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
}
|
|
260
|
+
</script>
|
|
261
|
+
|
|
262
|
+
<style scoped>
|
|
263
|
+
.col-progress {
|
|
264
|
+
min-width: 200px;
|
|
265
|
+
}
|
|
266
|
+
.col-details {
|
|
267
|
+
max-width: 100px;
|
|
268
|
+
}
|
|
269
|
+
.chip-truncate {
|
|
270
|
+
max-width: 40vw;
|
|
271
|
+
direction: rtl;
|
|
272
|
+
}
|
|
273
|
+
.log-item p {
|
|
274
|
+
margin-bottom: 0px;
|
|
275
|
+
}
|
|
276
|
+
.remote-code {
|
|
277
|
+
background: inherit;
|
|
278
|
+
max-width: 40vw;
|
|
279
|
+
padding: 4px;
|
|
280
|
+
}
|
|
281
|
+
</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_log.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() {
|
|
@@ -4,6 +4,7 @@ import Canvas from '../helpers/Driver/Canvas'
|
|
|
4
4
|
import Desire2Learn from '../helpers/Driver/Desire2Learn'
|
|
5
5
|
import Moodle from '../helpers/Driver/Moodle'
|
|
6
6
|
import GoogleClassroom from '../helpers/Driver/GoogleClassroom'
|
|
7
|
+
import Resourcespace from '../helpers/Driver/Resourcespace'
|
|
7
8
|
|
|
8
9
|
export default {
|
|
9
10
|
/**
|
|
@@ -20,5 +21,6 @@ export default {
|
|
|
20
21
|
desire2learn: { driver: Desire2Learn },
|
|
21
22
|
moodle: { driver: Moodle },
|
|
22
23
|
google_classroom: { driver: GoogleClassroom },
|
|
24
|
+
resourcespace: { driver: Resourcespace },
|
|
23
25
|
},
|
|
24
26
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
import Manage from '../../components/Integration/Driver/ManageResourcespace.vue'
|
|
3
|
+
import DriverInterface, { IntegrationComponents } from './DriverInterface'
|
|
4
|
+
import BaseDriver from './BaseDriver'
|
|
5
|
+
|
|
6
|
+
export default class Resourcespace
|
|
7
|
+
extends BaseDriver
|
|
8
|
+
implements DriverInterface
|
|
9
|
+
{
|
|
10
|
+
public components(): IntegrationComponents {
|
|
11
|
+
return {
|
|
12
|
+
Manage,
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -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)',
|
|
@@ -3,6 +3,7 @@ import settings from './settings'
|
|
|
3
3
|
import navigation from './navigation'
|
|
4
4
|
import integration from './integration'
|
|
5
5
|
import externalIntegration from './external_integration'
|
|
6
|
+
import fileImport from './file_import'
|
|
6
7
|
|
|
7
8
|
export default {
|
|
8
9
|
content,
|
|
@@ -10,4 +11,5 @@ export default {
|
|
|
10
11
|
navigation,
|
|
11
12
|
integration,
|
|
12
13
|
external_integration: externalIntegration,
|
|
14
|
+
file_import: fileImport,
|
|
13
15
|
}
|
|
@@ -8,6 +8,7 @@ export default {
|
|
|
8
8
|
aws_secure_url: 'AWS CDN Url',
|
|
9
9
|
aws_secure_url_hint: 'Eg: https://cdn-d.mindedgecollege.com',
|
|
10
10
|
},
|
|
11
|
+
remove_slash: 'Remove / at end of url',
|
|
11
12
|
atutor_wgu: {
|
|
12
13
|
manage_dialog_title: 'Manage ATutor WGU Integration',
|
|
13
14
|
},
|
|
@@ -26,6 +27,13 @@ export default {
|
|
|
26
27
|
google_classroom: {
|
|
27
28
|
manage_dialog_title: 'Manage Google Classroom Integration',
|
|
28
29
|
},
|
|
30
|
+
resourcespace: {
|
|
31
|
+
manage_dialog_title: 'Manage Resourcespace Integration',
|
|
32
|
+
url: 'Resourcespace Url',
|
|
33
|
+
url_hint: 'Eg: https://resourcespace.mindedgeuniversity.com',
|
|
34
|
+
username: 'Username',
|
|
35
|
+
key: 'API Key',
|
|
36
|
+
},
|
|
29
37
|
enabled: 'Integration Enabled',
|
|
30
38
|
disabled: 'Integration Disabled',
|
|
31
39
|
ssl_enabled: 'SSL Enabled (Should be enabled for production)',
|