diff --git a/bundles/org.openhab.ui/web/src/components/cards/card-mixin.js b/bundles/org.openhab.ui/web/src/components/cards/card-mixin.js index 0547a4667d..b6da1625a1 100644 --- a/bundles/org.openhab.ui/web/src/components/cards/card-mixin.js +++ b/bundles/org.openhab.ui/web/src/components/cards/card-mixin.js @@ -65,6 +65,12 @@ export default { } }, methods: { + itemPathLabel (item) { + if (!item.modelPath) return '(?) > ' + item.name + return item.modelPath.map((parent) => { + return parent.label || parent.name + }).join(' > ') + }, cardOpening () { this.cardId = this.title + '-' + this.$f7.utils.id() history.pushState({ cardId: this.cardId }, null, window.location.href.split('#card=')[0] + '#' + this.$f7.utils.serializeObject({ card: this.element.key })) diff --git a/bundles/org.openhab.ui/web/src/components/cards/equipment-card.vue b/bundles/org.openhab.ui/web/src/components/cards/equipment-card.vue index ebe8adb937..a26be10729 100644 --- a/bundles/org.openhab.ui/web/src/components/cards/equipment-card.vue +++ b/bundles/org.openhab.ui/web/src/components/cards/equipment-card.vue @@ -35,13 +35,13 @@ export default { }, computed: { listContext () { - const standaloneEquipment = this.element.equipment.filter((i) => i.points.length === 0).map((i) => itemDefaultListComponent(i.item, true)) + const standaloneEquipment = this.element.equipment.filter((i) => i.points.length === 0).map((i) => itemDefaultListComponent(i.item, this.itemPathLabel(i.item))) const equipmentWithPoints = this.element.equipment.filter((i) => i.points.length !== 0).map((i) => { return [ { component: 'oh-list-item', config: { - title: i.item.label || i.item.name, + title: [this.itemPathLabel(i.item), i.item.label || i.item.name].filter((label) => label && label.length > 0).join(' > '), divider: true } }, diff --git a/bundles/org.openhab.ui/web/src/components/cards/property-card.vue b/bundles/org.openhab.ui/web/src/components/cards/property-card.vue index 4de9c14367..fc4493403f 100644 --- a/bundles/org.openhab.ui/web/src/components/cards/property-card.vue +++ b/bundles/org.openhab.ui/web/src/components/cards/property-card.vue @@ -54,7 +54,7 @@ export default { divider: true } }, - ...this.itemsByPointType[pointType].map((p) => itemDefaultListComponent(p, true)) + ...this.itemsByPointType[pointType].map((p) => itemDefaultListComponent(p, this.itemPathLabel(p))) ]) } diff --git a/bundles/org.openhab.ui/web/src/components/widgets/standard/list/default-list-item.js b/bundles/org.openhab.ui/web/src/components/widgets/standard/list/default-list-item.js index 2ac1c9fc93..6ad67a4723 100644 --- a/bundles/org.openhab.ui/web/src/components/widgets/standard/list/default-list-item.js +++ b/bundles/org.openhab.ui/web/src/components/widgets/standard/list/default-list-item.js @@ -3,7 +3,7 @@ in the "listWidget" metadata namespace of the item */ -export default function itemDefaultListComponent (item, itemNameAsFooter) { +export default function itemDefaultListComponent (item, itemNameAsFooterOrLocation) { const stateDescription = item.stateDescription || {} const metadata = (item.metadata && item.metadata.listWidget) ? item.metadata.listWidget : {} let component = null @@ -98,7 +98,8 @@ export default function itemDefaultListComponent (item, itemNameAsFooter) { if (!component.config.title) component.config.title = item.label || item.name if (item.category && !component.config.icon) component.config.icon = 'oh:' + item.category if (item.category && ['Switch', 'Rollershutter', 'Contact', 'Dimmer', 'Group'].indexOf(item.type) >= 0) component.config.iconUseState = true - if (item.label && itemNameAsFooter) component.config.footer = item.name + if (item.label && itemNameAsFooterOrLocation === true) component.config.footer = item.name + else if (item.label && itemNameAsFooterOrLocation) component.config.footer = itemNameAsFooterOrLocation if (!item.category) component.config.fallbackIconToInitial = true return component diff --git a/bundles/org.openhab.ui/web/src/components/widgets/standard/list/oh-list-item.vue b/bundles/org.openhab.ui/web/src/components/widgets/standard/list/oh-list-item.vue index e0ed647ca2..a84e4ef427 100644 --- a/bundles/org.openhab.ui/web/src/components/widgets/standard/list/oh-list-item.vue +++ b/bundles/org.openhab.ui/web/src/components/widgets/standard/list/oh-list-item.vue @@ -1,6 +1,6 @@ + + diff --git a/bundles/org.openhab.ui/web/src/pages/home/homecards-mixin.js b/bundles/org.openhab.ui/web/src/pages/home/homecards-mixin.js index 88d514db7a..b014f473e7 100644 --- a/bundles/org.openhab.ui/web/src/pages/home/homecards-mixin.js +++ b/bundles/org.openhab.ui/web/src/pages/home/homecards-mixin.js @@ -50,10 +50,31 @@ export default { } } }, + // Recursively builds path in model (sorted array of relations to ancestors, either Equipment or Location) for an item + // that has semantics configuration and returns it + buildPathInModel (item) { + if (!item.metadata || !item.metadata.semantics) return + if (item.modelPath) return item.modelPath + // console.log(`Building path for ${item.name} with semantics ${item.metadata.semantics.config}`) + let parent = null + if (item.metadata.semantics.config && item.metadata.semantics.config.isPointOf) { + parent = (this.items.find((i) => i.name === item.metadata.semantics.config.isPointOf)) + } else if (item.metadata.semantics.config && item.metadata.semantics.config.isPartOf) { + parent = (this.items.find((i) => i.name === item.metadata.semantics.config.isPartOf)) + } else if (item.metadata.semantics.config && item.metadata.semantics.config.hasLocation) { + parent = (this.items.find((i) => i.name === item.metadata.semantics.config.hasLocation)) + } + item.modelPath = parent ? [...this.buildPathInModel(parent), parent] : [] + return item.modelPath + }, loadModel (page) { this.$oh.api.get('/rest/items?metadata=semantics,listWidget,widgetOrder') .then((data) => { this.items = data + // build model path for all model items + data.forEach((item) => { + if (item.metadata && item.metadata.semantics) this.buildPathInModel(item) + }) // get the location items const locations = data.filter((item, index, items) => { return item.metadata && item.metadata.semantics &&