main
vue 306 lines 7.91 KB
Raw
1 <template>
2 <div class="connector-form">
3 <n-spin :show="loading">
4 <div class="connector-header">
5 <n-avatar
6 class="connector-image"
7 object-fit="contain"
8 round
9 :size="60"
10 :src="`/images/connectors/${
11 connector ? `${connector.connector_name.toLowerCase()}.svg` : 'default-logo.svg'
12 }`"
13 :alt="`${connector.connector_name} Logo`"
14 fallback-src="/images/img-not-found.svg"
15 />
16
17 <h3>{{ connector.connector_name || "" }}</h3>
18 </div>
19
20 <div class="connector-form-type">
21 <CredentialsType
22 v-if="connectorFormType === ConnectorFormType.CREDENTIALS"
23 :form="connectorForm"
24 @mounted="formRef = $event"
25 />
26 <FileType
27 v-if="connectorFormType === ConnectorFormType.FILE"
28 :form="connectorForm"
29 @mounted="formRef = $event"
30 />
31 <TokenType
32 v-if="connectorFormType === ConnectorFormType.TOKEN"
33 :form="connectorForm"
34 @mounted="formRef = $event"
35 />
36 <HostType
37 v-if="connectorFormType === ConnectorFormType.HOST"
38 :form="connectorForm"
39 @mounted="formRef = $event"
40 />
41 </div>
42 <div class="connector-form-options">
43 <n-form
44 ref="formOptionsRef"
45 :model="connectorForm"
46 :rules="optionsRules"
47 label-width="120px"
48 label-placement="top"
49 >
50 <n-form-item v-if="connectorFormOptions.extraData" label="Extra data" path="connector_extra_data">
51 <n-input v-model:value="connectorForm.connector_extra_data" type="text" />
52 </n-form-item>
53 </n-form>
54 </div>
55
56 <div class="connector-footer mt-4">
57 <n-form-item>
58 <div class="flex w-full justify-end gap-2">
59 <n-button type="primary" @click="saveConnector()">Save</n-button>
60 <n-button @click="closeForm(false)">Cancel</n-button>
61 </div>
62 </n-form-item>
63 </div>
64 </n-spin>
65 </div>
66 </template>
67
68 <script setup lang="ts">
69 import type { FormInst, FormRules, FormValidationError } from "naive-ui"
70 import type {
71 Connector,
72 ConnectorForm,
73 ConnectorFormOptionKeys,
74 ConnectorFormOptions,
75 ConnectorRequestPayload
76 } from "@/types/connectors.d"
77 import _pick from "lodash/pick"
78 import { NAvatar, NButton, NForm, NFormItem, NInput, NSpin, useMessage } from "naive-ui"
79 import { computed, onMounted, ref, toRefs, watch } from "vue"
80 import Api from "@/api"
81 import { ConnectorFormType } from "@/types/connectors.d"
82 import CredentialsType from "./FormTypes/CredentialsType.vue"
83 import FileType from "./FormTypes/FileType.vue"
84 import HostType from "./FormTypes/HostType.vue"
85 import TokenType from "./FormTypes/TokenType.vue"
86
87 const props = defineProps<{
88 connector: Connector
89 }>()
90 const emit = defineEmits<{
91 (e: "close", value: boolean): void
92 (e: "loading", value: boolean): void
93 }>()
94
95 const { connector } = toRefs(props)
96
97 const connectorForm = ref<ConnectorForm>({
98 connector_url: "",
99 connector_username: "",
100 connector_password: "",
101 connector_api_key: "",
102 connector_extra_data: "",
103 connector_file: null
104 })
105
106 const optionsRules: FormRules = {
107 connector_extra_data: [{ required: true, trigger: "blur", message: "Please input a valid Extra Data" }]
108 }
109
110 const message = useMessage()
111 const formOptionsRef = ref<FormInst>()
112 const connectorFormType = computed<ConnectorFormType>(() => getConnectorFormType(connector.value))
113 const connectorFormOptions = computed<ConnectorFormOptions>(() => getConnectorFormOptions(connector.value))
114 const isConnectorConfigured = computed<boolean>(() => connector.value.connector_configured)
115 const formRef = ref<FormInst | null>(null)
116 const loading = ref<boolean>(false)
117
118 const formOptionsCheckRequired = computed<boolean>(() => {
119 let checkRequired = false
120 for (const key in connectorFormOptions.value) {
121 const required = connectorFormOptions.value[key as ConnectorFormOptionKeys]
122 if (required === true) {
123 checkRequired = true
124 }
125 }
126 return checkRequired
127 })
128
129 watch(loading, val => {
130 emit("loading", val)
131 })
132
133 function setUpForm() {
134 connectorForm.value = _pick(connector.value, [
135 "connector_url",
136 "connector_username",
137 "connector_password",
138 "connector_api_key",
139 "connector_extra_data",
140 "connector_file"
141 ]) as unknown as ConnectorForm
142 }
143
144 function getConnectorFormType(connector: Connector): ConnectorFormType {
145 if (connector.connector_accepts_api_key) {
146 return ConnectorFormType.TOKEN
147 }
148 if (connector.connector_accepts_file) {
149 return ConnectorFormType.FILE
150 }
151 if (connector.connector_accepts_username_password) {
152 return ConnectorFormType.CREDENTIALS
153 }
154 if (connector.connector_accepts_host_only) {
155 return ConnectorFormType.HOST
156 }
157 return ConnectorFormType.UNKNOWN
158 }
159
160 function getConnectorFormOptions(connector: Connector): ConnectorFormOptions {
161 const options: ConnectorFormOptions = {}
162
163 if (connector.connector_accepts_extra_data) {
164 options.extraData = true
165 }
166
167 return options
168 }
169
170 function saveConnector() {
171 if (!formRef.value) return
172
173 let messageSent = false
174
175 formRef.value.validate((errors?: Array<FormValidationError>) => {
176 if (!errors) {
177 if (formOptionsRef.value && formOptionsCheckRequired.value) {
178 formOptionsRef.value.validate((errors?: Array<FormValidationError>) => {
179 if (!errors) {
180 configureConnector()
181 } else {
182 if (!messageSent) {
183 message.warning("You must fill in the required fields correctly.")
184 }
185 return false
186 }
187 })
188 } else {
189 configureConnector()
190 }
191 } else {
192 message.warning("You must fill in the required fields correctly.")
193 messageSent = true
194 return false
195 }
196 })
197 }
198
199 function closeForm(update: boolean) {
200 emit("close", update)
201 }
202
203 function getRequestMethod() {
204 if (connectorFormType.value === ConnectorFormType.FILE) {
205 return Api.connectors.upload
206 }
207
208 return isConnectorConfigured.value ? Api.connectors.update : Api.connectors.configure
209 }
210
211 function configureConnector() {
212 loading.value = true
213
214 const {
215 connector_url,
216 connector_username,
217 connector_password,
218 connector_api_key,
219 connector_file,
220 connector_extra_data
221 } = connectorForm.value
222
223 const requestMethod = getRequestMethod()
224
225 let requestPayload: ConnectorRequestPayload = {}
226
227 if (connectorFormType.value === ConnectorFormType.HOST) {
228 requestPayload = {
229 connector_url
230 }
231 }
232 if (connectorFormType.value === ConnectorFormType.TOKEN) {
233 requestPayload = {
234 connector_url,
235 connector_api_key
236 }
237 }
238 if (connectorFormType.value === ConnectorFormType.CREDENTIALS) {
239 requestPayload = {
240 connector_url,
241 connector_username,
242 connector_password
243 }
244 }
245 if (connectorFormType.value === ConnectorFormType.FILE && connector_file) {
246 const form = new FormData()
247 form.append("file", new Blob([connector_file], { type: connector_file.type }), connector_file.name)
248 requestPayload = form
249 }
250 if (connectorFormOptions.value.extraData) {
251 if (requestPayload instanceof FormData) {
252 requestPayload.append("connector_extra_data", connector_extra_data)
253 } else {
254 requestPayload.connector_extra_data = connector_extra_data
255 }
256 }
257
258 requestMethod(connector.value.id, requestPayload)
259 .then(() => {
260 message.success("Connector has been successfully configured.")
261 closeForm(true)
262 })
263 .catch(err => {
264 if (err.response.status === 400) {
265 if (isConnectorConfigured.value) {
266 message.error(
267 "This connector is not configured. If you would like to configure this connector select `Configure`."
268 )
269 } else {
270 message.error(
271 "This connector is already configured. If you would like to reconfigure this connector select `Edit`."
272 )
273 }
274 } else if (err.response?.status === 401) {
275 message.error("Unauthorized. Please check all fields")
276 } else {
277 message.error(
278 "Error updating the connector. Your settings were not inserted into the keystore. Please try again."
279 )
280 }
281 closeForm(false)
282 })
283 .finally(() => {
284 loading.value = false
285 })
286 }
287
288 onMounted(() => {
289 setUpForm()
290 })
291 </script>
292
293 <style lang="scss" scoped>
294 .connector-form {
295 .connector-header {
296 display: flex;
297 align-items: center;
298 margin-bottom: calc(var(--spacing) * 7);
299 gap: calc(var(--spacing) * 5);
300
301 .connector-image {
302 border: 2px solid var(--bg-body-color);
303 }
304 }
305 }
306 </style>