@windward/integrations 0.0.10 → 0.0.11
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.
|
@@ -1,75 +1,99 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<v-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
3
|
+
<v-progress-circular v-if="loading" size="128" indeterminate />
|
|
4
|
+
<div v-if="!loading">
|
|
5
|
+
<SearchField
|
|
6
|
+
v-model="search"
|
|
7
|
+
:filters="filters"
|
|
8
|
+
:tags="levelTags"
|
|
9
|
+
:tag-label="
|
|
10
|
+
$t(
|
|
11
|
+
'windward.integrations.components.integration.job_log.log_level'
|
|
12
|
+
)
|
|
13
|
+
"
|
|
14
|
+
:tag-chip-label-prefix="
|
|
15
|
+
$t(
|
|
16
|
+
'windward.integrations.components.integration.job_log.level_prefix'
|
|
17
|
+
)
|
|
18
|
+
"
|
|
19
|
+
:tag-icon="'mdi-scale'"
|
|
20
|
+
></SearchField>
|
|
21
|
+
|
|
22
|
+
<v-alert
|
|
23
|
+
v-for="logItem in filteredLog"
|
|
24
|
+
:key="logItem.id"
|
|
25
|
+
:type="logItem.level"
|
|
26
|
+
:icon="logItemIcon(logItem)"
|
|
27
|
+
class="log-item"
|
|
28
|
+
>
|
|
29
|
+
<p>{{ logItem.message }}</p>
|
|
24
30
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
<
|
|
36
|
-
v-if="
|
|
37
|
-
logItem.context.remote_content &&
|
|
38
|
-
remoteCourse
|
|
39
|
-
"
|
|
40
|
-
>
|
|
31
|
+
<div v-if="showDetails(logItem)">
|
|
32
|
+
<v-divider class="mt-1 mb-1" />
|
|
33
|
+
<table class="log-table">
|
|
34
|
+
<tbody>
|
|
35
|
+
<tr
|
|
36
|
+
v-if="
|
|
37
|
+
logItem.context.remote_content &&
|
|
38
|
+
remoteCourse
|
|
39
|
+
"
|
|
40
|
+
>
|
|
41
|
+
<th class="text-left">
|
|
41
42
|
{{
|
|
42
43
|
$t(
|
|
43
44
|
'windward.integrations.components.integration.job_log.remote_course_id'
|
|
44
45
|
)
|
|
45
|
-
}}
|
|
46
|
+
}}:
|
|
47
|
+
</th>
|
|
48
|
+
<td>
|
|
46
49
|
{{ remoteCourse.id }}
|
|
47
|
-
</
|
|
48
|
-
|
|
50
|
+
</td>
|
|
51
|
+
</tr>
|
|
52
|
+
<tr v-if="logItem.context.remote_content">
|
|
53
|
+
<th class="text-left">
|
|
49
54
|
{{
|
|
50
55
|
$t(
|
|
51
56
|
'windward.integrations.components.integration.job_log.remote_content_id'
|
|
52
57
|
)
|
|
53
|
-
}}
|
|
58
|
+
}}:
|
|
59
|
+
</th>
|
|
60
|
+
<td>
|
|
54
61
|
{{ logItem.context.remote_content.id }}
|
|
55
|
-
</
|
|
56
|
-
|
|
62
|
+
</td>
|
|
63
|
+
</tr>
|
|
64
|
+
<tr v-if="logItem.context.remote_content">
|
|
65
|
+
<th class="text-left">
|
|
66
|
+
{{
|
|
67
|
+
$t(
|
|
68
|
+
'windward.integrations.components.integration.job_log.remote_content_name'
|
|
69
|
+
)
|
|
70
|
+
}}:
|
|
71
|
+
</th>
|
|
72
|
+
<td>
|
|
73
|
+
{{ logItem.context.remote_content.name }}
|
|
74
|
+
</td>
|
|
75
|
+
</tr>
|
|
76
|
+
<tr v-if="logItem.context.remote_url">
|
|
77
|
+
<th class="text-left">
|
|
57
78
|
{{
|
|
58
79
|
$t(
|
|
59
80
|
'windward.integrations.components.integration.job_log.remote_url'
|
|
60
81
|
)
|
|
61
|
-
}}
|
|
82
|
+
}}:
|
|
83
|
+
</th>
|
|
84
|
+
<td>
|
|
62
85
|
<v-chip
|
|
63
86
|
:href="
|
|
64
87
|
isUrl(logItem.context.remote_url)
|
|
65
88
|
? logItem.context.remote_url
|
|
66
89
|
: undefined
|
|
67
90
|
"
|
|
91
|
+
outlined
|
|
68
92
|
label
|
|
69
93
|
target="_blank"
|
|
70
94
|
>
|
|
71
95
|
<span
|
|
72
|
-
class="d-inline-block text-truncate chip-
|
|
96
|
+
class="d-inline-block text-truncate chip--truncate chip--truncate-left"
|
|
73
97
|
>
|
|
74
98
|
{{ logItem.context.remote_url }}
|
|
75
99
|
</span>
|
|
@@ -85,14 +109,18 @@
|
|
|
85
109
|
mdi-launch
|
|
86
110
|
</v-icon>
|
|
87
111
|
</v-chip>
|
|
88
|
-
</
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
112
|
+
</td>
|
|
113
|
+
</tr>
|
|
114
|
+
<tr v-if="logItem.context.remote_code">
|
|
115
|
+
<th class="text-left">
|
|
116
|
+
{{
|
|
117
|
+
$t(
|
|
118
|
+
'windward.integrations.components.integration.job_log.remote_code'
|
|
119
|
+
)
|
|
120
|
+
}}:
|
|
121
|
+
</th>
|
|
122
|
+
<td>
|
|
123
|
+
<div class="remote-code grey darken-3">
|
|
96
124
|
<v-btn
|
|
97
125
|
icon
|
|
98
126
|
@click="
|
|
@@ -107,28 +135,52 @@
|
|
|
107
135
|
$t('shared.forms.copy')
|
|
108
136
|
}}</span>
|
|
109
137
|
</v-btn>
|
|
110
|
-
</p>
|
|
111
|
-
<div class="remote-code grey darken-3">
|
|
112
138
|
<code
|
|
113
139
|
class="grey darken-3"
|
|
114
140
|
v-text="logItem.context.remote_code"
|
|
115
141
|
></code>
|
|
116
142
|
</div>
|
|
117
|
-
</
|
|
118
|
-
</
|
|
119
|
-
|
|
143
|
+
</td>
|
|
144
|
+
</tr>
|
|
145
|
+
<tr v-if="logItem.context.remote_sso">
|
|
146
|
+
<th class="text-left">
|
|
147
|
+
{{
|
|
148
|
+
$t(
|
|
149
|
+
'windward.integrations.components.integration.job_log.remote_sso'
|
|
150
|
+
)
|
|
151
|
+
}}
|
|
152
|
+
</th>
|
|
153
|
+
<td>
|
|
154
|
+
<v-chip
|
|
155
|
+
:href="logItem.context.remote_sso"
|
|
156
|
+
outlined
|
|
157
|
+
label
|
|
158
|
+
target="_blank"
|
|
159
|
+
>
|
|
160
|
+
<span
|
|
161
|
+
class="d-inline-block text-truncate chip--truncate"
|
|
162
|
+
>
|
|
163
|
+
{{ logItem.context.remote_sso }}
|
|
164
|
+
</span>
|
|
120
165
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
</
|
|
128
|
-
</
|
|
166
|
+
<v-icon class="ml-2">
|
|
167
|
+
mdi-launch
|
|
168
|
+
</v-icon>
|
|
169
|
+
</v-chip>
|
|
170
|
+
</td>
|
|
171
|
+
</tr>
|
|
172
|
+
</tbody>
|
|
173
|
+
</table>
|
|
129
174
|
</div>
|
|
130
|
-
</
|
|
131
|
-
|
|
175
|
+
</v-alert>
|
|
176
|
+
<p v-if="filteredLog.length === 0">
|
|
177
|
+
{{
|
|
178
|
+
$t(
|
|
179
|
+
'windward.integrations.components.integration.job_log.no_results'
|
|
180
|
+
)
|
|
181
|
+
}}
|
|
182
|
+
</p>
|
|
183
|
+
</div>
|
|
132
184
|
</div>
|
|
133
185
|
</template>
|
|
134
186
|
|
|
@@ -150,7 +202,70 @@ export default {
|
|
|
150
202
|
loading: true,
|
|
151
203
|
job: {},
|
|
152
204
|
log: [],
|
|
153
|
-
|
|
205
|
+
filters: [
|
|
206
|
+
{
|
|
207
|
+
value: 'tag',
|
|
208
|
+
text: this.$t(
|
|
209
|
+
'windward.integrations.components.integration.job_log.log_level'
|
|
210
|
+
),
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
value: 'file_missing_error',
|
|
214
|
+
text: this.$t(
|
|
215
|
+
'windward.integrations.components.integration.job_log.search.file_missing_error'
|
|
216
|
+
),
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
value: 'data_error',
|
|
220
|
+
text: this.$t(
|
|
221
|
+
'windward.integrations.components.integration.job_log.search.data_error'
|
|
222
|
+
),
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
value: 'converted_file',
|
|
226
|
+
text: this.$t(
|
|
227
|
+
'windward.integrations.components.integration.job_log.search.converted_file'
|
|
228
|
+
),
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
value: 'converted_file_error',
|
|
232
|
+
text: this.$t(
|
|
233
|
+
'windward.integrations.components.integration.job_log.search.converted_file_error'
|
|
234
|
+
),
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
value: 'parse_error',
|
|
238
|
+
text: this.$t(
|
|
239
|
+
'windward.integrations.components.integration.job_log.search.parse_error'
|
|
240
|
+
),
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
value: 'linking_error',
|
|
244
|
+
text: this.$t(
|
|
245
|
+
'windward.integrations.components.integration.job_log.search.linking_error'
|
|
246
|
+
),
|
|
247
|
+
},
|
|
248
|
+
],
|
|
249
|
+
levelTags: [
|
|
250
|
+
{
|
|
251
|
+
value: 'info',
|
|
252
|
+
text: this.$t(
|
|
253
|
+
'windward.integrations.components.integration.job_log.search.level_info'
|
|
254
|
+
),
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
value: 'warning',
|
|
258
|
+
text: this.$t(
|
|
259
|
+
'windward.integrations.components.integration.job_log.search.level_warning'
|
|
260
|
+
),
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
value: 'error',
|
|
264
|
+
text: this.$t(
|
|
265
|
+
'windward.integrations.components.integration.job_log.search.level_error'
|
|
266
|
+
),
|
|
267
|
+
},
|
|
268
|
+
],
|
|
154
269
|
}
|
|
155
270
|
},
|
|
156
271
|
computed: {
|
|
@@ -158,45 +273,70 @@ export default {
|
|
|
158
273
|
organization: 'organization/get',
|
|
159
274
|
}),
|
|
160
275
|
filteredLog() {
|
|
161
|
-
|
|
276
|
+
// Get the term and if it doesn't exist or is null convert to empty string
|
|
277
|
+
const term = (_.get(this.search, 'term', '') || '').toLowerCase()
|
|
278
|
+
|
|
279
|
+
// If there's no fiters and no terms then just return the whole log
|
|
280
|
+
if (
|
|
281
|
+
_.get(this.search, 'filter', []).length === 0 &&
|
|
282
|
+
term.length < 3
|
|
283
|
+
) {
|
|
162
284
|
return this.job.log || []
|
|
163
285
|
}
|
|
164
286
|
const filtered = this.job.log.filter((item) => {
|
|
165
|
-
let match =
|
|
166
|
-
.toLowerCase()
|
|
167
|
-
.includes(this.search.term.toLowerCase())
|
|
287
|
+
let match = false
|
|
168
288
|
|
|
169
|
-
//
|
|
170
|
-
if (
|
|
171
|
-
match =
|
|
172
|
-
.
|
|
173
|
-
|
|
174
|
-
.includes(this.search.term.toLowerCase())
|
|
289
|
+
// Apply any search filters
|
|
290
|
+
if (this.search.filter && this.search.filter.length > 0) {
|
|
291
|
+
match = this.search.filter.includes(
|
|
292
|
+
_.get(item, 'context.type', '')
|
|
293
|
+
)
|
|
175
294
|
}
|
|
176
295
|
|
|
177
|
-
//
|
|
178
|
-
if (
|
|
179
|
-
|
|
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())
|
|
296
|
+
// Apply any log level tag filters
|
|
297
|
+
if (this.search.tags && this.search.tags.length > 0) {
|
|
298
|
+
match = this.search.tags.includes(item.level)
|
|
186
299
|
}
|
|
187
300
|
|
|
188
|
-
// Search
|
|
189
|
-
if (
|
|
190
|
-
match = item.
|
|
191
|
-
.toLowerCase()
|
|
192
|
-
.includes(this.search.term.toLowerCase())
|
|
193
|
-
}
|
|
301
|
+
// Search by term on various fields
|
|
302
|
+
if (term.length >= 3) {
|
|
303
|
+
match = item.message.toLowerCase().includes(term)
|
|
194
304
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
.
|
|
199
|
-
|
|
305
|
+
// Search the remote course id
|
|
306
|
+
if (
|
|
307
|
+
!match &&
|
|
308
|
+
_.get(item, 'context.remote_course.id', null)
|
|
309
|
+
) {
|
|
310
|
+
match = _.get(item, 'context.remote_course.id', '')
|
|
311
|
+
.toString()
|
|
312
|
+
.toLowerCase()
|
|
313
|
+
.includes(term)
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Search the remote assessment id
|
|
317
|
+
if (
|
|
318
|
+
!match &&
|
|
319
|
+
_.get(item, 'context.remote_assessment.id', null)
|
|
320
|
+
) {
|
|
321
|
+
match = _.get(item, 'context.remote_assessment.id', '')
|
|
322
|
+
.toString()
|
|
323
|
+
.toLowerCase()
|
|
324
|
+
.includes(term)
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Search the remote url
|
|
328
|
+
if (!match && item.context.remote_url) {
|
|
329
|
+
match = item.context.remote_url
|
|
330
|
+
.toLowerCase()
|
|
331
|
+
.includes(term)
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Search the remote code
|
|
335
|
+
if (!match && item.context.remote_code) {
|
|
336
|
+
match = item.context.remote_code
|
|
337
|
+
.toLowerCase()
|
|
338
|
+
.includes(term)
|
|
339
|
+
}
|
|
200
340
|
}
|
|
201
341
|
|
|
202
342
|
return match
|
|
@@ -236,9 +376,11 @@ export default {
|
|
|
236
376
|
}
|
|
237
377
|
},
|
|
238
378
|
},
|
|
379
|
+
mounted() {
|
|
380
|
+
this.loadLog()
|
|
381
|
+
},
|
|
239
382
|
methods: {
|
|
240
|
-
async
|
|
241
|
-
this.logDialog = true
|
|
383
|
+
async loadLog() {
|
|
242
384
|
this.job = {}
|
|
243
385
|
|
|
244
386
|
const job = await new Organization({
|
|
@@ -260,22 +402,22 @@ export default {
|
|
|
260
402
|
</script>
|
|
261
403
|
|
|
262
404
|
<style scoped>
|
|
263
|
-
.
|
|
264
|
-
min-width: 200px;
|
|
265
|
-
}
|
|
266
|
-
.col-details {
|
|
267
|
-
max-width: 100px;
|
|
268
|
-
}
|
|
269
|
-
.chip-truncate {
|
|
405
|
+
.chip--truncate {
|
|
270
406
|
max-width: 40vw;
|
|
407
|
+
}
|
|
408
|
+
.chip--truncate-left {
|
|
271
409
|
direction: rtl;
|
|
272
410
|
}
|
|
273
|
-
.log-
|
|
274
|
-
|
|
411
|
+
.log-table th {
|
|
412
|
+
padding-right: 8px;
|
|
413
|
+
min-width: 12em;
|
|
414
|
+
}
|
|
415
|
+
.log-table td {
|
|
416
|
+
max-width: 30vw;
|
|
275
417
|
}
|
|
276
418
|
.remote-code {
|
|
277
419
|
background: inherit;
|
|
278
|
-
max-width:
|
|
420
|
+
max-width: 30vw;
|
|
279
421
|
padding: 4px;
|
|
280
422
|
}
|
|
281
423
|
</style>
|
|
@@ -127,7 +127,23 @@
|
|
|
127
127
|
</td>
|
|
128
128
|
<td>{{ $d(new Date(item.created_at), 'long') }}</td>
|
|
129
129
|
<td>
|
|
130
|
-
<
|
|
130
|
+
<Dialog color="primary" outlined>
|
|
131
|
+
<template #trigger>
|
|
132
|
+
<v-icon>mdi-note-search</v-icon>
|
|
133
|
+
</template>
|
|
134
|
+
<template #title>{{
|
|
135
|
+
$t(
|
|
136
|
+
'windward.integrations.components.integration.job_log.view_log'
|
|
137
|
+
)
|
|
138
|
+
}}</template>
|
|
139
|
+
<template #form="{ on, attrs }">
|
|
140
|
+
<JobLog
|
|
141
|
+
:id="item.id"
|
|
142
|
+
v-bind="attrs"
|
|
143
|
+
v-on="on"
|
|
144
|
+
></JobLog>
|
|
145
|
+
</template>
|
|
146
|
+
</Dialog>
|
|
131
147
|
</td>
|
|
132
148
|
</tr>
|
|
133
149
|
</tbody>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-list-item v-if="showLog" @click="dialog = true">
|
|
3
|
+
<v-list-item-action>
|
|
4
|
+
<v-icon>{{ config.icon }}</v-icon>
|
|
5
|
+
</v-list-item-action>
|
|
6
|
+
<v-list-item-content>
|
|
7
|
+
<v-list-item-title>
|
|
8
|
+
{{ $t(config.i18n) }}
|
|
9
|
+
</v-list-item-title>
|
|
10
|
+
<Dialog v-model="dialog" color="primary" text :trigger="false">
|
|
11
|
+
<template #title>{{ $t(config.i18n) }}</template>
|
|
12
|
+
<template #form="{ on, attrs }">
|
|
13
|
+
<JobLog :id="jobId" v-bind="attrs" v-on="on"></JobLog>
|
|
14
|
+
</template>
|
|
15
|
+
</Dialog>
|
|
16
|
+
</v-list-item-content>
|
|
17
|
+
</v-list-item>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<script>
|
|
21
|
+
import _ from 'lodash'
|
|
22
|
+
import { mapGetters } from 'vuex'
|
|
23
|
+
import JobLog from '../../Integration/JobLog.vue'
|
|
24
|
+
|
|
25
|
+
export default {
|
|
26
|
+
name: 'NavigationItemCourseJobLog',
|
|
27
|
+
components: { JobLog },
|
|
28
|
+
props: {
|
|
29
|
+
config: { type: Object, required: true },
|
|
30
|
+
},
|
|
31
|
+
data() {
|
|
32
|
+
return {
|
|
33
|
+
dialog: false,
|
|
34
|
+
jobId: false,
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
computed: {
|
|
38
|
+
...mapGetters({
|
|
39
|
+
course: 'course/get',
|
|
40
|
+
}),
|
|
41
|
+
showLog() {
|
|
42
|
+
return !_.isEmpty(this.jobId)
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
mounted() {
|
|
46
|
+
// Check to see if this course was imported
|
|
47
|
+
this.jobId = _.get(
|
|
48
|
+
this.course,
|
|
49
|
+
'metadata.integration.integration_job_id',
|
|
50
|
+
null
|
|
51
|
+
)
|
|
52
|
+
},
|
|
53
|
+
methods: {},
|
|
54
|
+
}
|
|
55
|
+
</script>
|
|
@@ -1,8 +1,24 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
view_log: 'View Log',
|
|
3
|
+
view_course_import_log: 'View Course Import Log',
|
|
3
4
|
no_results: 'No results found',
|
|
4
5
|
remote_course_id: 'Remote Course Id',
|
|
5
6
|
remote_content_id: 'Remtote Content Id',
|
|
7
|
+
remote_content_name: 'Remote Content Name',
|
|
6
8
|
remote_url: 'Remote Url',
|
|
7
9
|
remote_code: 'Remote Code',
|
|
10
|
+
remote_sso: 'Remote SSO',
|
|
11
|
+
log_level: 'Log Level',
|
|
12
|
+
level_prefix: 'level',
|
|
13
|
+
search: {
|
|
14
|
+
level_info: 'Info Messages',
|
|
15
|
+
level_warning: 'Warning Messages',
|
|
16
|
+
level_error: 'Error Messages',
|
|
17
|
+
file_missing_error: 'File Missing',
|
|
18
|
+
data_error: 'Unexpected Data Error',
|
|
19
|
+
converted_file: 'File Converted',
|
|
20
|
+
converted_file_error: 'File Conversion Error',
|
|
21
|
+
parse_error: 'Content Block Parsing Error',
|
|
22
|
+
linking_error: 'Content Linking Error',
|
|
23
|
+
},
|
|
8
24
|
}
|
package/package.json
CHANGED
package/plugin.js
CHANGED
|
@@ -14,6 +14,8 @@ import FileImportResourcespace from './components/FileImport/Resourcespace.vue'
|
|
|
14
14
|
import FileImportGoogleDrive from './components/FileImport/GoogleDrive.vue'
|
|
15
15
|
import FileImportDropbox from './components/FileImport/Dropbox.vue'
|
|
16
16
|
|
|
17
|
+
import CourseJobLog from './components/Navigation/Items/CourseJobLog.vue'
|
|
18
|
+
|
|
17
19
|
export default {
|
|
18
20
|
name: 'windward.integrations.name',
|
|
19
21
|
hooks: {
|
|
@@ -185,6 +187,18 @@ export default {
|
|
|
185
187
|
},
|
|
186
188
|
],
|
|
187
189
|
},
|
|
190
|
+
{
|
|
191
|
+
i18n: 'windward.integrations.components.integration.job_log.view_course_import_log',
|
|
192
|
+
template: CourseJobLog,
|
|
193
|
+
icon: 'mdi-note-search',
|
|
194
|
+
context: ['course'],
|
|
195
|
+
display: ['course_tools.append-9'],
|
|
196
|
+
permissions: {
|
|
197
|
+
'plugin.windward.integrations.course.externalIntegration': {
|
|
198
|
+
readable: true,
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
},
|
|
188
202
|
],
|
|
189
203
|
contentBlock: [
|
|
190
204
|
{
|