Skip to content

Commit

Permalink
Link add/edit: Fix profile selection (openhab#2941)
Browse files Browse the repository at this point in the history
Regression from openhab#2690.

Reported here:

https://community.openhab.org/t/enocean-impossible-to-link-a-rockerswitch-channel-with-an-item-in-main-ui-there-is-no-profile-available-for-the-selected-item/160987

When creating a Thing channel link to an item, the profile selection are
disabled. This presents two problems:

- It made linking a trigger channel to an item not possible, because a
profile must be selected, but they're disabled.
- Linking a non-trigger channel to a new item is possible, but selecting
a profile is not possible at link creation. The user has to create the
link without a profile first, then go back to edit the link in order to
assign a profile.

When editing a channel link, profile selection was possible for
unsupported profiles, e.g. when editing a link between a Switch Item and
a Number channel, one could edit the link to use the default or follow
profiles.

---------

Signed-off-by: Florian Hotze <[email protected]>
  • Loading branch information
florian-h05 authored Dec 24, 2024
1 parent 3861fa8 commit bd9c6f0
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@
Learn more about profiles.
</f7-link>
</f7-block-footer>
<f7-list class="profile-list profile-disabled">
<f7-list class="profile-list">
<f7-list-item radio v-for="profileType in profileTypes" class="profile-item"
:checked="(!currentProfileType && profileType.uid === 'system:default' && !isNumberChannelButNoNumberItem) || (currentProfileType && profileType.uid === currentProfileType.uid)"
:checked="(!currentProfileType && profileType.uid === 'system:default' && itemTypeIsChannelType(currentItem, channel)) || (currentProfileType && profileType.uid === currentProfileType.uid)"
:disabled="!compatibleProfileTypes.includes(profileType)"
:class="{ 'profile-disabled': !compatibleProfileTypes.includes(profileType) }"
@change="onProfileTypeChange(profileType.uid)"
Expand Down Expand Up @@ -131,11 +131,11 @@ import Item from '@/components/item/item.vue'
import * as Types from '@/assets/item-types.js'
import ItemMixin from '@/components/item/item-mixin'
import uomMixin from '@/components/item/uom-mixin'
import LinkMixin from '@/pages/settings/things/link/link-mixin'
export default {
mixins: [ItemMixin, uomMixin],
mixins: [ItemMixin, uomMixin, LinkMixin],
components: {
ConfigSheet,
ItemPicker,
Expand Down Expand Up @@ -181,15 +181,7 @@ export default {
return this.item ? this.item : (this.createMode ? this.newItem : (this.items ? this.items.find(item => item.name === this.selectedItemName) : null))
},
compatibleProfileTypes () {
let currentItemType = this.currentItem && this.currentItem.type ? this.currentItem.type : ''
return this.profileTypes
.filter(p => !p.supportedItemTypes.length || p.supportedItemTypes.includes(currentItemType.split(':', 1)[0]))
.filter(p => this.isNumberChannelButNoNumberItem && (p.uid !== 'system:default' && p.uid !== 'system:follow'))
},
isNumberChannelButNoNumberItem () {
if (!this.channel || !this.channel.itemType) return false
if (!this.currentItem || !this.currentItem.type) return false
return this.channel.itemType.startsWith('Number') && !this.currentItem.type.startsWith('Number')
return this.profileTypes.filter(p => this.isProfileTypeCompatible(this.channel, p, this.currentItem))
}
},
methods: {
Expand Down Expand Up @@ -220,8 +212,7 @@ export default {
loadProfileTypes (channel) {
this.ready = false
this.selectedChannel = channel
const getProfileTypes = this.$oh.api.get('/rest/profile-types?channelTypeUID=' + channel.channelTypeUID)
getProfileTypes.then((data) => {
this.$oh.api.get('/rest/profile-types?channelTypeUID=' + channel.channelTypeUID).then((data) => {
this.profileTypes = data
this.profileTypes.unshift(data.splice(data.findIndex(p => p.uid === 'system:default'), 1)[0]) // move default to be first
this.ready = true
Expand Down Expand Up @@ -304,7 +295,7 @@ export default {
return
}
}
if (this.isNumberChannelButNoNumberItem && (!this.currentProfileType || !this.compatibleProfileTypes.includes(this.currentProfileType))) {
if (!this.itemTypeIsChannelType(this.currentItem, this.channel) && (!this.currentProfileType || !this.compatibleProfileTypes.includes(this.currentProfileType))) {
this.$f7.dialog.alert('Please configure a valid profile')
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,10 @@ import ConfigSheet from '@/components/config/config-sheet.vue'
import Item from '@/components/item/item.vue'
import ItemStatePreview from '@/components/item/item-state-preview.vue'
import ThingStatus from '@/components/thing/thing-status-mixin'
import LinkMixin from '@/pages/settings/things/link/link-mixin'
export default {
mixins: [ThingStatus],
mixins: [ThingStatus, LinkMixin],
components: {
ConfigSheet,
Item,
Expand Down Expand Up @@ -137,7 +138,7 @@ export default {
this.$oh.api.get('/rest/profile-types?channelTypeUID=' + this.channel.channelTypeUID + '&itemType=' + itemType).then((data) => {
this.profileTypes = data
this.profileTypes.unshift(data.splice(data.findIndex(p => p.uid === 'system:default'), 1)[0]) // move default to be first
this.profileTypes = this.profileTypes.filter(p => !p.supportedItemTypes.length || p.supportedItemTypes.includes(this.item.type.split(':', 1)[0])) // only show compatible profile types
this.profileTypes = this.profileTypes.filter(p => this.isProfileTypeCompatible(this.channel, p, this.item)) // only show compatible profile types
this.$oh.api.get('/rest/links/' + itemName + '/' + channelUID).then((data2) => {
this.link = data2
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
export default {
methods: {
/**
* Check whether the type of the given Item does match the type of the given channel.
* @param {object} item
* @param {object} channel
* @return {boolean}
*/
itemTypeIsChannelType (item, channel) {
if (!channel || !channel.itemType) return true
if (!item || !item.type) return true
if (channel.itemType.startsWith('Number')) {
return item.type.startsWith('Number')
}
return channel.itemType === item.type
},
/**
* Check whether the given profileType is compatible with the given Item for the given channel.
*
* @param {object} channel
* @param {object} profileType
* @param {object} item
* @return {boolean}
*/
isProfileTypeCompatible (channel, profileType, item) {
if (!this.itemTypeIsChannelType(item, channel) && (profileType.uid === 'system:default' || profileType.uid === 'system:follow')) return false
if (!profileType.supportedItemTypes || profileType.supportedItemTypes.length === 0) return true
return profileType.supportedItemTypes.includes(item.type.split(':', 1)[0])
}
}
}

0 comments on commit bd9c6f0

Please sign in to comment.