@windward/integrations 0.0.12 → 0.1.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.
Files changed (98) hide show
  1. package/components/Content/Blocks/ExternalIntegration/LtiConsumer.vue +136 -20
  2. package/components/ExternalIntegration/Driver/Lti1p1/ManageConsumer.vue +7 -5
  3. package/components/ExternalIntegration/Driver/Lti1p1/ManageConsumers.vue +3 -2
  4. package/components/ExternalIntegration/Driver/Lti1p3/ManageConsumer.vue +284 -0
  5. package/components/ExternalIntegration/Driver/Lti1p3/ManageConsumers.vue +229 -0
  6. package/components/ExternalIntegration/Driver/Lti1p3/ManageProvider.vue +14 -0
  7. package/components/ExternalIntegration/Driver/Lti1p3/ViewConsumer.vue +224 -0
  8. package/components/ExternalIntegration/Driver/ManageLti1p3.vue +3 -3
  9. package/components/Integration/Driver/ManageAtutor.vue +7 -13
  10. package/components/Integration/Driver/ManageBase.vue +0 -7
  11. package/components/Integration/Driver/ManageResourcespace.vue +6 -0
  12. package/components/Integration/JobLog.vue +4 -3
  13. package/components/SecretField.vue +16 -1
  14. package/components/Settings/ExternalIntegration/LtiConsumerSettings.vue +72 -30
  15. package/i18n/en-US/components/content/blocks/external_integration/lti_consumer.ts +7 -0
  16. package/i18n/en-US/components/external_integration/driver/lti1p3.ts +4 -0
  17. package/i18n/en-US/components/integration/driver.ts +2 -2
  18. package/i18n/en-US/components/settings/external_integration/lti_consumer.ts +3 -0
  19. package/i18n/es-ES/components/content/blocks/external_integration/index.ts +5 -0
  20. package/i18n/es-ES/components/content/blocks/external_integration/lti_consumer.ts +17 -0
  21. package/i18n/es-ES/components/content/blocks/index.ts +5 -0
  22. package/i18n/es-ES/components/content/index.ts +5 -0
  23. package/i18n/es-ES/components/external_integration/driver/lti1p1.ts +14 -0
  24. package/i18n/es-ES/components/external_integration/driver/lti1p3.ts +23 -0
  25. package/i18n/es-ES/components/external_integration/index.ts +31 -0
  26. package/i18n/es-ES/components/external_integration/provider_target.ts +9 -0
  27. package/i18n/es-ES/components/file_import/index.ts +5 -0
  28. package/i18n/es-ES/components/file_import/resourcespace.ts +4 -0
  29. package/i18n/es-ES/components/index.ts +15 -0
  30. package/i18n/es-ES/components/integration/driver.ts +45 -0
  31. package/i18n/es-ES/components/integration/index.ts +9 -0
  32. package/i18n/es-ES/components/integration/job.ts +23 -0
  33. package/i18n/es-ES/components/integration/job_log.ts +24 -0
  34. package/i18n/es-ES/components/navigation/index.ts +5 -0
  35. package/i18n/es-ES/components/navigation/integrations.ts +8 -0
  36. package/i18n/es-ES/components/settings/external_integration/index.ts +5 -0
  37. package/i18n/es-ES/components/settings/external_integration/lti_consumer.ts +10 -0
  38. package/i18n/es-ES/components/settings/index.ts +5 -0
  39. package/i18n/es-ES/index.ts +16 -0
  40. package/i18n/es-ES/modules/index.ts +5 -0
  41. package/i18n/es-ES/pages/course/external_integration/index.ts +6 -0
  42. package/i18n/es-ES/pages/course/index.ts +5 -0
  43. package/i18n/es-ES/pages/importContent.ts +3 -0
  44. package/i18n/es-ES/pages/importCourse.ts +13 -0
  45. package/i18n/es-ES/pages/index.ts +13 -0
  46. package/i18n/es-ES/pages/login/index.ts +5 -0
  47. package/i18n/es-ES/pages/login/lti.ts +21 -0
  48. package/i18n/es-ES/pages/vendor.ts +11 -0
  49. package/i18n/es-ES/shared/content_blocks.ts +8 -0
  50. package/i18n/es-ES/shared/error.ts +10 -0
  51. package/i18n/es-ES/shared/file.ts +5 -0
  52. package/i18n/es-ES/shared/index.ts +15 -0
  53. package/i18n/es-ES/shared/menu.ts +3 -0
  54. package/i18n/es-ES/shared/permission.ts +31 -0
  55. package/i18n/es-ES/shared/settings.ts +5 -0
  56. package/i18n/index.ts +11 -0
  57. package/i18n/sv-SE/components/content/blocks/external_integration/index.ts +5 -0
  58. package/i18n/sv-SE/components/content/blocks/external_integration/lti_consumer.ts +17 -0
  59. package/i18n/sv-SE/components/content/blocks/index.ts +5 -0
  60. package/i18n/sv-SE/components/content/index.ts +5 -0
  61. package/i18n/sv-SE/components/external_integration/driver/lti1p1.ts +14 -0
  62. package/i18n/sv-SE/components/external_integration/driver/lti1p3.ts +22 -0
  63. package/i18n/sv-SE/components/external_integration/index.ts +31 -0
  64. package/i18n/sv-SE/components/external_integration/provider_target.ts +9 -0
  65. package/i18n/sv-SE/components/file_import/index.ts +5 -0
  66. package/i18n/sv-SE/components/file_import/resourcespace.ts +4 -0
  67. package/i18n/sv-SE/components/index.ts +15 -0
  68. package/i18n/sv-SE/components/integration/driver.ts +44 -0
  69. package/i18n/sv-SE/components/integration/index.ts +9 -0
  70. package/i18n/sv-SE/components/integration/job.ts +23 -0
  71. package/i18n/sv-SE/components/integration/job_log.ts +24 -0
  72. package/i18n/sv-SE/components/navigation/index.ts +5 -0
  73. package/i18n/sv-SE/components/navigation/integrations.ts +8 -0
  74. package/i18n/sv-SE/components/settings/external_integration/index.ts +5 -0
  75. package/i18n/sv-SE/components/settings/external_integration/lti_consumer.ts +10 -0
  76. package/i18n/sv-SE/components/settings/index.ts +5 -0
  77. package/i18n/sv-SE/index.ts +16 -0
  78. package/i18n/sv-SE/modules/index.ts +5 -0
  79. package/i18n/sv-SE/pages/course/external_integration/index.ts +6 -0
  80. package/i18n/sv-SE/pages/course/index.ts +5 -0
  81. package/i18n/sv-SE/pages/importContent.ts +3 -0
  82. package/i18n/sv-SE/pages/importCourse.ts +13 -0
  83. package/i18n/sv-SE/pages/index.ts +13 -0
  84. package/i18n/sv-SE/pages/login/index.ts +5 -0
  85. package/i18n/sv-SE/pages/login/lti.ts +21 -0
  86. package/i18n/sv-SE/pages/vendor.ts +11 -0
  87. package/i18n/sv-SE/shared/content_blocks.ts +8 -0
  88. package/i18n/sv-SE/shared/error.ts +9 -0
  89. package/i18n/sv-SE/shared/file.ts +5 -0
  90. package/i18n/sv-SE/shared/index.ts +15 -0
  91. package/i18n/sv-SE/shared/menu.ts +3 -0
  92. package/i18n/sv-SE/shared/permission.ts +31 -0
  93. package/i18n/sv-SE/shared/settings.ts +5 -0
  94. package/models/ExternalIntegration/{Lti1p1Consumer.ts → LtiConsumer.ts} +1 -1
  95. package/package.json +1 -1
  96. package/plugin.js +3 -4
  97. package/test/Feature/LocaleKeys.spec.js +9 -0
  98. package/test/__mocks__/componentsMock.js +12 -0
@@ -0,0 +1,229 @@
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>{{
15
+ $t(
16
+ 'windward.integrations.components.external_integration.driver.lti1p1.new'
17
+ )
18
+ }}</template>
19
+ <template #form="{ on, attrs }"
20
+ ><ManageConsumer v-bind="attrs" v-on="on"></ManageConsumer
21
+ ></template>
22
+ </Dialog>
23
+
24
+ <v-data-table
25
+ :headers="headers"
26
+ :items="consumers"
27
+ :items-per-page="10"
28
+ class="elevation-1"
29
+ >
30
+ <template #[`item.description`]="{ item }">
31
+ {{ item.description.replace(/(<([^>]+)>)/gi, '').trim() }}
32
+ </template>
33
+
34
+ <template #[`item.enabled`]="{ item }">
35
+ <v-icon :color="item.enabled ? 'success' : 'error'"
36
+ >{{ item.enabled ? 'mdi-check' : 'mdi-close' }}
37
+ </v-icon>
38
+ <span v-if="!item.enabled" class="sr-only">{{
39
+ $t('shared.forms.enabled')
40
+ }}</span>
41
+ </template>
42
+
43
+ <template #[`item.created_at`]="{ item }">
44
+ {{ $d(new Date(item.created_at), 'long') }}
45
+ </template>
46
+ <template #[`item.actions`]="{ index, item }">
47
+ <Dialog color="primary">
48
+ <template #title>{{
49
+ $t(
50
+ 'windward.integrations.components.external_integration.driver.lti1p3.view'
51
+ )
52
+ }}</template>
53
+ <template #trigger>
54
+ <v-icon small>mdi-eye-outline</v-icon>
55
+ <span class="sr-only">{{
56
+ $t(
57
+ 'windward.integrations.components.external_integration.driver.lti1p3.view'
58
+ )
59
+ }}</span>
60
+ </template>
61
+ <template #form="{ on, attrs }"
62
+ ><ViewConsumer
63
+ v-model="consumers[index]"
64
+ v-bind="attrs"
65
+ v-on="on"
66
+ ></ViewConsumer
67
+ ></template>
68
+ </Dialog>
69
+ <Dialog color="primary" action-save @click:save="onSaved">
70
+ <template #title>{{
71
+ $t(
72
+ 'windward.integrations.components.external_integration.driver.lti1p3.edit'
73
+ )
74
+ }}</template>
75
+ <template #trigger>
76
+ <v-icon small>mdi-pencil</v-icon>
77
+ <span class="sr-only">{{
78
+ $t(
79
+ 'windward.integrations.components.external_integration.driver.lti1p3.edit'
80
+ )
81
+ }}</span>
82
+ </template>
83
+ <template #form="{ on, attrs }"
84
+ ><ManageConsumer
85
+ v-model="consumers[index]"
86
+ v-bind="attrs"
87
+ v-on="on"
88
+ ></ManageConsumer
89
+ ></template>
90
+ </Dialog>
91
+
92
+ <v-btn icon>
93
+ <v-icon @click="onConfirmDelete(item)"> mdi-delete </v-icon>
94
+ <span class="sr-only">{{ $t('shared.forms.delete') }}</span>
95
+ </v-btn>
96
+ </template>
97
+ </v-data-table>
98
+ </div>
99
+ </template>
100
+
101
+ <script>
102
+ import _ from 'lodash'
103
+ import { mapGetters } from 'vuex'
104
+ import LtiConsumer from '../../../../models/ExternalIntegration/LtiConsumer'
105
+ import ManageConsumer from './ManageConsumer.vue'
106
+ import ViewConsumer from './ViewConsumer.vue'
107
+ import Course from '~/models/Course'
108
+ import Organization from '~/models/Organization'
109
+ import Dialog from '~/components/Dialog.vue'
110
+
111
+ export default {
112
+ name: 'ManageLti1p1ConsumersDriver',
113
+ components: { Dialog, ManageConsumer, ViewConsumer },
114
+ data() {
115
+ return {
116
+ consumers: [],
117
+ headers: [
118
+ {
119
+ text: this.$t(
120
+ 'windward.integrations.components.external_integration.target_url'
121
+ ),
122
+ value: 'target',
123
+ },
124
+ {
125
+ text: this.$t('shared.forms.name'),
126
+ value: 'name',
127
+ },
128
+ {
129
+ text: this.$t('shared.forms.description'),
130
+ value: 'description',
131
+ },
132
+ {
133
+ text: this.$t('shared.forms.enabled'),
134
+ value: 'enabled',
135
+ },
136
+ { text: this.$t('shared.forms.created'), value: 'created_at' },
137
+ {
138
+ text: this.$t('shared.forms.actions'),
139
+ value: 'actions',
140
+ sortable: false,
141
+ },
142
+ ],
143
+ }
144
+ },
145
+
146
+ async fetch() {
147
+ if (
148
+ !this.$PermissionService.userHasAccessTo(
149
+ 'plugin.windward.integrations.course.externalIntegration',
150
+ 'readable'
151
+ ) ||
152
+ _.isEmpty(this.organization.id) ||
153
+ _.isEmpty(this.course.id)
154
+ ) {
155
+ // Display an angry error that they can't view this driver
156
+ this.$dialog.error(this.$t('shared.error.description_401'), {
157
+ duration: null,
158
+ action: {
159
+ text: this.$t('shared.forms.close'),
160
+ onClick: (_e, toastObject) => {
161
+ toastObject.goAway(0)
162
+ },
163
+ },
164
+ })
165
+ if (_.isEmpty(this.organization.id) || _.isEmpty(this.course.id)) {
166
+ // eslint-disable-next-line no-console
167
+ console.error(
168
+ 'Cannot load external integrations because organization or course is not set!'
169
+ )
170
+ } else {
171
+ // eslint-disable-next-line no-console
172
+ console.error(
173
+ 'You do not have access to this external integration!'
174
+ )
175
+ }
176
+
177
+ // Return so we don't even attempt loading
178
+ return false
179
+ }
180
+
181
+ await this.loadConsumers()
182
+ },
183
+ computed: {
184
+ ...mapGetters({
185
+ organization: 'organization/get',
186
+ course: 'course/get',
187
+ }),
188
+ },
189
+ methods: {
190
+ onSaved() {
191
+ this.loadConsumers()
192
+ },
193
+ async loadConsumers() {
194
+ this.consumers = await new LtiConsumer()
195
+ .for(
196
+ new Organization({ id: this.organization.id }),
197
+ new Course({ id: this.course.id })
198
+ )
199
+ .where('version', '1.3')
200
+ .get()
201
+ },
202
+ onConfirmDelete(consumer) {
203
+ this.$dialog.show(this.$t('shared.forms.confirm_delete_text'), {
204
+ icon: 'mdi-help',
205
+ duration: null,
206
+ action: [
207
+ {
208
+ text: this.$t('shared.forms.cancel'),
209
+ onClick: (_e, toastObject) => {
210
+ toastObject.goAway(0)
211
+ },
212
+ },
213
+ {
214
+ text: this.$t('shared.forms.confirm'),
215
+ // router navigation
216
+ onClick: (_e, toastObject) => {
217
+ this.deleteConsumer(consumer)
218
+ toastObject.goAway(0)
219
+ },
220
+ },
221
+ ],
222
+ })
223
+ },
224
+ deleteConsumer(consumer) {
225
+ consumer.delete()
226
+ },
227
+ },
228
+ }
229
+ </script>
@@ -127,6 +127,20 @@
127
127
  )
128
128
  "
129
129
  ></v-text-field>
130
+ <v-text-field
131
+ id="lti-oauth2-aud"
132
+ v-model="provider.metadata.platform_oauth2_audience"
133
+ :label="
134
+ $t(
135
+ 'windward.integrations.components.external_integration.driver.lti1p3.platform_oauth2_audience'
136
+ )
137
+ "
138
+ :hint="
139
+ $t(
140
+ 'windward.integrations.components.external_integration.driver.lti1p3.platform_oauth2_audience'
141
+ )
142
+ "
143
+ ></v-text-field>
130
144
  <v-text-field
131
145
  id="lti-client-id"
132
146
  v-model="provider.metadata.tool_client_id"
@@ -0,0 +1,224 @@
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-form v-model="formValid" @submit.prevent>
8
+ <v-row justify="center" align="center" class="mt-5">
9
+ <v-col cols="12">
10
+ <SecretField
11
+ v-model="consumer.metadata.platform_id"
12
+ :hidden="false"
13
+ :placeholder="
14
+ $t(
15
+ 'windward.integrations.components.external_integration.driver.lti1p3.platform_id'
16
+ )
17
+ "
18
+ :label="
19
+ $t(
20
+ 'windward.integrations.components.external_integration.driver.lti1p3.platform_id'
21
+ )
22
+ "
23
+ ></SecretField>
24
+ <SecretField
25
+ v-model="consumer.metadata.client_id"
26
+ :hidden="false"
27
+ :placeholder="
28
+ $t(
29
+ 'windward.integrations.components.external_integration.driver.lti1p3.tool_client_id'
30
+ )
31
+ "
32
+ :label="
33
+ $t(
34
+ 'windward.integrations.components.external_integration.driver.lti1p3.tool_client_id'
35
+ )
36
+ "
37
+ ></SecretField>
38
+ <SecretField
39
+ v-model="consumer.metadata.deployment_id"
40
+ :hidden="false"
41
+ :placeholder="
42
+ $t(
43
+ 'windward.integrations.components.external_integration.driver.lti1p3.platform_deployment_id'
44
+ )
45
+ "
46
+ :label="
47
+ $t(
48
+ 'windward.integrations.components.external_integration.driver.lti1p3.platform_deployment_id'
49
+ )
50
+ "
51
+ ></SecretField>
52
+ <SecretField
53
+ v-model="
54
+ consumer.metadata.platform_oidc_auth_endpoint
55
+ "
56
+ :hidden="false"
57
+ :placeholder="
58
+ $t(
59
+ 'windward.integrations.components.external_integration.driver.lti1p3.platform_oidc_auth_endpoint'
60
+ )
61
+ "
62
+ :label="
63
+ $t(
64
+ 'windward.integrations.components.external_integration.driver.lti1p3.platform_oidc_auth_endpoint'
65
+ )
66
+ "
67
+ ></SecretField>
68
+ <SecretField
69
+ v-model="
70
+ consumer.metadata.platform_public_keyset_url
71
+ "
72
+ :hidden="false"
73
+ :placeholder="
74
+ $t(
75
+ 'windward.integrations.components.external_integration.driver.lti1p3.platform_public_keyset_url'
76
+ )
77
+ "
78
+ :label="
79
+ $t(
80
+ 'windward.integrations.components.external_integration.driver.lti1p3.platform_public_keyset_url'
81
+ )
82
+ "
83
+ ></SecretField>
84
+ <SecretField
85
+ v-model="
86
+ consumer.metadata
87
+ .platform_oauth2_access_token_url
88
+ "
89
+ :hidden="false"
90
+ :placeholder="
91
+ $t(
92
+ 'windward.integrations.components.external_integration.driver.lti1p3.platform_oauth2_access_token_url'
93
+ )
94
+ "
95
+ :label="
96
+ $t(
97
+ 'windward.integrations.components.external_integration.driver.lti1p3.platform_oauth2_access_token_url'
98
+ )
99
+ "
100
+ ></SecretField>
101
+ </v-col>
102
+ </v-row>
103
+ </v-form>
104
+ </div>
105
+ </div>
106
+ </template>
107
+
108
+ <script>
109
+ import _ from 'lodash'
110
+ import { mapGetters } from 'vuex'
111
+ import LtiConsumer from '../../../../models/ExternalIntegration/LtiConsumer'
112
+ import SecretField from '../../../SecretField.vue'
113
+ import Organization from '~/models/Organization'
114
+ import Course from '~/models/Course'
115
+ import FormVue from '~/components/Form'
116
+ export default {
117
+ name: 'ViewLti1p3Consumer',
118
+ components: { SecretField },
119
+ extends: FormVue,
120
+ props: {
121
+ value: {
122
+ type: [LtiConsumer, null],
123
+ required: false,
124
+ default: null,
125
+ },
126
+ },
127
+ emits: ['view:consumer'],
128
+ meta: {
129
+ privilege: {
130
+ '': {
131
+ writable: true,
132
+ },
133
+ },
134
+ },
135
+ data() {
136
+ return {
137
+ render: false,
138
+ consumer: {
139
+ version: '1.3',
140
+ metadata: {
141
+ custom: [],
142
+ security_level: '',
143
+ security: [],
144
+ },
145
+ },
146
+ }
147
+ },
148
+ computed: {
149
+ ...mapGetters({
150
+ organization: 'organization/get',
151
+ course: 'course/get',
152
+ }),
153
+ },
154
+ created() {
155
+ if (_.isEmpty(this.value)) {
156
+ this.consumer = new LtiConsumer(this.consumer)
157
+ } else {
158
+ this.consumer = new LtiConsumer(_.cloneDeep(this.value))
159
+ }
160
+ },
161
+ mounted() {
162
+ if (
163
+ !this.$PermissionService.userHasAccessTo(
164
+ 'plugin.windward.integrations.course.externalIntegration',
165
+ 'writable'
166
+ )
167
+ ) {
168
+ // Display an angry error that they can't view this driver
169
+ this.$dialog.error(this.$t('shared.error.description_401'), {
170
+ duration: null,
171
+ action: {
172
+ text: this.$t('shared.forms.close'),
173
+ onClick: (_e, toastObject) => {
174
+ toastObject.goAway(0)
175
+ },
176
+ },
177
+ })
178
+
179
+ // eslint-disable-next-line no-console
180
+ console.error('You do not have access to this consumer!')
181
+
182
+ // Return so we don't even attempt loading
183
+ return false
184
+ }
185
+
186
+ this.render = true
187
+ },
188
+ methods: {
189
+ addCustomParameter() {
190
+ this.consumer.metadata.custom.push({ key: '', value: '' })
191
+ },
192
+ deleteCustomParameter(index) {
193
+ this.consumer.metadata.custom.splice(index, 1)
194
+ },
195
+ async save() {
196
+ let consumer = new LtiConsumer(this.consumer).for(
197
+ new Organization({ id: this.organization.id }),
198
+ new Course({ id: this.course.id })
199
+ )
200
+
201
+ try {
202
+ consumer = await consumer.save()
203
+ this.consumer = consumer
204
+
205
+ // Clone and delete the metadata since we don't need to share that around
206
+ // Also include the vendor going back for easier mapping
207
+ const consumerEvent = _.cloneDeep(consumer)
208
+
209
+ this.$dialog.success(this.$t('shared.forms.saved'))
210
+ this.$emit('update:consumer', consumerEvent)
211
+ } catch (e) {
212
+ this.$dialog.error(
213
+ this.$t('windward.integrations.shared.error.save_failed')
214
+ )
215
+ }
216
+ },
217
+ async onSave() {
218
+ if (this.formValid) {
219
+ await this.save()
220
+ }
221
+ },
222
+ },
223
+ }
224
+ </script>
@@ -22,7 +22,7 @@
22
22
  }}
23
23
  </v-expansion-panel-header>
24
24
  <v-expansion-panel-content>
25
- <!-- <ManageConsumers></ManageConsumers>-->
25
+ <ManageConsumers></ManageConsumers>
26
26
  </v-expansion-panel-content>
27
27
  </v-expansion-panel>
28
28
  </v-expansion-panels>
@@ -31,11 +31,11 @@
31
31
 
32
32
  <script>
33
33
  import ManageProviders from './Lti1p3/ManageProviders.vue'
34
- /* import ManageConsumers from './Lti1p3/ManageConsumers.vue' */
34
+ import ManageConsumers from './Lti1p3/ManageConsumers.vue'
35
35
 
36
36
  export default {
37
37
  name: 'ManageLti1p3Driver',
38
- components: { ManageProviders },
38
+ components: { ManageProviders, ManageConsumers },
39
39
  data() {
40
40
  return {
41
41
  panel: 0,
@@ -16,6 +16,7 @@
16
16
  />
17
17
 
18
18
  <v-text-field
19
+ id="atutor-url"
19
20
  ref="atutor_url"
20
21
  v-model="integration.metadata.config.url"
21
22
  :label="
@@ -28,17 +29,20 @@
28
29
  'windward.integrations.components.integration.driver.atutor.url_hint'
29
30
  )
30
31
  "
31
- :rules="urlValidation"
32
+ :rules="validation.urlRules"
32
33
  ></v-text-field>
33
34
  <v-text-field
35
+ id="atutor-username"
34
36
  v-model="integration.metadata.config.username"
35
37
  :label="
36
38
  $t(
37
39
  'windward.integrations.components.integration.driver.atutor.username'
38
40
  )
39
41
  "
42
+ :rules="validation.existsRules"
40
43
  ></v-text-field>
41
44
  <v-text-field
45
+ id="atutor-password"
42
46
  v-model="integration.metadata.config.password"
43
47
  :label="
44
48
  $t(
@@ -46,6 +50,7 @@
46
50
  )
47
51
  "
48
52
  type="password"
53
+ :rules="validation.existsRules"
49
54
  ></v-text-field>
50
55
 
51
56
  <v-text-field
@@ -61,7 +66,7 @@
61
66
  'windward.integrations.components.integration.driver.atutor.aws_secure_url_hint'
62
67
  )
63
68
  "
64
- :rules="urlValidation"
69
+ :rules="validation.urlRules"
65
70
  ></v-text-field>
66
71
 
67
72
  <v-switch
@@ -104,17 +109,6 @@ export default {
104
109
  // integration: { metadata: {...} } The integration object to write to. Defined and loaded in ManageBase.vue
105
110
  errorMessage: '',
106
111
  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
- ],
118
112
  }
119
113
  },
120
114
  methods: {
@@ -13,13 +13,6 @@ export default {
13
13
  vendor: { type: Object, required: true, default: null },
14
14
  },
15
15
  emits: ['update:integration'],
16
- meta: {
17
- privilege: {
18
- '': {
19
- writable: true,
20
- },
21
- },
22
- },
23
16
  data() {
24
17
  return {
25
18
  render: false,
@@ -16,6 +16,7 @@
16
16
  />
17
17
 
18
18
  <v-text-field
19
+ id="resourcespace-url"
19
20
  v-model="integration.metadata.config.url"
20
21
  :label="
21
22
  $t(
@@ -27,16 +28,20 @@
27
28
  'windward.integrations.components.integration.driver.resourcespace.url_hint'
28
29
  )
29
30
  "
31
+ :rules="validation.urlRules"
30
32
  ></v-text-field>
31
33
  <v-text-field
34
+ id="resourcespace-username"
32
35
  v-model="integration.metadata.config.username"
33
36
  :label="
34
37
  $t(
35
38
  'windward.integrations.components.integration.driver.resourcespace.username'
36
39
  )
37
40
  "
41
+ :rules="validation.existsRules"
38
42
  ></v-text-field>
39
43
  <v-text-field
44
+ id="resourcespace-key"
40
45
  v-model="integration.metadata.config.key"
41
46
  :label="
42
47
  $t(
@@ -44,6 +49,7 @@
44
49
  )
45
50
  "
46
51
  type="password"
52
+ :rules="validation.existsRules"
47
53
  ></v-text-field>
48
54
 
49
55
  <v-switch
@@ -268,6 +268,9 @@ export default {
268
268
  ],
269
269
  }
270
270
  },
271
+ async fetch() {
272
+ await this.loadLog()
273
+ },
271
274
  computed: {
272
275
  ...mapGetters({
273
276
  organization: 'organization/get',
@@ -376,9 +379,7 @@ export default {
376
379
  }
377
380
  },
378
381
  },
379
- mounted() {
380
- this.loadLog()
381
- },
382
+ mounted() {},
382
383
  methods: {
383
384
  async loadLog() {
384
385
  this.job = {}
@@ -1,5 +1,12 @@
1
1
  <template>
2
- <v-text-field id="secret-field" :value="value" readonly :type="fieldType">
2
+ <v-text-field
3
+ id="secret-field"
4
+ :value="value"
5
+ readonly
6
+ :type="fieldType"
7
+ :placeholder="placeholder"
8
+ :label="label"
9
+ >
3
10
  <template #append>
4
11
  <v-btn icon @click="toggleClear">
5
12
  <v-icon>{{ showClear ? 'mdi-eye-off' : 'mdi-eye' }}</v-icon>
@@ -19,6 +26,14 @@ export default {
19
26
  value: { type: String, required: false, default: '' },
20
27
  hidden: { type: Boolean, required: false, default: true },
21
28
  copy: { type: Boolean, required: false, default: true },
29
+ placeholder: {
30
+ type: String,
31
+ required: false,
32
+ },
33
+ label: {
34
+ type: String,
35
+ required: false,
36
+ },
22
37
  },
23
38
  data() {
24
39
  return {