diff --git a/bundles/org.openhab.ui/web/src/components/config/controls/item-picker.vue b/bundles/org.openhab.ui/web/src/components/config/controls/item-picker.vue index a063c2ee7a..e8381c4898 100644 --- a/bundles/org.openhab.ui/web/src/components/config/controls/item-picker.vue +++ b/bundles/org.openhab.ui/web/src/components/config/controls/item-picker.vue @@ -3,7 +3,7 @@ @@ -30,11 +30,11 @@ import ModelPickerPopup from '@/components/model/model-picker-popup.vue' export default { - props: ['title', 'name', 'value', 'multiple', 'filterType', 'required', 'editableOnly'], + props: ['title', 'name', 'value', 'items', 'multiple', 'filterType', 'required', 'editableOnly'], data () { return { ready: false, - items: [], + preparedItems: [], icons: {}, smartSelectParams: { view: this.$f7.view.main, @@ -48,23 +48,30 @@ export default { }, created () { this.smartSelectParams.closeOnSelect = !(this.multiple) - // TODO use a Vuex store - this.$oh.api.get('/rest/items').then((data) => { - this.items = data.sort((a, b) => { + if (!this.items) { + // TODO use a Vuex store + this.$oh.api.get('/rest/items').then((items) => { + this.sortAndFilterItems(items) + }) + } else { + this.sortAndFilterItems(this.items) + } + }, + methods: { + sortAndFilterItems (items) { + this.preparedItems = items.sort((a, b) => { const labelA = a.label || a.name const labelB = b.label || b.name return labelA.localeCompare(labelB) }) if (this.filterType) { - this.items = this.items.filter((i) => i.type === this.filterType) + this.preparedItems = this.preparedItems.filter((i) => i.type === this.filterType) } if (this.editableOnly) { - this.items = this.items.filter((i) => i.editable) + this.preparedItems = this.preparedItems.filter((i) => i.editable) } this.ready = true - }) - }, - methods: { + }, select (e) { this.$f7.input.validateInputs(this.$refs.smartSelect.$el) const value = this.$refs.smartSelect.f7SmartSelect.getValue() diff --git a/bundles/org.openhab.ui/web/src/components/item/item-form.vue b/bundles/org.openhab.ui/web/src/components/item/item-form.vue index 4e516f62c4..2f820882a7 100644 --- a/bundles/org.openhab.ui/web/src/components/item/item-form.vue +++ b/bundles/org.openhab.ui/web/src/components/item/item-form.vue @@ -1,34 +1,39 @@ @@ -46,15 +51,18 @@ import * as Types from '@/assets/item-types.js' import { Categories } from '@/assets/categories.js' export default { - props: ['item', 'enableName', 'hideCategory', 'hideType', 'hideSemantics', 'forceSemantics'], + props: ['item', 'items', 'enableName', 'hideCategory', 'hideType', 'hideSemantics', 'forceSemantics'], components: { SemanticsPicker }, data () { return { + ready: !this.enableName, types: Types, categoryInputId: '', - categoryAutocomplete: null + categoryAutocomplete: null, + allItems: [], + nameErrorMessage: '' } }, methods: { @@ -70,6 +78,36 @@ export default { } } }) + }, + onNameInput (event) { + this.item.name = event.target.value + this.validateName(this.item.name) + }, + validateName (name) { + let oldError = this.nameErrorMessage + if (!/^[A-Za-z0-9_]+$/.test(name)) { + this.nameErrorMessage = 'Required. Alphanumeric & underscores only' + } else if (this.allItems.some(item => item.name === name)) { + this.nameErrorMessage = 'An item with this name already exists' + } else { + this.nameErrorMessage = '' + } + if (oldError !== this.nameErrorMessage) this.$emit('valid', !this.nameErrorMessage) + } + }, + created () { + if (this.enableName) { + if (!this.items) { + this.$oh.api.get('/rest/items').then((items) => { + this.allItems = items + this.validateName(this.item.name) + this.ready = true + }) + } else { + this.allItems = this.items + this.validateName(this.item.name) + this.ready = true + } } }, mounted () { diff --git a/bundles/org.openhab.ui/web/src/pages/settings/things/link/link-add.vue b/bundles/org.openhab.ui/web/src/pages/settings/things/link/link-add.vue index 4c38ced5ee..d628c131c2 100644 --- a/bundles/org.openhab.ui/web/src/pages/settings/things/link/link-add.vue +++ b/bundles/org.openhab.ui/web/src/pages/settings/things/link/link-add.vue @@ -19,31 +19,36 @@ - - - Item - - - - - +
+ +
Loading...
+
+ @@ -138,6 +143,8 @@ export default { return { ready: true, createItem: false, + items: false, + itemValid: true, link: { itemName: null, channelUID: null, @@ -159,6 +166,13 @@ export default { semanticClasses: SemanticClasses } }, + created () { + if (!this.item) { + this.$oh.api.get('/rest/items').then((items) => { + this.items = items + }) + } + }, methods: { onPageAfterIn (event) { if (!this.channel) return @@ -247,6 +261,10 @@ export default { } // checks + if (this.createItem && !this.itemValid) { + this.$f7.dialog.alert('Please correct the item to link') + return + } if (!link.itemName) { this.$f7.dialog.alert('Please configure the item to link') return