mirror of https://github.com/h44z/wg-portal.git
				
				
				
			change tagged-input-field component, allow to paste multiple values (#365)
This commit is contained in:
		
							parent
							
								
									6681dfa96f
								
							
						
					
					
						commit
						1d94f6baaf
					
				|  | @ -12,6 +12,7 @@ | ||||||
|         "@fortawesome/fontawesome-free": "^6.7.2", |         "@fortawesome/fontawesome-free": "^6.7.2", | ||||||
|         "@kyvg/vue3-notification": "^3.4.1", |         "@kyvg/vue3-notification": "^3.4.1", | ||||||
|         "@popperjs/core": "^2.11.8", |         "@popperjs/core": "^2.11.8", | ||||||
|  |         "@vojtechlanka/vue-tags-input": "^3.1.1", | ||||||
|         "bootstrap": "^5.3.5", |         "bootstrap": "^5.3.5", | ||||||
|         "bootswatch": "^5.3.5", |         "bootswatch": "^5.3.5", | ||||||
|         "flag-icons": "^7.3.2", |         "flag-icons": "^7.3.2", | ||||||
|  | @ -23,8 +24,7 @@ | ||||||
|         "vue": "^3.5.13", |         "vue": "^3.5.13", | ||||||
|         "vue-i18n": "^11.1.3", |         "vue-i18n": "^11.1.3", | ||||||
|         "vue-prism-component": "github:h44z/vue-prism-component", |         "vue-prism-component": "github:h44z/vue-prism-component", | ||||||
|         "vue-router": "^4.5.0", |         "vue-router": "^4.5.0" | ||||||
|         "vue3-tags-input": "^1.0.12" |  | ||||||
|       }, |       }, | ||||||
|       "devDependencies": { |       "devDependencies": { | ||||||
|         "@vitejs/plugin-vue": "^5.2.3", |         "@vitejs/plugin-vue": "^5.2.3", | ||||||
|  | @ -884,6 +884,20 @@ | ||||||
|         "vue": "^3.2.25" |         "vue": "^3.2.25" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/@vojtechlanka/vue-tags-input": { | ||||||
|  |       "version": "3.1.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@vojtechlanka/vue-tags-input/-/vue-tags-input-3.1.1.tgz", | ||||||
|  |       "integrity": "sha512-GdREECH+k2pQCKdbHHh4/IxRXje3QQ8rXzXd9/6L1kzGYXqHlG1tbRoi1qC7enph67/g2nvGaZfpqLuuW+CX3g==", | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "fast-deep-equal": "^3.1.3", | ||||||
|  |         "vue": "3.x", | ||||||
|  |         "vuedraggable": "^4.1.0" | ||||||
|  |       }, | ||||||
|  |       "peerDependencies": { | ||||||
|  |         "vue": "3.x" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/@vue/compiler-core": { |     "node_modules/@vue/compiler-core": { | ||||||
|       "version": "3.5.13", |       "version": "3.5.13", | ||||||
|       "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz", |       "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz", | ||||||
|  | @ -1070,15 +1084,6 @@ | ||||||
|         "node": ">=14" |         "node": ">=14" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/click-outside-vue3": { |  | ||||||
|       "version": "4.0.1", |  | ||||||
|       "resolved": "https://registry.npmjs.org/click-outside-vue3/-/click-outside-vue3-4.0.1.tgz", |  | ||||||
|       "integrity": "sha512-sbplNecrup5oGqA3o4bo8XmvHRT6q9fvw21Z67aDbTqB9M6LF7CuYLTlLvNtOgKU6W3zst5H5zJuEh4auqA34g==", |  | ||||||
|       "license": "MIT", |  | ||||||
|       "engines": { |  | ||||||
|         "node": ">=6" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/clone-regexp": { |     "node_modules/clone-regexp": { | ||||||
|       "version": "3.0.0", |       "version": "3.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-3.0.0.tgz", |       "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-3.0.0.tgz", | ||||||
|  | @ -1193,6 +1198,12 @@ | ||||||
|       "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", |       "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", | ||||||
|       "license": "MIT" |       "license": "MIT" | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/fast-deep-equal": { | ||||||
|  |       "version": "3.1.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", | ||||||
|  |       "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|     "node_modules/fdir": { |     "node_modules/fdir": { | ||||||
|       "version": "6.4.4", |       "version": "6.4.4", | ||||||
|       "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", |       "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", | ||||||
|  | @ -1893,6 +1904,12 @@ | ||||||
|         "node": ">=14.0.0" |         "node": ">=14.0.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/sortablejs": { | ||||||
|  |       "version": "1.14.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz", | ||||||
|  |       "integrity": "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==", | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|     "node_modules/source-map-js": { |     "node_modules/source-map-js": { | ||||||
|       "version": "1.2.1", |       "version": "1.2.1", | ||||||
|       "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", |       "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", | ||||||
|  | @ -2173,19 +2190,16 @@ | ||||||
|       "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", |       "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", | ||||||
|       "license": "MIT" |       "license": "MIT" | ||||||
|     }, |     }, | ||||||
|     "node_modules/vue3-tags-input": { |     "node_modules/vuedraggable": { | ||||||
|       "version": "1.0.12", |       "version": "4.1.0", | ||||||
|       "resolved": "https://registry.npmjs.org/vue3-tags-input/-/vue3-tags-input-1.0.12.tgz", |       "resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-4.1.0.tgz", | ||||||
|       "integrity": "sha512-s5rG+1W3M8+be0nd9H1nv/8WLjJOO6pShgVz8ALAqOiz3tDH5QhGrDH6fzD14ZjJNRWSa3bRBSXQwHEXffPQ6g==", |       "integrity": "sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==", | ||||||
|       "license": "MIT", |       "license": "MIT", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "click-outside-vue3": "^4.0.1" |         "sortablejs": "1.14.0" | ||||||
|       }, |  | ||||||
|       "engines": { |  | ||||||
|         "node": ">=12" |  | ||||||
|       }, |       }, | ||||||
|       "peerDependencies": { |       "peerDependencies": { | ||||||
|         "vue": "^3.0.5" |         "vue": "^3.0.1" | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -12,6 +12,7 @@ | ||||||
|     "@fortawesome/fontawesome-free": "^6.7.2", |     "@fortawesome/fontawesome-free": "^6.7.2", | ||||||
|     "@kyvg/vue3-notification": "^3.4.1", |     "@kyvg/vue3-notification": "^3.4.1", | ||||||
|     "@popperjs/core": "^2.11.8", |     "@popperjs/core": "^2.11.8", | ||||||
|  |     "@vojtechlanka/vue-tags-input": "^3.1.1", | ||||||
|     "bootstrap": "^5.3.5", |     "bootstrap": "^5.3.5", | ||||||
|     "bootswatch": "^5.3.5", |     "bootswatch": "^5.3.5", | ||||||
|     "flag-icons": "^7.3.2", |     "flag-icons": "^7.3.2", | ||||||
|  | @ -23,8 +24,7 @@ | ||||||
|     "vue": "^3.5.13", |     "vue": "^3.5.13", | ||||||
|     "vue-i18n": "^11.1.3", |     "vue-i18n": "^11.1.3", | ||||||
|     "vue-prism-component": "github:h44z/vue-prism-component", |     "vue-prism-component": "github:h44z/vue-prism-component", | ||||||
|     "vue-router": "^4.5.0", |     "vue-router": "^4.5.0" | ||||||
|     "vue3-tags-input": "^1.0.12" |  | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@vitejs/plugin-vue": "^5.2.3", |     "@vitejs/plugin-vue": "^5.2.3", | ||||||
|  |  | ||||||
|  | @ -15,3 +15,85 @@ a.disabled { | ||||||
| .desc::after { | .desc::after { | ||||||
|   content: " ↓"; |   content: " ↓"; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | /* style the background and the text color of the input ... */ | ||||||
|  | .vue-tags-input { | ||||||
|  |   max-width: 100% !important; | ||||||
|  |   background-color: #f7f7f9 !important; | ||||||
|  |   padding: 0 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .vue-tags-input .ti-input { | ||||||
|  |   padding: 0 0; | ||||||
|  |   border: none !important; | ||||||
|  |   transition: border-bottom 200ms ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .vue-tags-input .ti-new-tag-input { | ||||||
|  |   background: transparent; | ||||||
|  |   color: var(--bs-body-color); | ||||||
|  |   padding: 0.75rem 1.5rem !important; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* style the placeholders color across all browser */ | ||||||
|  | .vue-tags-input ::-webkit-input-placeholder { | ||||||
|  |   color: var(--bs-secondary-color); | ||||||
|  | } | ||||||
|  | .vue-tags-input .ti-input::placeholder { | ||||||
|  |   color: var(--bs-secondary-color); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .vue-tags-input ::-moz-placeholder { | ||||||
|  |   color: var(--bs-secondary-color); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .vue-tags-input :-ms-input-placeholder { | ||||||
|  |   color: var(--bs-secondary-color); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .vue-tags-input :-moz-placeholder { | ||||||
|  |   color: var(--bs-secondary-color); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* default styles for all the tags */ | ||||||
|  | .vue-tags-input .ti-tag { | ||||||
|  |   position: relative; | ||||||
|  |   background: #ffffff; | ||||||
|  |   border: 2px solid var(--bs-body-color); | ||||||
|  |   margin: 6px; | ||||||
|  |   color: var(--bs-body-color); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* the styles if a tag is invalid */ | ||||||
|  | .vue-tags-input .ti-tag.ti-invalid { | ||||||
|  |   background-color: #e88a74; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* if the user input is invalid, the input color should be red */ | ||||||
|  | .vue-tags-input .ti-new-tag-input.ti-invalid { | ||||||
|  |   color: #e88a74; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* if a tag or the user input is a duplicate, it should be crossed out */ | ||||||
|  | .vue-tags-input .ti-duplicate span, | ||||||
|  | .vue-tags-input .ti-new-tag-input.ti-duplicate { | ||||||
|  |   text-decoration: line-through; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* if the user presses backspace, the complete tag should be crossed out, to mark it for deletion */ | ||||||
|  | .vue-tags-input .ti-tag:after { | ||||||
|  |   transition: transform .2s; | ||||||
|  |   position: absolute; | ||||||
|  |   content: ''; | ||||||
|  |   height: 2px; | ||||||
|  |   width: 108%; | ||||||
|  |   left: -4%; | ||||||
|  |   top: calc(50% - 1px); | ||||||
|  |   background-color: #000; | ||||||
|  |   transform: scaleX(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .vue-tags-input .ti-deletion-mark:after { | ||||||
|  |   transform: scaleX(1); | ||||||
|  | } | ||||||
|  | @ -4,7 +4,7 @@ import {interfaceStore} from "@/stores/interfaces"; | ||||||
| import {computed, ref, watch} from "vue"; | import {computed, ref, watch} from "vue"; | ||||||
| import { useI18n } from 'vue-i18n'; | import { useI18n } from 'vue-i18n'; | ||||||
| import { notify } from "@kyvg/vue3-notification"; | import { notify } from "@kyvg/vue3-notification"; | ||||||
| import Vue3TagsInput from 'vue3-tags-input'; | import { VueTagsInput } from '@vojtechlanka/vue-tags-input'; | ||||||
| import { validateCIDR, validateIP, validateDomain } from '@/helpers/validators'; | import { validateCIDR, validateIP, validateDomain } from '@/helpers/validators'; | ||||||
| import isCidr from "is-cidr"; | import isCidr from "is-cidr"; | ||||||
| import {isIP} from 'is-ip'; | import {isIP} from 'is-ip'; | ||||||
|  | @ -38,6 +38,15 @@ const title = computed(() => { | ||||||
|   return t("modals.interface-edit.headline-new") |   return t("modals.interface-edit.headline-new") | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
|  | const currentTags = ref({ | ||||||
|  |   Addresses: "", | ||||||
|  |   Dns: "", | ||||||
|  |   DnsSearch: "", | ||||||
|  |   PeerDefNetwork: "", | ||||||
|  |   PeerDefAllowedIPs: "", | ||||||
|  |   PeerDefDns: "", | ||||||
|  |   PeerDefDnsSearch: "" | ||||||
|  | }) | ||||||
| const formData = ref(freshInterface()) | const formData = ref(freshInterface()) | ||||||
| 
 | 
 | ||||||
| // functions | // functions | ||||||
|  | @ -137,94 +146,94 @@ function close() { | ||||||
| function handleChangeAddresses(tags) { | function handleChangeAddresses(tags) { | ||||||
|   let validInput = true |   let validInput = true | ||||||
|   tags.forEach(tag => { |   tags.forEach(tag => { | ||||||
|     if(isCidr(tag) === 0) { |     if(isCidr(tag.text) === 0) { | ||||||
|       validInput = false |       validInput = false | ||||||
|       notify({ |       notify({ | ||||||
|         title: "Invalid CIDR", |         title: "Invalid CIDR", | ||||||
|         text: tag + " is not a valid IP address", |         text: tag.text + " is not a valid IP address", | ||||||
|         type: 'error', |         type: 'error', | ||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
|   }) |   }) | ||||||
|   if(validInput) { |   if(validInput) { | ||||||
|     formData.value.Addresses = tags |     formData.value.Addresses = tags.map(tag => tag.text) | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function handleChangeDns(tags) { | function handleChangeDns(tags) { | ||||||
|   let validInput = true |   let validInput = true | ||||||
|   tags.forEach(tag => { |   tags.forEach(tag => { | ||||||
|     if(!isIP(tag)) { |     if(!isIP(tag.text)) { | ||||||
|       validInput = false |       validInput = false | ||||||
|       notify({ |       notify({ | ||||||
|         title: "Invalid IP", |         title: "Invalid IP", | ||||||
|         text: tag + " is not a valid IP address", |         text: tag.text + " is not a valid IP address", | ||||||
|         type: 'error', |         type: 'error', | ||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
|   }) |   }) | ||||||
|   if(validInput) { |   if(validInput) { | ||||||
|     formData.value.Dns = tags |     formData.value.Dns = tags.map(tag => tag.text) | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function handleChangeDnsSearch(tags) { | function handleChangeDnsSearch(tags) { | ||||||
|   formData.value.DnsSearch = tags |   formData.value.DnsSearch = tags.map(tag => tag.text) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function handleChangePeerDefNetwork(tags) { | function handleChangePeerDefNetwork(tags) { | ||||||
|   let validInput = true |   let validInput = true | ||||||
|   tags.forEach(tag => { |   tags.forEach(tag => { | ||||||
|     if(isCidr(tag) === 0) { |     if(isCidr(tag.text) === 0) { | ||||||
|       validInput = false |       validInput = false | ||||||
|       notify({ |       notify({ | ||||||
|         title: "Invalid CIDR", |         title: "Invalid CIDR", | ||||||
|         text: tag + " is not a valid IP address", |         text: tag.text + " is not a valid IP address", | ||||||
|         type: 'error', |         type: 'error', | ||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
|   }) |   }) | ||||||
|   if(validInput) { |   if(validInput) { | ||||||
|     formData.value.PeerDefNetwork = tags |     formData.value.PeerDefNetwork = tags.map(tag => tag.text) | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function handleChangePeerDefAllowedIPs(tags) { | function handleChangePeerDefAllowedIPs(tags) { | ||||||
|   let validInput = true |   let validInput = true | ||||||
|   tags.forEach(tag => { |   tags.forEach(tag => { | ||||||
|     if(isCidr(tag) === 0) { |     if(isCidr(tag.text) === 0) { | ||||||
|       validInput = false |       validInput = false | ||||||
|       notify({ |       notify({ | ||||||
|         title: "Invalid CIDR", |         title: "Invalid CIDR", | ||||||
|         text: tag + " is not a valid IP address", |         text: tag.text + " is not a valid IP address", | ||||||
|         type: 'error', |         type: 'error', | ||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
|   }) |   }) | ||||||
|   if(validInput) { |   if(validInput) { | ||||||
|     formData.value.PeerDefAllowedIPs = tags |     formData.value.PeerDefAllowedIPs = tags.map(tag => tag.text) | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function handleChangePeerDefDns(tags) { | function handleChangePeerDefDns(tags) { | ||||||
|   let validInput = true |   let validInput = true | ||||||
|   tags.forEach(tag => { |   tags.forEach(tag => { | ||||||
|     if(!isIP(tag)) { |     if(!isIP(tag.text)) { | ||||||
|       validInput = false |       validInput = false | ||||||
|       notify({ |       notify({ | ||||||
|         title: "Invalid IP", |         title: "Invalid IP", | ||||||
|         text: tag + " is not a valid IP address", |         text: tag.text + " is not a valid IP address", | ||||||
|         type: 'error', |         type: 'error', | ||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
|   }) |   }) | ||||||
|   if(validInput) { |   if(validInput) { | ||||||
|     formData.value.PeerDefDns = tags |     formData.value.PeerDefDns = tags.map(tag => tag.text) | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function handleChangePeerDefDnsSearch(tags) { | function handleChangePeerDefDnsSearch(tags) { | ||||||
|   formData.value.PeerDefDnsSearch = tags |   formData.value.PeerDefDnsSearch = tags.map(tag => tag.text) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async function save() { | async function save() { | ||||||
|  | @ -333,11 +342,15 @@ async function del() { | ||||||
|             <legend class="mt-4">{{ $t('modals.interface-edit.header-network') }}</legend> |             <legend class="mt-4">{{ $t('modals.interface-edit.header-network') }}</legend> | ||||||
|             <div class="form-group"> |             <div class="form-group"> | ||||||
|               <label class="form-label mt-4">{{ $t('modals.interface-edit.ip.label') }}</label> |               <label class="form-label mt-4">{{ $t('modals.interface-edit.ip.label') }}</label> | ||||||
|               <vue3-tags-input class="form-control" :tags="formData.Addresses" |               <vue-tags-input class="form-control" v-model="currentTags.Addresses" | ||||||
|  |                               :tags="formData.Addresses.map(str => ({ text: str }))" | ||||||
|                               :placeholder="$t('modals.interface-edit.ip.placeholder')" |                               :placeholder="$t('modals.interface-edit.ip.placeholder')" | ||||||
|                                :add-tag-on-keys="[13, 188, 32, 9]" |                               :validation="validateCIDR()" | ||||||
|                                :validate="validateCIDR" |                               :add-on-key="[13, 188, 32, 9]" | ||||||
|                                @on-tags-changed="handleChangeAddresses"/> |                               :save-on-key="[13, 188, 32, 9]" | ||||||
|  |                               :allow-edit-tags="true" | ||||||
|  |                               :separators="[',', ';', ' ']" | ||||||
|  |                               @tags-changed="handleChangeAddresses"/> | ||||||
|             </div> |             </div> | ||||||
|             <div v-if="formData.Mode==='server'" class="form-group"> |             <div v-if="formData.Mode==='server'" class="form-group"> | ||||||
|               <label class="form-label mt-4">{{ $t('modals.interface-edit.listen-port.label') }}</label> |               <label class="form-label mt-4">{{ $t('modals.interface-edit.listen-port.label') }}</label> | ||||||
|  | @ -345,19 +358,27 @@ async function del() { | ||||||
|             </div> |             </div> | ||||||
|             <div v-if="formData.Mode!=='server'" class="form-group"> |             <div v-if="formData.Mode!=='server'" class="form-group"> | ||||||
|               <label class="form-label mt-4">{{ $t('modals.interface-edit.dns.label') }}</label> |               <label class="form-label mt-4">{{ $t('modals.interface-edit.dns.label') }}</label> | ||||||
|               <vue3-tags-input class="form-control" :tags="formData.Dns" |               <vue-tags-input class="form-control" v-model="currentTags.Dns" | ||||||
|  |                               :tags="formData.Dns.map(str => ({ text: str }))" | ||||||
|                               :placeholder="$t('modals.interface-edit.dns.placeholder')" |                               :placeholder="$t('modals.interface-edit.dns.placeholder')" | ||||||
|                                :add-tag-on-keys="[13, 188, 32, 9]" |                               :validation="validateIP()" | ||||||
|                                :validate="validateIP" |                               :add-on-key="[13, 188, 32, 9]" | ||||||
|                                @on-tags-changed="handleChangeDns"/> |                               :save-on-key="[13, 188, 32, 9]" | ||||||
|  |                               :allow-edit-tags="true" | ||||||
|  |                               :separators="[',', ';', ' ']" | ||||||
|  |                               @tags-changed="handleChangeDns"/> | ||||||
|             </div> |             </div> | ||||||
|             <div v-if="formData.Mode!=='server'" class="form-group"> |             <div v-if="formData.Mode!=='server'" class="form-group"> | ||||||
|               <label class="form-label mt-4">{{ $t('modals.interface-edit.dns-search.label') }}</label> |               <label class="form-label mt-4">{{ $t('modals.interface-edit.dns-search.label') }}</label> | ||||||
|               <vue3-tags-input class="form-control" :tags="formData.DnsSearch" |               <vue-tags-input class="form-control" v-model="currentTags.DnsSearch" | ||||||
|  |                               :tags="formData.DnsSearch.map(str => ({ text: str }))" | ||||||
|                               :placeholder="$t('modals.interface-edit.dns-search.placeholder')" |                               :placeholder="$t('modals.interface-edit.dns-search.placeholder')" | ||||||
|                                :add-tag-on-keys="[13, 188, 32, 9]" |                               :validation="validateDomain()" | ||||||
|                                :validate="validateDomain" |                               :add-on-key="[13, 188, 32, 9]" | ||||||
|                                @on-tags-changed="handleChangeDnsSearch"/> |                               :save-on-key="[13, 188, 32, 9]" | ||||||
|  |                               :allow-edit-tags="true" | ||||||
|  |                               :separators="[',', ';', ' ']" | ||||||
|  |                               @tags-changed="handleChangeDnsSearch"/> | ||||||
|             </div> |             </div> | ||||||
|             <div class="row"> |             <div class="row"> | ||||||
|               <div class="form-group col-md-6"> |               <div class="form-group col-md-6"> | ||||||
|  | @ -420,36 +441,52 @@ async function del() { | ||||||
|             </div> |             </div> | ||||||
|             <div class="form-group"> |             <div class="form-group"> | ||||||
|               <label class="form-label mt-4">{{ $t('modals.interface-edit.defaults.networks.label') }}</label> |               <label class="form-label mt-4">{{ $t('modals.interface-edit.defaults.networks.label') }}</label> | ||||||
|               <vue3-tags-input class="form-control" :tags="formData.PeerDefNetwork" |               <vue-tags-input class="form-control" v-model="currentTags.PeerDefNetwork" | ||||||
|  |                               :tags="formData.PeerDefNetwork.map(str => ({ text: str }))" | ||||||
|                               :placeholder="$t('modals.interface-edit.defaults.networks.placeholder')" |                               :placeholder="$t('modals.interface-edit.defaults.networks.placeholder')" | ||||||
|                                :add-tag-on-keys="[13, 188, 32, 9]" |                               :validation="validateCIDR()" | ||||||
|                                :validate="validateCIDR" |                               :add-on-key="[13, 188, 32, 9]" | ||||||
|                                @on-tags-changed="handleChangePeerDefNetwork"/> |                               :save-on-key="[13, 188, 32, 9]" | ||||||
|  |                               :allow-edit-tags="true" | ||||||
|  |                               :separators="[',', ';', ' ']" | ||||||
|  |                               @tags-changed="handleChangePeerDefNetwork"/> | ||||||
|               <small class="form-text text-muted">{{ $t('modals.interface-edit.defaults.networks.description') }}</small> |               <small class="form-text text-muted">{{ $t('modals.interface-edit.defaults.networks.description') }}</small> | ||||||
|             </div> |             </div> | ||||||
|             <div class="form-group"> |             <div class="form-group"> | ||||||
|               <label class="form-label mt-4">{{ $t('modals.interface-edit.defaults.allowed-ip.label') }}</label> |               <label class="form-label mt-4">{{ $t('modals.interface-edit.defaults.allowed-ip.label') }}</label> | ||||||
|               <vue3-tags-input class="form-control" :tags="formData.PeerDefAllowedIPs" |               <vue-tags-input class="form-control" v-model="currentTags.PeerDefAllowedIPs" | ||||||
|  |                               :tags="formData.PeerDefAllowedIPs.map(str => ({ text: str }))" | ||||||
|                               :placeholder="$t('modals.interface-edit.defaults.allowed-ip.placeholder')" |                               :placeholder="$t('modals.interface-edit.defaults.allowed-ip.placeholder')" | ||||||
|                                :add-tag-on-keys="[13, 188, 32, 9]" |                               :validation="validateCIDR()" | ||||||
|                                :validate="validateCIDR" |                               :add-on-key="[13, 188, 32, 9]" | ||||||
|                                @on-tags-changed="handleChangePeerDefAllowedIPs"/> |                               :save-on-key="[13, 188, 32, 9]" | ||||||
|  |                               :allow-edit-tags="true" | ||||||
|  |                               :separators="[',', ';', ' ']" | ||||||
|  |                               @tags-changed="handleChangePeerDefAllowedIPs"/> | ||||||
|             </div> |             </div> | ||||||
|             <div class="form-group"> |             <div class="form-group"> | ||||||
|               <label class="form-label mt-4">{{ $t('modals.interface-edit.dns.label') }}</label> |               <label class="form-label mt-4">{{ $t('modals.interface-edit.dns.label') }}</label> | ||||||
|               <vue3-tags-input class="form-control" :tags="formData.PeerDefDns" |               <vue-tags-input class="form-control" v-model="currentTags.PeerDefDns" | ||||||
|  |                               :tags="formData.PeerDefDns.map(str => ({ text: str }))" | ||||||
|                               :placeholder="$t('modals.interface-edit.dns.placeholder')" |                               :placeholder="$t('modals.interface-edit.dns.placeholder')" | ||||||
|                                :add-tag-on-keys="[13, 188, 32, 9]" |                               :validation="validateIP()" | ||||||
|                                :validate="validateIP" |                               :add-on-key="[13, 188, 32, 9]" | ||||||
|                                @on-tags-changed="handleChangePeerDefDns"/> |                               :save-on-key="[13, 188, 32, 9]" | ||||||
|  |                               :allow-edit-tags="true" | ||||||
|  |                               :separators="[',', ';', ' ']" | ||||||
|  |                               @tags-changed="handleChangePeerDefDns"/> | ||||||
|             </div> |             </div> | ||||||
|             <div class="form-group"> |             <div class="form-group"> | ||||||
|               <label class="form-label mt-4">{{ $t('modals.interface-edit.dns-search.label') }}</label> |               <label class="form-label mt-4">{{ $t('modals.interface-edit.dns-search.label') }}</label> | ||||||
|               <vue3-tags-input class="form-control" :tags="formData.PeerDefDnsSearch" |               <vue-tags-input class="form-control" v-model="currentTags.PeerDefDnsSearch" | ||||||
|  |                               :tags="formData.PeerDefDnsSearch.map(str => ({ text: str }))" | ||||||
|                               :placeholder="$t('modals.interface-edit.dns-search.placeholder')" |                               :placeholder="$t('modals.interface-edit.dns-search.placeholder')" | ||||||
|                                :add-tag-on-keys="[13, 188, 32, 9]" |                               :validation="validateDomain()" | ||||||
|                                :validate="validateDomain" |                               :add-on-key="[13, 188, 32, 9]" | ||||||
|                                @on-tags-changed="handleChangePeerDefDnsSearch"/> |                               :save-on-key="[13, 188, 32, 9]" | ||||||
|  |                               :allow-edit-tags="true" | ||||||
|  |                               :separators="[',', ';', ' ']" | ||||||
|  |                               @tags-changed="handleChangePeerDefDnsSearch"/> | ||||||
|             </div> |             </div> | ||||||
|             <div class="row"> |             <div class="row"> | ||||||
|               <div class="form-group col-md-6"> |               <div class="form-group col-md-6"> | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ import { interfaceStore } from "@/stores/interfaces"; | ||||||
| import { computed, ref, watch } from "vue"; | import { computed, ref, watch } from "vue"; | ||||||
| import { useI18n } from 'vue-i18n'; | import { useI18n } from 'vue-i18n'; | ||||||
| import { notify } from "@kyvg/vue3-notification"; | import { notify } from "@kyvg/vue3-notification"; | ||||||
| import Vue3TagsInput from "vue3-tags-input"; | import { VueTagsInput } from '@vojtechlanka/vue-tags-input'; | ||||||
| import { validateCIDR, validateIP, validateDomain } from '@/helpers/validators'; | import { validateCIDR, validateIP, validateDomain } from '@/helpers/validators'; | ||||||
| import isCidr from "is-cidr"; | import isCidr from "is-cidr"; | ||||||
| import { isIP } from 'is-ip'; | import { isIP } from 'is-ip'; | ||||||
|  | @ -65,6 +65,13 @@ const title = computed(() => { | ||||||
|   } |   } | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
|  | const currentTags = ref({ | ||||||
|  |   Addresses: "", | ||||||
|  |   AllowedIPs: "", | ||||||
|  |   ExtraAllowedIPs: "", | ||||||
|  |   Dns: "", | ||||||
|  |   DnsSearch: "" | ||||||
|  | }) | ||||||
| const formData = ref(freshPeer()) | const formData = ref(freshPeer()) | ||||||
| 
 | 
 | ||||||
| // functions | // functions | ||||||
|  | @ -193,73 +200,73 @@ function close() { | ||||||
| function handleChangeAddresses(tags) { | function handleChangeAddresses(tags) { | ||||||
|   let validInput = true |   let validInput = true | ||||||
|   tags.forEach(tag => { |   tags.forEach(tag => { | ||||||
|     if (isCidr(tag) === 0) { |     if (isCidr(tag.text) === 0) { | ||||||
|       validInput = false |       validInput = false | ||||||
|       notify({ |       notify({ | ||||||
|         title: "Invalid CIDR", |         title: "Invalid CIDR", | ||||||
|         text: tag + " is not a valid IP address", |         text: tag.text + " is not a valid IP address", | ||||||
|         type: 'error', |         type: 'error', | ||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
|   }) |   }) | ||||||
|   if (validInput) { |   if (validInput) { | ||||||
|     formData.value.Addresses = tags |     formData.value.Addresses = tags.map(tag => tag.text) | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function handleChangeAllowedIPs(tags) { | function handleChangeAllowedIPs(tags) { | ||||||
|   let validInput = true |   let validInput = true | ||||||
|   tags.forEach(tag => { |   tags.forEach(tag => { | ||||||
|     if (isCidr(tag) === 0) { |     if (isCidr(tag.text) === 0) { | ||||||
|       validInput = false |       validInput = false | ||||||
|       notify({ |       notify({ | ||||||
|         title: "Invalid CIDR", |         title: "Invalid CIDR", | ||||||
|         text: tag + " is not a valid IP address", |         text: tag.text + " is not a valid IP address", | ||||||
|         type: 'error', |         type: 'error', | ||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
|   }) |   }) | ||||||
|   if (validInput) { |   if (validInput) { | ||||||
|     formData.value.AllowedIPs.Value = tags |     formData.value.AllowedIPs.Value = tags.map(tag => tag.text) | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function handleChangeExtraAllowedIPs(tags) { | function handleChangeExtraAllowedIPs(tags) { | ||||||
|   let validInput = true |   let validInput = true | ||||||
|   tags.forEach(tag => { |   tags.forEach(tag => { | ||||||
|     if (isCidr(tag) === 0) { |     if (isCidr(tag.text) === 0) { | ||||||
|       validInput = false |       validInput = false | ||||||
|       notify({ |       notify({ | ||||||
|         title: "Invalid CIDR", |         title: "Invalid CIDR", | ||||||
|         text: tag + " is not a valid IP address", |         text: tag.text + " is not a valid IP address", | ||||||
|         type: 'error', |         type: 'error', | ||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
|   }) |   }) | ||||||
|   if (validInput) { |   if (validInput) { | ||||||
|     formData.value.ExtraAllowedIPs = tags |     formData.value.ExtraAllowedIPs = tags.map(tag => tag.text) | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function handleChangeDns(tags) { | function handleChangeDns(tags) { | ||||||
|   let validInput = true |   let validInput = true | ||||||
|   tags.forEach(tag => { |   tags.forEach(tag => { | ||||||
|     if (!isIP(tag)) { |     if (!isIP(tag.text)) { | ||||||
|       validInput = false |       validInput = false | ||||||
|       notify({ |       notify({ | ||||||
|         title: "Invalid IP", |         title: "Invalid IP", | ||||||
|         text: tag + " is not a valid IP address", |         text: tag.text + " is not a valid IP address", | ||||||
|         type: 'error', |         type: 'error', | ||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
|   }) |   }) | ||||||
|   if (validInput) { |   if (validInput) { | ||||||
|     formData.value.Dns.Value = tags |     formData.value.Dns.Value = tags.map(tag => tag.text) | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function handleChangeDnsSearch(tags) { | function handleChangeDnsSearch(tags) { | ||||||
|   formData.value.DnsSearch.Value = tags |   formData.value.DnsSearch.Value = tags.map(tag => tag.text) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async function save() { | async function save() { | ||||||
|  | @ -344,34 +351,64 @@ async function del() { | ||||||
|         </div> |         </div> | ||||||
|         <div class="form-group"> |         <div class="form-group"> | ||||||
|           <label class="form-label mt-4">{{ $t('modals.peer-edit.ip.label') }}</label> |           <label class="form-label mt-4">{{ $t('modals.peer-edit.ip.label') }}</label> | ||||||
|           <vue3-tags-input class="form-control" :tags="formData.Addresses" |           <vue-tags-input class="form-control" v-model="currentTags.Addresses" | ||||||
|             :placeholder="$t('modals.peer-edit.ip.placeholder')" :add-tag-on-keys="[13, 188, 32, 9]" |                            :tags="formData.Addresses.map(str => ({ text: str }))" | ||||||
|             :validate="validateCIDR" @on-tags-changed="handleChangeAddresses" /> |                            :placeholder="$t('modals.peer-edit.ip.placeholder')" | ||||||
|  |                            :validation="validateCIDR()" | ||||||
|  |                            :add-on-key="[13, 188, 32, 9]" | ||||||
|  |                            :save-on-key="[13, 188, 32, 9]" | ||||||
|  |                            :allow-edit-tags="true" | ||||||
|  |                            :separators="[',', ';', ' ']" | ||||||
|  |                            @tags-changed="handleChangeAddresses" /> | ||||||
|         </div> |         </div> | ||||||
|         <div class="form-group"> |         <div class="form-group"> | ||||||
|           <label class="form-label mt-4">{{ $t('modals.peer-edit.allowed-ip.label') }}</label> |           <label class="form-label mt-4">{{ $t('modals.peer-edit.allowed-ip.label') }}</label> | ||||||
|           <vue3-tags-input class="form-control" :tags="formData.AllowedIPs.Value" |           <vue-tags-input class="form-control" v-model="currentTags.AllowedIPs" | ||||||
|             :placeholder="$t('modals.peer-edit.allowed-ip.placeholder')" :add-tag-on-keys="[13, 188, 32, 9]" |                            :tags="formData.AllowedIPs.Value.map(str => ({ text: str }))" | ||||||
|             :validate="validateCIDR" @on-tags-changed="handleChangeAllowedIPs" /> |                            :placeholder="$t('modals.peer-edit.allowed-ip.placeholder')" | ||||||
|  |                            :validation="validateCIDR()" | ||||||
|  |                            :add-on-key="[13, 188, 32, 9]" | ||||||
|  |                            :save-on-key="[13, 188, 32, 9]" | ||||||
|  |                            :allow-edit-tags="true" | ||||||
|  |                            :separators="[',', ';', ' ']" | ||||||
|  |                            @tags-changed="handleChangeAllowedIPs" /> | ||||||
|         </div> |         </div> | ||||||
|         <div class="form-group"> |         <div class="form-group"> | ||||||
|           <label class="form-label mt-4">{{ $t('modals.peer-edit.extra-allowed-ip.label') }}</label> |           <label class="form-label mt-4">{{ $t('modals.peer-edit.extra-allowed-ip.label') }}</label> | ||||||
|           <vue3-tags-input class="form-control" :tags="formData.ExtraAllowedIPs" |           <vue-tags-input class="form-control" v-model="currentTags.ExtraAllowedIPs" | ||||||
|             :placeholder="$t('modals.peer-edit.extra-allowed-ip.placeholder')" :add-tag-on-keys="[13, 188, 32, 9]" |                           :tags="formData.ExtraAllowedIPs.map(str => ({ text: str }))" | ||||||
|             :validate="validateCIDR" @on-tags-changed="handleChangeExtraAllowedIPs" /> |                           :placeholder="$t('modals.peer-edit.extra-allowed-ip.placeholder')" | ||||||
|  |                           :validation="validateCIDR()" | ||||||
|  |                           :add-on-key="[13, 188, 32, 9]" | ||||||
|  |                           :save-on-key="[13, 188, 32, 9]" | ||||||
|  |                           :allow-edit-tags="true" | ||||||
|  |                           :separators="[',', ';', ' ']" | ||||||
|  |                           @tags-changed="handleChangeExtraAllowedIPs" /> | ||||||
|           <small class="form-text text-muted">{{ $t('modals.peer-edit.extra-allowed-ip.description') }}</small> |           <small class="form-text text-muted">{{ $t('modals.peer-edit.extra-allowed-ip.description') }}</small> | ||||||
|         </div> |         </div> | ||||||
|         <div class="form-group"> |         <div class="form-group"> | ||||||
|           <label class="form-label mt-4">{{ $t('modals.peer-edit.dns.label') }}</label> |           <label class="form-label mt-4">{{ $t('modals.peer-edit.dns.label') }}</label> | ||||||
|           <vue3-tags-input class="form-control" :tags="formData.Dns.Value" |           <vue-tags-input class="form-control" v-model="currentTags.Dns" | ||||||
|             :placeholder="$t('modals.peer-edit.dns.placeholder')" :add-tag-on-keys="[13, 188, 32, 9]" |                           :tags="formData.Dns.Value.map(str => ({ text: str }))" | ||||||
|             :validate="validateIP" @on-tags-changed="handleChangeDns" /> |                           :placeholder="$t('modals.peer-edit.dns.placeholder')" | ||||||
|  |                           :validation="validateIP()" | ||||||
|  |                           :add-on-key="[13, 188, 32, 9]" | ||||||
|  |                           :save-on-key="[13, 188, 32, 9]" | ||||||
|  |                           :allow-edit-tags="true" | ||||||
|  |                           :separators="[',', ';', ' ']" | ||||||
|  |                           @tags-changed="handleChangeDns" /> | ||||||
|         </div> |         </div> | ||||||
|         <div hidden class="form-group"> |         <div class="form-group"> | ||||||
|           <label class="form-label mt-4">{{ $t('modals.peer-edit.dns-search.label') }}</label> |           <label class="form-label mt-4">{{ $t('modals.peer-edit.dns-search.label') }}</label> | ||||||
|           <vue3-tags-input class="form-control" :tags="formData.DnsSearch.Value" |           <vue-tags-input class="form-control" v-model="currentTags.DnsSearch" | ||||||
|             :placeholder="$t('modals.peer-edit.dns-search.label')" :add-tag-on-keys="[13, 188, 32, 9]" |                           :tags="formData.DnsSearch.Value.map(str => ({ text: str }))" | ||||||
|             :validate="validateDomain" @on-tags-changed="handleChangeDnsSearch" /> |                           :placeholder="$t('modals.peer-edit.dns-search.label')" | ||||||
|  |                           :validation="validateDomain()" | ||||||
|  |                           :add-on-key="[13, 188, 32, 9]" | ||||||
|  |                           :save-on-key="[13, 188, 32, 9]" | ||||||
|  |                           :allow-edit-tags="true" | ||||||
|  |                           :separators="[',', ';', ' ']" | ||||||
|  |                           @tags-changed="handleChangeDnsSearch" /> | ||||||
|         </div> |         </div> | ||||||
|         <div class="row"> |         <div class="row"> | ||||||
|           <div class="form-group col-md-6"> |           <div class="form-group col-md-6"> | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ import {interfaceStore} from "@/stores/interfaces"; | ||||||
| import {computed, ref} from "vue"; | import {computed, ref} from "vue"; | ||||||
| import { useI18n } from 'vue-i18n'; | import { useI18n } from 'vue-i18n'; | ||||||
| import { notify } from "@kyvg/vue3-notification"; | import { notify } from "@kyvg/vue3-notification"; | ||||||
| import Vue3TagsInput from "vue3-tags-input"; | import { VueTagsInput } from '@vojtechlanka/vue-tags-input'; | ||||||
| import { freshInterface } from '@/helpers/models'; | import { freshInterface } from '@/helpers/models'; | ||||||
| 
 | 
 | ||||||
| const { t } = useI18n() | const { t } = useI18n() | ||||||
|  | @ -36,6 +36,7 @@ function freshForm() { | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | const currentTag = ref("") | ||||||
| const formData = ref(freshForm()) | const formData = ref(freshForm()) | ||||||
| 
 | 
 | ||||||
| const title = computed(() => { | const title = computed(() => { | ||||||
|  | @ -55,7 +56,7 @@ function close() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function handleChangeUserIdentifiers(tags) { | function handleChangeUserIdentifiers(tags) { | ||||||
|   formData.value.Identifiers = tags |   formData.value.Identifiers = tags.map(tag => tag.text) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async function save() { | async function save() { | ||||||
|  | @ -89,10 +90,14 @@ async function save() { | ||||||
|       <fieldset> |       <fieldset> | ||||||
|         <div class="form-group"> |         <div class="form-group"> | ||||||
|           <label class="form-label mt-4">{{ $t('modals.peer-multi-create.identifiers.label') }}</label> |           <label class="form-label mt-4">{{ $t('modals.peer-multi-create.identifiers.label') }}</label> | ||||||
|           <vue3-tags-input class="form-control" :tags="formData.Identifiers" |           <vue-tags-input class="form-control" v-model="currentTag" | ||||||
|  |                           :tags="formData.Identifiers.map(str => ({ text: str }))" | ||||||
|                           :placeholder="$t('modals.peer-multi-create.identifiers.placeholder')" |                           :placeholder="$t('modals.peer-multi-create.identifiers.placeholder')" | ||||||
|                            :add-tag-on-keys="[13, 188, 32, 9]" |                           :add-on-key="[13, 188, 32, 9]" | ||||||
|                            @on-tags-changed="handleChangeUserIdentifiers"/> |                           :save-on-key="[13, 188, 32, 9]" | ||||||
|  |                           :allow-edit-tags="true" | ||||||
|  |                           :separators="[',', ';', ' ']" | ||||||
|  |                           @tags-changed="handleChangeUserIdentifiers"/> | ||||||
|           <small class="form-text text-muted">{{ $t('modals.peer-multi-create.identifiers.description') }}</small> |           <small class="form-text text-muted">{{ $t('modals.peer-multi-create.identifiers.description') }}</small> | ||||||
|         </div> |         </div> | ||||||
|         <div class="form-group"> |         <div class="form-group"> | ||||||
|  |  | ||||||
|  | @ -1,14 +1,26 @@ | ||||||
| import isCidr from "is-cidr"; | import isCidr from "is-cidr"; | ||||||
| import {isIP} from 'is-ip'; | import {isIP} from 'is-ip'; | ||||||
| 
 | 
 | ||||||
| export function validateCIDR(value) { | export function validateCIDR() { | ||||||
|   return isCidr(value) !== 0 |   return [{ | ||||||
|  |     classes: 'invalid-cidr', | ||||||
|  |     rule: ({ text }) => isCidr(text) === 0, | ||||||
|  |     disableAdd: true, | ||||||
|  |   }] | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function validateIP(value) { | export function validateIP() { | ||||||
|   return isIP(value) |   return [{ | ||||||
|  |     classes: 'invalid-ip', | ||||||
|  |     rule: ({ text }) => !isIP(text), | ||||||
|  |     disableAdd: true, | ||||||
|  |   }] | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function validateDomain(value) { | export function validateDomain() { | ||||||
|   return true |   return [{ | ||||||
|  |     classes: 'invalid-domain', | ||||||
|  |     rule: tag => tag.text.length < 3, | ||||||
|  |     disableAdd: true, | ||||||
|  |   }] | ||||||
| } | } | ||||||
		Loading…
	
		Reference in New Issue