blob: c5a296a42b37cdd9781f43aabadf1da40f3d610b [file] [log] [blame]
Hoang Nguyenbc13fe22020-03-25 16:10:17 +07001// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18<template>
19 <div>
20 <a-card
21 class="ant-form-text"
22 v-if="description && description.length > 0"
23 v-html="$t(description)">
24 </a-card>
25 <a-form
Hoang Nguyen8efc3ea2021-07-26 18:29:19 +070026 v-ctrl-enter="handleSubmit"
Hoang Nguyenbc13fe22020-03-25 16:10:17 +070027 class="form-content"
Hoang Nguyend258da52022-03-09 19:47:09 +070028 :ref="formRef"
29 :model="form"
30 :rules="rules"
31 @finish="handleSubmit"
32 >
33 <div v-for="(field, index) in fields" :key="index">
34 <a-form-item
35 :name="field.key"
36 :ref="field.key"
37 :label="$t(field.title)"
Hoang Nguyend6488c52022-06-20 14:27:22 +070038 v-if="isDisplayInput(field)"
Hoang Nguyend258da52022-03-09 19:47:09 +070039 v-bind="formItemLayout"
40 :has-feedback="field.switch ? false : true">
41 <a-select
42 v-if="field.select"
43 v-model:value="form[field.key]"
44 :allowClear="true"
45 v-focus="index === 0"
46 showSearch
47 optionFilterProp="label"
48 :filterOption="(input, option) => {
David Jumani3c25a352023-04-11 14:05:21 +053049 return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
Hoang Nguyend258da52022-03-09 19:47:09 +070050 }" >
51 <a-select-option
52 v-for="option in field.options"
53 :key="option.id"
54 :value="option.id"
David Jumani3c25a352023-04-11 14:05:21 +053055 :label="option.name || option.description"
Hoang Nguyend258da52022-03-09 19:47:09 +070056 >
57 {{ option.name || option.description }}
58 </a-select-option>
59 </a-select>
60 <a-switch
61 v-else-if="field.switch"
62 v-model:checked="form[field.key]"
63 v-focus="index === 0"
64 />
Hoang Nguyend6488c52022-06-20 14:27:22 +070065 <a-checkbox
66 v-else-if="field.checkbox"
67 v-model:checked="form[field.key]"
68 v-focus="index === 0">
69 </a-checkbox>
Hoang Nguyend258da52022-03-09 19:47:09 +070070 <a-input
71 v-else-if="field.password"
72 type="password"
73 v-model:value="form[field.key]"
74 v-focus="index === 0"
75 />
Hoang Nguyen9e5cda52022-07-06 13:46:09 +070076 <a-radio-group
77 v-else-if="field.radioGroup"
78 v-model:value="form[field.key]"
79 buttonStyle="solid">
80 <span
81 style="margin-right: 5px;"
82 v-for="(radioItem, idx) in field.radioOption"
83 :key="idx">
84 <a-radio-button
85 :value="radioItem.value"
86 v-if="isDisplayItem(radioItem.condition)">
87 {{ $t(radioItem.label) }}
88 </a-radio-button>
89 </span>
90 <a-alert style="margin-top: 5px" type="warning" v-if="field.alert && isDisplayItem(field.alert.display)">
91 <template #message>
92 <span v-html="$t(field.alert.message)" />
93 </template>
94 </a-alert>
95 </a-radio-group>
Hoang Nguyend258da52022-03-09 19:47:09 +070096 <a-input
97 v-else
98 v-model:value="form[field.key]"
Abhishek Kumar12c077d2025-04-25 14:32:27 +053099 :defaultValue="field.defaultValue"
Hoang Nguyend258da52022-03-09 19:47:09 +0700100 v-focus="index === 0"
101 />
102 </a-form-item>
103 </div>
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700104 </a-form>
105 <div class="form-action">
106 <a-button
107 v-if="!isFixError"
108 class="button-prev"
109 @click="handleBack">
110 {{ $t('label.previous') }}
111 </a-button>
Hoang Nguyen8efc3ea2021-07-26 18:29:19 +0700112 <a-button class="button-next" ref="submit" type="primary" @click="handleSubmit">
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700113 {{ $t('label.next') }}
114 </a-button>
115 </div>
116 </div>
117</template>
118
119<script>
Hoang Nguyend258da52022-03-09 19:47:09 +0700120import { ref, reactive, toRaw } from 'vue'
121
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700122export default {
123 props: {
124 prefillContent: {
125 type: Object,
126 default: function () {
127 return {}
128 }
129 },
130 fields: {
131 type: Array,
132 default: function () {
133 return []
134 }
135 },
136 description: {
137 type: String,
Hoang Nguyen4f97fea2020-07-27 14:33:31 +0700138 default: 'label.creating.iprange'
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700139 },
140 isFixError: {
141 type: Boolean,
142 default: false
143 }
144 },
145 created () {
Hoang Nguyend258da52022-03-09 19:47:09 +0700146 this.initForm()
147 },
Hoang Nguyen9e5cda52022-07-06 13:46:09 +0700148 computed: {
149 hypervisor () {
150 return this.prefillContent?.hypervisor || null
151 }
152 },
Hoang Nguyend258da52022-03-09 19:47:09 +0700153 mounted () {
154 this.fillValue()
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700155 },
156 data: () => ({
157 formItemLayout: {
158 labelCol: { span: 8 },
159 wrapperCol: { span: 12 }
160 },
161 ipV4Regex: /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i,
Hoang Nguyend258da52022-03-09 19:47:09 +0700162 ipV6Regex: /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i,
163 formModel: {}
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700164 }),
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700165 watch: {
Hoang Nguyend258da52022-03-09 19:47:09 +0700166 formModel: {
167 deep: true,
168 handler (changedFields) {
169 const fieldsChanged = toRaw(changedFields)
170 this.$emit('fieldsChanged', fieldsChanged)
171 }
Hoang Nguyend6488c52022-06-20 14:27:22 +0700172 },
173 'prefillContent.provider' (val) {
174 if (['SolidFire', 'PowerFlex'].includes(val)) {
175 this.form.primaryStorageProtocol = 'custom'
176 }
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700177 }
178 },
179 methods: {
Hoang Nguyend258da52022-03-09 19:47:09 +0700180 initForm () {
181 this.formRef = ref()
182 this.form = reactive({})
183 this.rules = reactive({})
184 },
185 fillValue () {
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700186 this.fields.forEach(field => {
Hoang Nguyend258da52022-03-09 19:47:09 +0700187 this.setRules(field)
Hoang Nguyend6488c52022-06-20 14:27:22 +0700188 const fieldExists = this.isDisplayInput(field)
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700189 if (!fieldExists) {
190 return
191 }
Hoang Nguyend6488c52022-06-20 14:27:22 +0700192 if (field.key === 'agentUserName' && !this.getPrefilled(field)) {
Hoang Nguyend258da52022-03-09 19:47:09 +0700193 this.form[field.key] = 'Oracle'
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700194 } else {
Hoang Nguyend6488c52022-06-20 14:27:22 +0700195 if (field.switch || field.checkbox) {
Hoang Nguyend258da52022-03-09 19:47:09 +0700196 this.form[field.key] = this.isChecked(field)
197 } else {
Hoang Nguyend6488c52022-06-20 14:27:22 +0700198 this.form[field.key] = this.getPrefilled(field)
Hoang Nguyend258da52022-03-09 19:47:09 +0700199 }
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700200 }
201 })
Hoang Nguyend258da52022-03-09 19:47:09 +0700202
203 this.formModel = toRaw(this.form)
204 },
205 setRules (field) {
206 this.rules[field.key] = []
207 if (field.required) {
208 this.rules[field.key].push({ required: field.required, message: this.$t(field.placeHolder) })
209 }
210 if (field.ipV4 || field.ipV6) {
211 this.rules[field.key].push({
212 ipV4: field.ipV4,
213 ipV6: field.ipV6,
214 validator: this.checkIpFormat,
215 message: this.$t(field.message)
216 })
217 }
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700218 },
Hoang Nguyend6488c52022-06-20 14:27:22 +0700219 getPrefilled (field) {
Hoang Nguyen9e5cda52022-07-06 13:46:09 +0700220 if (field.key === 'authmethod' && this.hypervisor !== 'KVM') {
221 return field.value || field.defaultValue || 'password'
222 }
223 return this.prefillContent?.[field.key] || field.value || field.defaultValue || null
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700224 },
Hoang Nguyend258da52022-03-09 19:47:09 +0700225 handleSubmit () {
226 this.formRef.value.validate().then(() => {
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700227 if (this.isFixError) {
228 this.$emit('submitLaunchZone')
229 return
230 }
231 this.$emit('nextPressed')
Hoang Nguyend258da52022-03-09 19:47:09 +0700232 }).catch(error => {
233 this.formRef.value.scrollToField(error.errorFields[0].name)
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700234 })
235 },
Hoang Nguyend258da52022-03-09 19:47:09 +0700236 handleBack () {
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700237 this.$emit('backPressed')
238 },
Hoang Nguyend258da52022-03-09 19:47:09 +0700239 async checkIpFormat (rule, value) {
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700240 if (!value || value === '') {
Hoang Nguyend258da52022-03-09 19:47:09 +0700241 return Promise.resolve()
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700242 } else if (rule.ipV4 && !this.ipV4Regex.test(value)) {
Hoang Nguyend258da52022-03-09 19:47:09 +0700243 return Promise.reject(rule.message)
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700244 } else if (rule.ipV6 && !this.ipV6Regex.test(value)) {
Hoang Nguyend258da52022-03-09 19:47:09 +0700245 return Promise.reject(rule.message)
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700246 } else {
Hoang Nguyend258da52022-03-09 19:47:09 +0700247 return Promise.resolve()
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700248 }
249 },
Hoang Nguyend6488c52022-06-20 14:27:22 +0700250 isDisplayInput (field) {
251 if (!field.display && !field.hidden) {
252 return true
253 }
254 const conditions = field.display || field.hidden
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700255 if (!conditions || Object.keys(conditions).length === 0) {
256 return true
257 }
Hoang Nguyen0f926b52022-01-10 20:31:53 +0700258 let isShow = true
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700259 Object.keys(conditions).forEach(key => {
Hoang Nguyen0f926b52022-01-10 20:31:53 +0700260 if (isShow) {
261 const condition = conditions[key]
Hoang Nguyend258da52022-03-09 19:47:09 +0700262 const fieldVal = this.form[key]
263 ? this.form[key]
264 : (this.prefillContent?.[key] || null)
Hoang Nguyend6488c52022-06-20 14:27:22 +0700265
266 if (field.hidden) {
267 if (Array.isArray(condition) && condition.includes(fieldVal)) {
268 isShow = false
269 } else if (!Array.isArray(condition) && fieldVal === condition) {
270 isShow = false
271 }
272 } else if (field.display) {
273 if (Array.isArray(condition) && !condition.includes(fieldVal)) {
274 isShow = false
275 } else if (!Array.isArray(condition) && fieldVal !== condition) {
276 isShow = false
277 }
Hoang Nguyen0f926b52022-01-10 20:31:53 +0700278 }
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700279 }
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700280 })
281
282 return isShow
283 },
284 isChecked (field) {
Hoang Nguyend258da52022-03-09 19:47:09 +0700285 if (this.prefillContent[field.key]) {
286 return this.prefillContent[field.key]
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700287 }
288 if (!field.checked) {
289 return false
290 }
291 return true
Hoang Nguyen9e5cda52022-07-06 13:46:09 +0700292 },
293 isDisplayItem (conditions) {
294 if (!conditions || Object.keys(conditions).length === 0) {
295 return true
296 }
297 let isShow = true
298 Object.keys(conditions).forEach(key => {
299 if (!isShow) return false
300
301 const condition = conditions[key]
302 const fieldVal = this.form[key]
303 ? this.form[key]
304 : (this.prefillContent?.[key] || null)
305 if (Array.isArray(condition) && !condition.includes(fieldVal)) {
306 isShow = false
307 } else if (!Array.isArray(condition) && fieldVal !== condition) {
308 isShow = false
309 }
310 })
311
312 return isShow
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700313 }
314 }
315}
316</script>
317
318<style scoped lang="less">
319 .form-content {
320 border: 1px dashed #e9e9e9;
321 border-radius: 6px;
322 background-color: #fafafa;
323 min-height: 200px;
324 text-align: center;
325 vertical-align: center;
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700326 margin-top: 8px;
327 max-height: 300px;
328 overflow-y: auto;
Hoang Nguyen5b986be2021-03-30 15:39:56 +0700329 padding: 16px 20px 0;
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700330
Hoang Nguyend258da52022-03-09 19:47:09 +0700331 :deep(.has-error) {
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700332 .ant-form-explain {
333 text-align: left;
334 }
335 }
336
Hoang Nguyend258da52022-03-09 19:47:09 +0700337 :deep(.ant-form-item-control) {
Hoang Nguyenbc13fe22020-03-25 16:10:17 +0700338 text-align: left;
339 }
340 }
341
342 .ant-form-text {
343 text-align: justify;
344 margin: 10px 0;
345 padding: 24px;
346 width: 100%;
347 }
348
349 .form-action {
350 margin-top: 16px;
351 }
352</style>