Thing Add: Validate Thing ID before saving (#3009)
Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>pull/3014/head
parent
e7d9b65bc2
commit
9a9d363fb8
|
@ -7,7 +7,7 @@
|
|||
<f7-list inline-labels no-hairlines-md class="no-margin">
|
||||
<f7-list-input v-if="createMode" label="Thing ID" type="text" placeholder="Required" :value="thing.ID"
|
||||
@input="changeUID" info="Note: cannot be changed after the creation"
|
||||
required validate pattern="[A-Za-z0-9_\-]+" error-message="Required. A-Z,a-z,0-9,_,- only" />
|
||||
required :error-message="idErrorMessage" :error-message-force="!!idErrorMessage" />
|
||||
<f7-list-input label="Thing UID" type="text" :input="false" disabled>
|
||||
<span slot="input">
|
||||
{{ thing.UID }}
|
||||
|
@ -43,9 +43,11 @@
|
|||
<script>
|
||||
import ThingPicker from '@/components/config/controls/thing-picker.vue'
|
||||
import ClipboardIcon from '@/components/util/clipboard-icon.vue'
|
||||
import ThingMixin from '@/components/thing/thing-mixin'
|
||||
|
||||
export default {
|
||||
props: ['thing', 'thingType', 'createMode', 'ready', 'readOnly'],
|
||||
mixins: [ThingMixin],
|
||||
props: ['thing', 'thingType', 'createMode', 'ready', 'readOnly', 'things'],
|
||||
components: {
|
||||
ThingPicker,
|
||||
ClipboardIcon
|
||||
|
@ -53,6 +55,9 @@ export default {
|
|||
computed: {
|
||||
editable () {
|
||||
return this.createMode || (this.thing && this.thing.editable)
|
||||
},
|
||||
idErrorMessage () {
|
||||
return this.validateThingUID(this.thing.UID, this.thing.ID)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -63,11 +68,11 @@ export default {
|
|||
},
|
||||
changeUID (event) {
|
||||
this.$set(this.thing, 'ID', event.target.value)
|
||||
if (this.createMode) this.thing.UID = this.computedThingUid()
|
||||
this.thing.UID = this.computedThingUid()
|
||||
},
|
||||
updateBridge (value) {
|
||||
this.thing.bridgeUID = value
|
||||
if (this.createMode) this.thing.UID = this.computedThingUid()
|
||||
this.thing.UID = this.computedThingUid()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
export default {
|
||||
methods: {
|
||||
/**
|
||||
* Validate the Thing ID against valid characters and
|
||||
* if existing Things are available on `this.things`,
|
||||
* ensures that the Thing UID doesn't match an existing UID.
|
||||
*
|
||||
* @param {string} uid The Thing UID to validate
|
||||
* @param {string} id The Thing ID to validate
|
||||
* @returns {string} The error message if either the ID or the UID are invalid, or an empty string if they are valid.
|
||||
*/
|
||||
validateThingUID (uid, id) {
|
||||
if (!/^[A-Za-z0-9_-]+$/.test(id)) {
|
||||
return 'Required. Must not start with a number. A-Z,a-z,0-9,_ only'
|
||||
} else if (this.things && this.things.some(thing => thing.UID === uid)) {
|
||||
return `A Thing with '${uid}' UID already exists`
|
||||
}
|
||||
return ''
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
<f7-block v-if="ready" class="block-narrow">
|
||||
<f7-col>
|
||||
<thing-general-settings :thing="thing" :thing-type="thingType" :createMode="true" :ready="true" />
|
||||
<thing-general-settings :thing="thing" :thing-type="thingType" :createMode="true" :things="things" :ready="true" />
|
||||
<f7-block-title medium>
|
||||
{{ thingType.label }}
|
||||
</f7-block-title>
|
||||
|
@ -61,13 +61,15 @@
|
|||
import ConfigSheet from '@/components/config/config-sheet.vue'
|
||||
|
||||
import ThingGeneralSettings from '@/components/thing/thing-general-settings.vue'
|
||||
import ThingMixin from '@/components/thing/thing-mixin'
|
||||
|
||||
export default {
|
||||
mixins: [ThingMixin],
|
||||
props: ['thingTypeId', 'thingCopy'],
|
||||
components: {
|
||||
ConfigSheet,
|
||||
ThingGeneralSettings
|
||||
},
|
||||
props: ['thingTypeId', 'thingCopy'],
|
||||
data () {
|
||||
if (this.thingCopy) {
|
||||
delete this.thingCopy.editable
|
||||
|
@ -77,6 +79,7 @@ export default {
|
|||
return {
|
||||
ready: false,
|
||||
currentTab: 'info',
|
||||
things: [],
|
||||
thing: this.thingCopy || {
|
||||
UID: '',
|
||||
label: '',
|
||||
|
@ -118,7 +121,10 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
this.ready = true
|
||||
this.$oh.api.get('/rest/things?summary=true&staticDataOnly=true').then((things) => {
|
||||
this.things = things
|
||||
this.ready = true
|
||||
})
|
||||
})
|
||||
},
|
||||
save () {
|
||||
|
@ -126,6 +132,11 @@ export default {
|
|||
this.$f7.dialog.alert('Please give a unique identifier')
|
||||
return
|
||||
}
|
||||
const uidValidationError = this.validateThingUID(this.thing.UID, this.thing.ID)
|
||||
if (uidValidationError !== '') {
|
||||
this.$f7.dialog.alert('Invalid Thing ID: ' + uidValidationError)
|
||||
return
|
||||
}
|
||||
if (!this.thing.label) {
|
||||
this.$f7.dialog.alert('Please give a name')
|
||||
return
|
||||
|
@ -140,14 +151,18 @@ export default {
|
|||
})
|
||||
}
|
||||
|
||||
this.$oh.api.post('/rest/things', this.thing).then(() => {
|
||||
this.$f7.toast.create({
|
||||
text: 'Thing created',
|
||||
destroyOnClose: true,
|
||||
closeTimeout: 2000
|
||||
}).open()
|
||||
})
|
||||
setTimeout(() => { this.$f7router.navigate('/settings/things/', { reloadCurrent: true }) }, 300)
|
||||
this.$oh.api.post('/rest/things', this.thing)
|
||||
.then(() => {
|
||||
this.$f7.toast.create({
|
||||
text: 'Thing created',
|
||||
destroyOnClose: true,
|
||||
closeTimeout: 2000
|
||||
}).open()
|
||||
setTimeout(() => { this.$f7router.navigate('/settings/things/', { reloadCurrent: true }) }, 300)
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$f7.dialog.alert('Error creating Thing: ' + error)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue