Fix icons not displayed & not dynamic on all pages (#1849)
Fixes #1839. Fixes #574. Closes #1860. * Fixes Item icon styling on the Item detail page. * Add support for openHAB iconsets. * Fix `oh:` icons not properly displayed in `default-list-item.vue`. * Refactor `oh-icon` config & style binding. * Enable real-time state on the semantic model page. * Enable state for the channel link edit page. * Enable dynamic icons in the settings where missing and possible (semantic model page, channel link edit page, Item edit page when setting category, Items list page). * Enable dynamic icons in the default list widget for most Items except some and update the docs accordingly. * Add a refresh button to the Item list page. -- Signed-off-by: Florian Hotze <florianh_dev@icloud.com>pull/1850/head
parent
79fbc793e3
commit
095bb2f9cb
|
@ -56,7 +56,7 @@ Display a color picker in a list
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
||||||
<PropDescription>
|
<PropDescription>
|
||||||
Use the state of the item to get a dynamic icon (for openHAB icons only)
|
Use the state of the Item to get a dynamic icon (enabled by default for all Item types except <code>Call</code>, <code>Image</code> & <code>Location</code>) (for openHAB icons only)
|
||||||
</PropDescription>
|
</PropDescription>
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
</PropGroup>
|
</PropGroup>
|
||||||
|
|
|
@ -56,7 +56,7 @@ Display an input field in a list
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
||||||
<PropDescription>
|
<PropDescription>
|
||||||
Use the state of the item to get a dynamic icon (for openHAB icons only)
|
Use the state of the Item to get a dynamic icon (enabled by default for all Item types except <code>Call</code>, <code>Image</code> & <code>Location</code>) (for openHAB icons only)
|
||||||
</PropDescription>
|
</PropDescription>
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
</PropGroup>
|
</PropGroup>
|
||||||
|
|
|
@ -421,7 +421,7 @@ Display the state of an item in a card
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
||||||
<PropDescription>
|
<PropDescription>
|
||||||
Use the state of the item to get a dynamic icon (for openHAB icons only)
|
Use the state of the Item to get a dynamic icon (enabled by default for all Item types except <code>Call</code>, <code>Image</code> & <code>Location</code>) (for openHAB icons only)
|
||||||
</PropDescription>
|
</PropDescription>
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
<PropBlock type="BOOLEAN" name="vertical" label="Vertical arrangement">
|
<PropBlock type="BOOLEAN" name="vertical" label="Vertical arrangement">
|
||||||
|
|
|
@ -67,7 +67,7 @@ Display the state of an item in a list
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
||||||
<PropDescription>
|
<PropDescription>
|
||||||
Use the state of the item to get a dynamic icon (for openHAB icons only)
|
Use the state of the Item to get a dynamic icon (enabled by default for all Item types except <code>Call</code>, <code>Image</code> & <code>Location</code>) (for openHAB icons only)
|
||||||
</PropDescription>
|
</PropDescription>
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
</PropGroup>
|
</PropGroup>
|
||||||
|
|
|
@ -56,7 +56,7 @@ A list item
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
||||||
<PropDescription>
|
<PropDescription>
|
||||||
Use the state of the item to get a dynamic icon (for openHAB icons only)
|
Use the state of the Item to get a dynamic icon (enabled by default for all Item types except <code>Call</code>, <code>Image</code> & <code>Location</code>) (for openHAB icons only)
|
||||||
</PropDescription>
|
</PropDescription>
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
</PropGroup>
|
</PropGroup>
|
||||||
|
|
|
@ -62,7 +62,7 @@ A marker on a floor plan
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
||||||
<PropDescription>
|
<PropDescription>
|
||||||
Use the state of the item to get a dynamic icon (for openHAB icons only)
|
Use the state of the Item to get a dynamic icon (enabled by default for all Item types except <code>Call</code>, <code>Image</code> & <code>Location</code>) (for openHAB icons only)
|
||||||
</PropDescription>
|
</PropDescription>
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
<PropBlock type="INTEGER" name="iconSize" label="Icon Size">
|
<PropBlock type="INTEGER" name="iconSize" label="Icon Size">
|
||||||
|
|
|
@ -56,7 +56,7 @@ Display player controls in a list
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
||||||
<PropDescription>
|
<PropDescription>
|
||||||
Use the state of the item to get a dynamic icon (for openHAB icons only)
|
Use the state of the Item to get a dynamic icon (enabled by default for all Item types except <code>Call</code>, <code>Image</code> & <code>Location</code>) (for openHAB icons only)
|
||||||
</PropDescription>
|
</PropDescription>
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
</PropGroup>
|
</PropGroup>
|
||||||
|
|
|
@ -56,7 +56,7 @@ Display rollershutter controls in a list
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
||||||
<PropDescription>
|
<PropDescription>
|
||||||
Use the state of the item to get a dynamic icon (for openHAB icons only)
|
Use the state of the Item to get a dynamic icon (enabled by default for all Item types except <code>Call</code>, <code>Image</code> & <code>Location</code>) (for openHAB icons only)
|
||||||
</PropDescription>
|
</PropDescription>
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
</PropGroup>
|
</PropGroup>
|
||||||
|
|
|
@ -56,7 +56,7 @@ Display a slider control in a list
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
||||||
<PropDescription>
|
<PropDescription>
|
||||||
Use the state of the item to get a dynamic icon (for openHAB icons only)
|
Use the state of the Item to get a dynamic icon (enabled by default for all Item types except <code>Call</code>, <code>Image</code> & <code>Location</code>) (for openHAB icons only)
|
||||||
</PropDescription>
|
</PropDescription>
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
</PropGroup>
|
</PropGroup>
|
||||||
|
|
|
@ -56,7 +56,7 @@ Display a stepper control in a list
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
||||||
<PropDescription>
|
<PropDescription>
|
||||||
Use the state of the item to get a dynamic icon (for openHAB icons only)
|
Use the state of the Item to get a dynamic icon (enabled by default for all Item types except <code>Call</code>, <code>Image</code> & <code>Location</code>) (for openHAB icons only)
|
||||||
</PropDescription>
|
</PropDescription>
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
</PropGroup>
|
</PropGroup>
|
||||||
|
|
|
@ -56,7 +56,7 @@ Display a toggle switch in a list
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
<PropBlock type="BOOLEAN" name="iconUseState" label="Icon depends on state">
|
||||||
<PropDescription>
|
<PropDescription>
|
||||||
Use the state of the item to get a dynamic icon (for openHAB icons only)
|
Use the state of the Item to get a dynamic icon (enabled by default for all Item types except <code>Call</code>, <code>Image</code> & <code>Location</code>) (for openHAB icons only)
|
||||||
</PropDescription>
|
</PropDescription>
|
||||||
</PropBlock>
|
</PropBlock>
|
||||||
</PropGroup>
|
</PropGroup>
|
||||||
|
|
|
@ -34,7 +34,7 @@ export const OhPlanMarkerDefinition = () => new WidgetDefinition('oh-plan-marker
|
||||||
])
|
])
|
||||||
.paramGroup(pg('icon', 'Icon', 'You can customize the styles further with CSS attributes in the <code>iconStyle</code> parameter (in YAML only)'), [
|
.paramGroup(pg('icon', 'Icon', 'You can customize the styles further with CSS attributes in the <code>iconStyle</code> parameter (in YAML only)'), [
|
||||||
pt('icon', 'Icon', 'Use <code>oh:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://www.openhab.org/link/icons">openHAB icon</a>), <code>f7:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://framework7.io/icons/">Framework7 icon</a>), <code>material:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://jossef.github.io/material-design-icons-iconfont/">Material icon</a>) or <code>iconify:iconSet:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://icon-sets.iconify.design">Iconify icon</a>, requires being online if not in cache)'),
|
pt('icon', 'Icon', 'Use <code>oh:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://www.openhab.org/link/icons">openHAB icon</a>), <code>f7:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://framework7.io/icons/">Framework7 icon</a>), <code>material:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://jossef.github.io/material-design-icons-iconfont/">Material icon</a>) or <code>iconify:iconSet:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://icon-sets.iconify.design">Iconify icon</a>, requires being online if not in cache)'),
|
||||||
pb('iconUseState', 'Icon depends on state', 'Use the state of the item to get a dynamic icon (for openHAB icons only)'),
|
pb('iconUseState', 'Icon depends on state', 'Use the state of the Item to get a dynamic icon (enabled by default for all Item types except <code>Call</code>, <code>Image</code> & <code>Location</code>) (for openHAB icons only)').a(),
|
||||||
pn('iconSize', 'Icon Size', 'Size of the icon in pixels (40 by default)'),
|
pn('iconSize', 'Icon Size', 'Size of the icon in pixels (40 by default)'),
|
||||||
pn('iconWidth', 'Icon Width', 'Width of the icon in pixels (for openHAB icons only, 40 by default)').a(),
|
pn('iconWidth', 'Icon Width', 'Width of the icon in pixels (for openHAB icons only, 40 by default)').a(),
|
||||||
pn('iconHeight', 'Icon Height', 'Height of the icon in pixels (for openHAB icons only, 40 by default)').a(),
|
pn('iconHeight', 'Icon Height', 'Height of the icon in pixels (for openHAB icons only, 40 by default)').a(),
|
||||||
|
|
|
@ -28,7 +28,7 @@ export const OhLabelCardDefinition = () => new WidgetDefinition('oh-label-card',
|
||||||
pt('icon', 'Icon', 'Use <code>oh:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://www.openhab.org/link/icons">openHAB icon</a>), <code>f7:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://framework7.io/icons/">Framework7 icon</a>), <code>material:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://jossef.github.io/material-design-icons-iconfont/">Material icon</a>) or <code>iconify:iconSet:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://icon-sets.iconify.design">Iconify icon</a>, requires being online if not in cache)'),
|
pt('icon', 'Icon', 'Use <code>oh:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://www.openhab.org/link/icons">openHAB icon</a>), <code>f7:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://framework7.io/icons/">Framework7 icon</a>), <code>material:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://jossef.github.io/material-design-icons-iconfont/">Material icon</a>) or <code>iconify:iconSet:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://icon-sets.iconify.design">Iconify icon</a>, requires being online if not in cache)'),
|
||||||
pt('iconColor', 'Icon Color', 'Not applicable to openHAB icons').a(),
|
pt('iconColor', 'Icon Color', 'Not applicable to openHAB icons').a(),
|
||||||
pn('iconSize', 'Icon Size', 'Size of the icon in px').a(),
|
pn('iconSize', 'Icon Size', 'Size of the icon in px').a(),
|
||||||
pb('iconUseState', 'Icon depends on state', 'Use the state of the item to get a dynamic icon (for openHAB icons only)').a(),
|
pb('iconUseState', 'Icon depends on state', 'Use the state of the Item to get a dynamic icon (enabled by default for all Item types except <code>Call</code>, <code>Image</code> & <code>Location</code>) (for openHAB icons only)').a(),
|
||||||
pb('vertical', 'Vertical arrangement', 'Display label below icon')
|
pb('vertical', 'Vertical arrangement', 'Display label below icon')
|
||||||
])
|
])
|
||||||
.paramGroup(pg('trend', 'Trend Line', 'Show a trend line in the background'), TrendParameters())
|
.paramGroup(pg('trend', 'Trend Line', 'Show a trend line in the background'), TrendParameters())
|
||||||
|
|
|
@ -11,7 +11,7 @@ export const ListItemParameters = () => [
|
||||||
pt('after', 'After', 'Text to display on the opposite side of the item (set either this or a badge)').a(),
|
pt('after', 'After', 'Text to display on the opposite side of the item (set either this or a badge)').a(),
|
||||||
pt('icon', 'Icon', 'Use <code>oh:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://www.openhab.org/link/icons">openHAB icon</a>), <code>f7:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://framework7.io/icons/">Framework7 icon</a>), <code>material:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://jossef.github.io/material-design-icons-iconfont/">Material icon</a>) or <code>iconify:iconSet:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://icon-sets.iconify.design">Iconify icon</a>, requires being online if not in cache)'),
|
pt('icon', 'Icon', 'Use <code>oh:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://www.openhab.org/link/icons">openHAB icon</a>), <code>f7:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://framework7.io/icons/">Framework7 icon</a>), <code>material:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://jossef.github.io/material-design-icons-iconfont/">Material icon</a>) or <code>iconify:iconSet:iconName</code> (<a class="external text-color-blue" target="_blank" href="https://icon-sets.iconify.design">Iconify icon</a>, requires being online if not in cache)'),
|
||||||
pt('iconColor', 'Icon Color', 'Not applicable to openHAB icons').a(),
|
pt('iconColor', 'Icon Color', 'Not applicable to openHAB icons').a(),
|
||||||
pb('iconUseState', 'Icon depends on state', 'Use the state of the item to get a dynamic icon (for openHAB icons only)').a()
|
pb('iconUseState', 'Icon depends on state', 'Use the state of the Item to get a dynamic icon (enabled by default for all Item types except <code>Call</code>, <code>Image</code> & <code>Location</code>) (for openHAB icons only)').a()
|
||||||
]
|
]
|
||||||
|
|
||||||
// OhListItem
|
// OhListItem
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
<div v-if="item" class="quick-link-form no-padding">
|
<div v-if="item" class="quick-link-form no-padding">
|
||||||
<f7-list inline-labels no-hairlines-md>
|
<f7-list inline-labels no-hairlines-md>
|
||||||
<f7-list-input label="Name" type="text" placeholder="Required" :value="item.name"
|
<f7-list-input label="Name" type="text" placeholder="Required" :value="item.name"
|
||||||
:disabled="!enableName" :info="(enableName) ? 'Note: cannot be changed after the creation' : ''"
|
:disabled="!createMode" :info="(createMode) ? 'Note: cannot be changed after the creation' : ''"
|
||||||
required :error-message="nameErrorMessage" :error-message-force="!!nameErrorMessage"
|
required :error-message="nameErrorMessage" :error-message-force="!!nameErrorMessage"
|
||||||
@input="onNameInput" :clear-button="enableName" />
|
@input="onNameInput" :clear-button="createMode" />
|
||||||
<f7-list-input label="Label" type="text" placeholder="Label" :value="item.label"
|
<f7-list-input label="Label" type="text" placeholder="Label" :value="item.label"
|
||||||
@input="item.label = $event.target.value" clear-button />
|
@input="item.label = $event.target.value" clear-button />
|
||||||
<f7-list-item v-if="item.type && !hideType" title="Type" type="text" smart-select :smart-select-params="{searchbar: true, openIn: 'popup', closeOnSelect: true}">
|
<f7-list-item v-if="item.type && !hideType" title="Type" type="text" smart-select :smart-select-params="{searchbar: true, openIn: 'popup', closeOnSelect: true}">
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
<f7-list-input v-if="!hideCategory" ref="category" label="Category" autocomplete="off" type="text" placeholder="temperature, firstfloor..." :value="item.category"
|
<f7-list-input v-if="!hideCategory" ref="category" label="Category" autocomplete="off" type="text" placeholder="temperature, firstfloor..." :value="item.category"
|
||||||
@input="item.category = $event.target.value" clear-button>
|
@input="item.category = $event.target.value" clear-button>
|
||||||
<div slot="root-end" style="margin-left: calc(35% + 8px)">
|
<div slot="root-end" style="margin-left: calc(35% + 8px)">
|
||||||
<oh-icon :icon="item.category" height="32" width="32" />
|
<oh-icon :icon="item.category" :state="(createMode) ? null : item.state" height="32" width="32" />
|
||||||
</div>
|
</div>
|
||||||
</f7-list-input>
|
</f7-list-input>
|
||||||
</f7-list>
|
</f7-list>
|
||||||
|
@ -46,7 +46,7 @@ import * as Types from '@/assets/item-types.js'
|
||||||
import { Categories } from '@/assets/categories.js'
|
import { Categories } from '@/assets/categories.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['item', 'items', 'enableName', 'hideCategory', 'hideType', 'hideSemantics', 'forceSemantics'],
|
props: ['item', 'items', 'createMode', 'hideCategory', 'hideType', 'hideSemantics', 'forceSemantics'],
|
||||||
components: {
|
components: {
|
||||||
SemanticsPicker
|
SemanticsPicker
|
||||||
},
|
},
|
||||||
|
@ -91,7 +91,7 @@ export default {
|
||||||
mounted () {
|
mounted () {
|
||||||
if (!this.item) return
|
if (!this.item) return
|
||||||
if (!this.item.category) this.$set(this.item, 'category', '')
|
if (!this.item.category) this.$set(this.item, 'category', '')
|
||||||
if (this.enableName) {
|
if (this.createMode) {
|
||||||
if (!this.items) this.items = []
|
if (!this.items) this.items = []
|
||||||
this.validateName(this.item.name)
|
this.validateName(this.item.name)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
:subtitle="getItemTypeAndMetaLabel(item)"
|
:subtitle="getItemTypeAndMetaLabel(item)"
|
||||||
:after="state"
|
:after="state"
|
||||||
v-on="$listeners">
|
v-on="$listeners">
|
||||||
<oh-icon v-if="!noIcon && item.category" slot="media" :icon="item.category" height="32" width="32" />
|
<oh-icon v-if="!noIcon && item.category" slot="media" :icon="item.category" :state="(noState) ? null : (context && context.store) ? context.store[item.name].state : item.state" height="32" width="32" />
|
||||||
<span v-else-if="!noIcon" slot="media" class="item-initial">{{ item.name[0] }}</span>
|
<span v-else-if="!noIcon" slot="media" class="item-initial">{{ item.name[0] }}</span>
|
||||||
<f7-icon v-if="!item.editable && !ignoreEditable" slot="after-title" f7="lock_fill" size="1rem" color="gray" />
|
<f7-icon v-if="!item.editable && !ignoreEditable" slot="after-title" f7="lock_fill" size="1rem" color="gray" />
|
||||||
<slot name="footer" #footer />
|
<slot name="footer" #footer />
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<item-state-preview v-if="model.item.created !== false" :item="model.item" :context="context" :key="$utils.id()" />
|
<item-state-preview v-if="model.item.created !== false" :item="model.item" :context="context" :key="$utils.id()" />
|
||||||
|
|
||||||
<f7-block-title>Item</f7-block-title>
|
<f7-block-title>Item</f7-block-title>
|
||||||
<item-details :model="model" :links="links" :items="items" @item-updated="$emit('item-updated')" @item-created="$emit('item-created')" @item-removed="$emit('item-removed')" @cancel-create="$emit('cancel-create')" />
|
<item-details :model="model" :links="links" :items="items" :context="context" @item-updated="$emit('item-updated')" @item-created="$emit('item-created')" @item-removed="$emit('item-removed')" @cancel-create="$emit('cancel-create')" />
|
||||||
<f7-block-title v-if="model.item.created !== false">
|
<f7-block-title v-if="model.item.created !== false">
|
||||||
Metadata
|
Metadata
|
||||||
</f7-block-title>
|
</f7-block-title>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<f7-card-content>
|
<f7-card-content>
|
||||||
<f7-list media-list accordion-list>
|
<f7-list media-list accordion-list>
|
||||||
<ul>
|
<ul>
|
||||||
<item v-if="!createMode" :item="model.item" :link="'/settings/items/' + model.item.name" :no-state="true" />
|
<item v-if="!createMode" :item="model.item" :link="'/settings/items/' + model.item.name" :context="context" />
|
||||||
<!-- <f7-list-button v-if="!editMode && !createMode" color="blue" title="Edit Item" @click="editMode = true">Edit Item</f7-list-button> -->
|
<!-- <f7-list-button v-if="!editMode && !createMode" color="blue" title="Edit Item" @click="editMode = true">Edit Item</f7-list-button> -->
|
||||||
</ul>
|
</ul>
|
||||||
</f7-list>
|
</f7-list>
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
<item-form :item="editedItem" :hide-type="true" :force-semantics="forceSemantics" />
|
<item-form :item="editedItem" :hide-type="true" :force-semantics="forceSemantics" />
|
||||||
</div>
|
</div>
|
||||||
<div class="padding-top" v-else-if="createMode">
|
<div class="padding-top" v-else-if="createMode">
|
||||||
<item-form :item="editedItem" :items="items" :enable-name="true" :force-semantics="forceSemantics" />
|
<item-form :item="editedItem" :items="items" :createMode="true" :force-semantics="forceSemantics" />
|
||||||
</div>
|
</div>
|
||||||
</f7-card-content>
|
</f7-card-content>
|
||||||
<f7-card-footer v-if="createMode || editMode" key="item-card-buttons">
|
<f7-card-footer v-if="createMode || editMode" key="item-card-buttons">
|
||||||
|
@ -42,7 +42,7 @@ import Item from '@/components/item/item.vue'
|
||||||
import ItemForm from '@/components/item/item-form.vue'
|
import ItemForm from '@/components/item/item-form.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['model', 'links', 'items'],
|
props: ['model', 'links', 'items', 'context'],
|
||||||
components: {
|
components: {
|
||||||
Item,
|
Item,
|
||||||
ItemForm
|
ItemForm
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
:footer="(link.item.label) ? link.item.name : '\xa0'"
|
:footer="(link.item.label) ? link.item.name : '\xa0'"
|
||||||
:subtitle="getItemTypeAndMetaLabel(link.item)"
|
:subtitle="getItemTypeAndMetaLabel(link.item)"
|
||||||
:after="context.store[link.item.name] ? context.store[link.item.name].displayState || context.store[link.item.name].state : link.item.state">
|
:after="context.store[link.item.name] ? context.store[link.item.name].displayState || context.store[link.item.name].state : link.item.state">
|
||||||
<oh-icon v-if="link.item.category" slot="media" :icon="link.item.category" height="32" width="32" />
|
<oh-icon v-if="link.item.category" slot="media" :icon="link.item.category" :state="context.store[link.item.name] ? context.store[link.item.name].state : link.item.state" height="32" width="32" />
|
||||||
<span v-else slot="media" class="item-initial">{{ link.item.name[0] }}</span>
|
<span v-else slot="media" class="item-initial">{{ link.item.name[0] }}</span>
|
||||||
<f7-icon v-if="!link.item.editable" slot="after-title" f7="lock_fill" size="1rem" color="gray" />
|
<f7-icon v-if="!link.item.editable" slot="after-title" f7="lock_fill" size="1rem" color="gray" />
|
||||||
<!-- <f7-button slot="after-start" color="blue" icon-f7="compose" icon-size="24px" :link="`${item.name}/edit`"></f7-button> -->
|
<!-- <f7-button slot="after-start" color="blue" icon-f7="compose" icon-size="24px" :link="`${item.name}/edit`"></f7-button> -->
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
@channel-updated="(e) => $emit('channels-updated', e)" />
|
@channel-updated="(e) => $emit('channels-updated', e)" />
|
||||||
</template>
|
</template>
|
||||||
<template #default="{ channel }" v-else-if="multipleLinksMode">
|
<template #default="{ channel }" v-else-if="multipleLinksMode">
|
||||||
<item-form v-if="isChecked(channel)" :item="newItem(channel)" :items="items" :enable-name="true" :channel="channel" :checked="isChecked(channel)" />
|
<item-form v-if="isChecked(channel)" :item="newItem(channel)" :items="items" :createMode="true" :channel="channel" :checked="isChecked(channel)" />
|
||||||
</template>
|
</template>
|
||||||
<!-- <channel-link #default="{ channelId }" /> -->
|
<!-- <channel-link #default="{ channelId }" /> -->
|
||||||
</channel-group>
|
</channel-group>
|
||||||
|
|
|
@ -165,8 +165,8 @@ export default function itemDefaultListComponent (item, footer) {
|
||||||
}
|
}
|
||||||
if (!component.config.item) component.config.item = item.name
|
if (!component.config.item) component.config.item = item.name
|
||||||
if (!component.config.title) component.config.title = item.label || item.name
|
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 && !component.config.icon) component.config.icon = item.category
|
||||||
if (item.category && ['Switch', 'Rollershutter', 'Contact', 'Dimmer', 'Group'].indexOf(item.type) >= 0) component.config.iconUseState = true
|
if (item.category && component.config.iconUseState === undefined && !['Call', 'Image', 'Location'].includes(item.type)) component.config.iconUseState = true
|
||||||
if (item.label && footer && footer.contextLabelSource) {
|
if (item.label && footer && footer.contextLabelSource) {
|
||||||
let text = itemContextLabel(item, footer)
|
let text = itemContextLabel(item, footer)
|
||||||
if (text) component.config.footer = text
|
if (text) component.config.footer = text
|
||||||
|
|
|
@ -2,21 +2,16 @@
|
||||||
<img v-if="iconType === 'oh'"
|
<img v-if="iconType === 'oh'"
|
||||||
:src="iconUrl" v-bind="config" @click="performAction()"
|
:src="iconUrl" v-bind="config" @click="performAction()"
|
||||||
:style="{
|
:style="{
|
||||||
width: (context && config && config.width) ? config.width + 'px' : (width) ? width + 'px' : 'auto',
|
width: (resolvedConfig.width !== null) ? resolvedConfig.width + 'px' : 'auto',
|
||||||
height: (context && config && config.height) ? config.height + 'px' : (height) ? height + 'px' : 'auto',
|
height: (resolvedConfig.height !== null) ? resolvedConfig.height + 'px' : 'auto',
|
||||||
...(config) ? config.style : {} }"
|
...resolvedStyle }"
|
||||||
onload="this.classList.remove('no-icon')" onerror="this.classList.add('no-icon')">
|
onload="this.classList.remove('no-icon')" onerror="this.classList.add('no-icon')">
|
||||||
<f7-icon v-else-if="iconType === 'f7'"
|
<f7-icon v-else-if="iconType === 'f7'" v-bind="resolvedConfig"
|
||||||
:ios="icon || ((config) ? config.icon : null)" :md="icon || ((config) ? config.icon : null)" :aurora="icon || ((config) ? config.icon : null)"
|
:size="resolvedConfig.width || resolvedConfig.height || null"
|
||||||
:color="color || ((config) ? config.color : null)" :size="width || height || ((config) ? (config.width || config.height) : null)"
|
:style="resolvedStyle" />
|
||||||
:style="(config) ? config.style : null" />
|
<iconify-icon v-else-if="iconType === 'iconify'" v-bind="resolvedConfig"
|
||||||
<iconify-icon v-else-if="iconType === 'iconify'"
|
|
||||||
:icon="iconName"
|
:icon="iconName"
|
||||||
:width="width || ((config) ? config.width : null)" :height="height || ((config) ? config.height : null)"
|
:style="resolvedStyle" />
|
||||||
:color="color || ((config) ? config.color : null)" :rotate="rotate || ((config) ? config.rotate : null)"
|
|
||||||
:horizontal-flip="horizontalFlip || ((config) ? config.horizontalFlip : null)"
|
|
||||||
:vertical-flip="verticalFlip || ((config) ? config.verticalFlip : null)"
|
|
||||||
:style="(config) ? config.style : null" />
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="stylus">
|
<style lang="stylus">
|
||||||
|
@ -35,7 +30,7 @@ export default {
|
||||||
components: {
|
components: {
|
||||||
'iconify-icon': Icon
|
'iconify-icon': Icon
|
||||||
},
|
},
|
||||||
props: ['icon', 'width', 'height', 'color', 'flip', 'state', 'rotate', 'horizontalFlip', 'verticalFlip'],
|
props: ['icon', 'width', 'height', 'color', 'state', 'rotate', 'horizontalFlip', 'verticalFlip'],
|
||||||
widget: OhIconDefinition,
|
widget: OhIconDefinition,
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
@ -45,6 +40,24 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
resolvedStyle () {
|
||||||
|
return {
|
||||||
|
...(this.config && this.config.style) ? this.config.style : {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resolvedConfig () {
|
||||||
|
return {
|
||||||
|
width: (this.width) ? this.width : (this.config && this.config.width) ? this.config.width : null,
|
||||||
|
height: (this.height) ? this.height : (this.config && this.config.height) ? this.config.height : null,
|
||||||
|
color: (this.color) ? this.color : (this.config && this.config.color) ? this.config.color : null,
|
||||||
|
rotate: (this.rotate) ? this.rotate : (this.config && this.config.rotate) ? this.config.rotate : null,
|
||||||
|
horizontalFlip: (this.horizontalFlip) ? this.horizontalFlip : (this.config && this.config.horizontalFlip) ? this.config.horizontalFlip : null,
|
||||||
|
verticalFlip: (this.verticalFlip) ? this.verticalFlip : (this.config && this.config.verticalFlip) ? this.config.verticalFlip : null,
|
||||||
|
ios: (this.icon) ? this.icon : (this.config && this.config.icon) ? this.config.icon : null,
|
||||||
|
md: (this.icon) ? this.icon : (this.config && this.config.icon) ? this.config.icon : null,
|
||||||
|
aurora: (this.icon) ? this.icon : (this.config && this.config.icon) ? this.config.icon : null
|
||||||
|
}
|
||||||
|
},
|
||||||
iconType () {
|
iconType () {
|
||||||
const icon = (this.context) ? this.config.icon : this.icon
|
const icon = (this.context) ? this.config.icon : this.icon
|
||||||
if (!icon) return 'oh'
|
if (!icon) return 'oh'
|
||||||
|
@ -53,9 +66,20 @@ export default {
|
||||||
if (icon.indexOf('if') === 0 || icon.indexOf('iconify') === 0) return 'iconify'
|
if (icon.indexOf('if') === 0 || icon.indexOf('iconify') === 0) return 'iconify'
|
||||||
return 'oh'
|
return 'oh'
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Icon set, for openHAB icons only.
|
||||||
|
* Defaults to 'classic'.
|
||||||
|
* @returns {*|string}
|
||||||
|
*/
|
||||||
|
iconSet () {
|
||||||
|
const icon = (this.context) ? this.config.icon : this.icon
|
||||||
|
if (icon.indexOf('oh:') === 0 && icon.split(':').length === 3) return icon.split(':')[1]
|
||||||
|
return 'classic'
|
||||||
|
},
|
||||||
iconName () {
|
iconName () {
|
||||||
const icon = (this.context) ? this.config.icon : this.icon
|
const icon = (this.context) ? this.config.icon : this.icon
|
||||||
if (!(typeof icon === 'string' || icon instanceof String)) return ''
|
if (!(typeof icon === 'string' || icon instanceof String)) return ''
|
||||||
|
if (icon.indexOf('oh:') === 0 && icon.split(':').length === 3) return icon.split(':')[2]
|
||||||
if (icon.indexOf(':') >= 0) return icon.substring(icon.indexOf(':') + 1)
|
if (icon.indexOf(':') >= 0) return icon.substring(icon.indexOf(':') + 1)
|
||||||
return icon
|
return icon
|
||||||
},
|
},
|
||||||
|
@ -90,7 +114,7 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
updateIcon () {
|
updateIcon () {
|
||||||
if (!this.currentIcon) return
|
if (!this.currentIcon) return
|
||||||
this.$oh.media.getIcon(this.currentIcon, this.iconFormat, this.currentState).then((url) => {
|
this.$oh.media.getIcon(this.currentIcon, this.iconFormat, this.currentState, this.iconSet).then((url) => {
|
||||||
if (url !== this.iconUrl) {
|
if (url !== this.iconUrl) {
|
||||||
this.iconUrl = url
|
this.iconUrl = url
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,11 @@ import { getBasicCredentials } from '@/js/openhab/auth'
|
||||||
import Framework7 from 'framework7/framework7-lite.esm.bundle.js'
|
import Framework7 from 'framework7/framework7-lite.esm.bundle.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getIcon: (icon, format, state) => {
|
getIcon: (icon, format, state, iconSet) => {
|
||||||
if (!format) format = 'svg'
|
if (!format) format = 'svg'
|
||||||
let url = `/icon/${icon}?format=${format}&anyFormat=true`
|
let url = `/icon/${icon}?format=${format}&anyFormat=true`
|
||||||
if (state) url += `&state=${encodeURIComponent(state)}`
|
if (state) url += `&state=${encodeURIComponent(state)}`
|
||||||
|
if (iconSet) url += `&iconset=${iconSet}`
|
||||||
|
|
||||||
if (getBasicCredentials()) {
|
if (getBasicCredentials()) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
</f7-nav-right>
|
</f7-nav-right>
|
||||||
<f7-subnavbar sliding class="item-header">
|
<f7-subnavbar sliding class="item-header">
|
||||||
<div class="item-icon" v-if="item.name">
|
<div class="item-icon" v-if="item.name">
|
||||||
<oh-icon v-if="item.category" :icon="item.category" height="60" width="60" />
|
<oh-icon v-if="item.category" :icon="item.category" :state="context.store[item.name] ? context.store[item.name].state : item.state" height="60" width="60" />
|
||||||
<span v-else>
|
<span v-else>
|
||||||
{{ item.label ? item.label[0] : item.name[0] }}
|
{{ item.label ? item.label[0] : item.name[0] }}
|
||||||
</span>
|
</span>
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
width 60px
|
width 60px
|
||||||
padding 10px
|
padding 10px
|
||||||
border-radius 40px
|
border-radius 40px
|
||||||
background white
|
border 1px solid white
|
||||||
img
|
img
|
||||||
height 60px
|
height 60px
|
||||||
width 60px
|
width 60px
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
</div>
|
</div>
|
||||||
</f7-col>
|
</f7-col>
|
||||||
<f7-col>
|
<f7-col>
|
||||||
<item-form :item="item" :items="items" :enable-name="createMode" />
|
<item-form :item="item" :items="items" :createMode="createMode" />
|
||||||
</f7-col>
|
</f7-col>
|
||||||
<f7-col>
|
<f7-col>
|
||||||
<f7-block-title>Group Membership</f7-block-title>
|
<f7-block-title>Group Membership</f7-block-title>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<f7-page @page:beforein="load" @page:afterout="stopEventSource">
|
<f7-page @page:afterin="onPageAfterIn" @page:beforeout="onPageBeforeOut">
|
||||||
<f7-navbar title="Items" back-link="Settings" back-link-url="/settings/" back-link-force>
|
<f7-navbar title="Items" back-link="Settings" back-link-url="/settings/" back-link-force>
|
||||||
<f7-nav-right>
|
<f7-nav-right>
|
||||||
<f7-link icon-md="material:done_all" @click="toggleCheck()"
|
<f7-link icon-md="material:done_all" @click="toggleCheck()"
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
</f7-col>
|
</f7-col>
|
||||||
<f7-col v-show="ready">
|
<f7-col v-show="ready">
|
||||||
<f7-block-title class="searchbar-hide-on-search">
|
<f7-block-title class="searchbar-hide-on-search">
|
||||||
{{ items.length }} items
|
{{ items.length }} Items
|
||||||
</f7-block-title>
|
</f7-block-title>
|
||||||
<f7-list
|
<f7-list
|
||||||
v-show="items.length > 0"
|
v-show="items.length > 0"
|
||||||
|
@ -78,7 +78,8 @@
|
||||||
:subtitle="getItemTypeAndMetaLabel(item)"
|
:subtitle="getItemTypeAndMetaLabel(item)"
|
||||||
:style="`top: ${vlData.topPosition}px`"
|
:style="`top: ${vlData.topPosition}px`"
|
||||||
:after="(item.state) ? item.state : '\xa0'">
|
:after="(item.state) ? item.state : '\xa0'">
|
||||||
<oh-icon v-if="item.category" slot="media" :icon="item.category" height="32" width="32" />
|
<!-- Note: Using dynamic states is not possible since state tracking has a heavy performance impact -->
|
||||||
|
<oh-icon v-if="item.category" slot="media" :icon="item.category" :state="(item.state) ? item.state : null" height="32" width="32" />
|
||||||
<span v-else slot="media" class="item-initial">{{ item.name[0] }}</span>
|
<span v-else slot="media" class="item-initial">{{ item.name[0] }}</span>
|
||||||
<f7-icon v-if="!item.editable" slot="after-title" f7="lock_fill" size="1rem" color="gray" />
|
<f7-icon v-if="!item.editable" slot="after-title" f7="lock_fill" size="1rem" color="gray" />
|
||||||
<!-- <f7-button slot="after-start" color="blue" icon-f7="compose" icon-size="24px" :link="`${item.name}/edit`"></f7-button> -->
|
<!-- <f7-button slot="after-start" color="blue" icon-f7="compose" icon-size="24px" :link="`${item.name}/edit`"></f7-button> -->
|
||||||
|
@ -90,6 +91,9 @@
|
||||||
<f7-block v-if="ready && !items.length" class="service-config block-narrow">
|
<f7-block v-if="ready && !items.length" class="service-config block-narrow">
|
||||||
<empty-state-placeholder icon="square_on_circle" title="items.title" text="items.text" />
|
<empty-state-placeholder icon="square_on_circle" title="items.title" text="items.text" />
|
||||||
</f7-block>
|
</f7-block>
|
||||||
|
<f7-fab v-show="!showCheckboxes" position="center-bottom" text="Refresh" slot="fixed" color="blue" @click="load()">
|
||||||
|
<f7-icon ios="f7:arrow_clockwise" md="material:refresh" aurora="f7:arrow_clockwise" />
|
||||||
|
</f7-fab>
|
||||||
<f7-fab v-show="!showCheckboxes" position="right-bottom" slot="fixed" color="blue">
|
<f7-fab v-show="!showCheckboxes" position="right-bottom" slot="fixed" color="blue">
|
||||||
<f7-icon ios="f7:plus" md="material:add" aurora="f7:plus" />
|
<f7-icon ios="f7:plus" md="material:add" aurora="f7:plus" />
|
||||||
<f7-icon ios="f7:multiply" md="material:close" aurora="f7:multiply" />
|
<f7-icon ios="f7:multiply" md="material:close" aurora="f7:multiply" />
|
||||||
|
@ -139,6 +143,12 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
onPageAfterIn (event) {
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
|
onPageBeforeOut (event) {
|
||||||
|
this.stopEventSource()
|
||||||
|
},
|
||||||
load () {
|
load () {
|
||||||
this.ready = false
|
this.ready = false
|
||||||
this.$oh.api.get('/rest/items?metadata=semantics').then(data => {
|
this.$oh.api.get('/rest/items?metadata=semantics').then(data => {
|
||||||
|
@ -270,11 +280,6 @@ export default {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
asyncComputed: {
|
|
||||||
iconUrl () {
|
|
||||||
return icon => this.$oh.media.getIcon(icon)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
searchPlaceholder () {
|
searchPlaceholder () {
|
||||||
return window.innerWidth >= 1280 ? 'Search (for advanced search, use the developer sidebar (Shift+Alt+D))' : 'Search'
|
return window.innerWidth >= 1280 ? 'Search (for advanced search, use the developer sidebar (Shift+Alt+D))' : 'Search'
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
<div>Loading...</div>
|
<div>Loading...</div>
|
||||||
</f7-block>
|
</f7-block>
|
||||||
<div v-else-if="selectedThing.UID && selectedThingType.UID">
|
<div v-else-if="selectedThing.UID && selectedThingType.UID">
|
||||||
<item-form v-if="createEquipment" :item="newEquipmentItem" :items="items" :enable-name="true" :hide-type="true" :force-semantics="true" />
|
<item-form v-if="createEquipment" :item="newEquipmentItem" :items="items" :createMode="true" :hide-type="true" :force-semantics="true" />
|
||||||
<f7-block-title>Channels</f7-block-title>
|
<f7-block-title>Channels</f7-block-title>
|
||||||
<f7-block-footer class="padding-left padding-right">
|
<f7-block-footer class="padding-left padding-right">
|
||||||
Check the channels you wish to create as new Point items.
|
Check the channels you wish to create as new Point items.
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
<!-- Create new item -->
|
<!-- Create new item -->
|
||||||
<f7-col v-else>
|
<f7-col v-else>
|
||||||
<item-form :item="newItem" :items="items" :enable-name="true" @valid="itemValid = $event" />
|
<item-form :item="newItem" :items="items" :createMode="true" @valid="itemValid = $event" />
|
||||||
<f7-list>
|
<f7-list>
|
||||||
<item-picker key="newItem-groups" title="Parent Group(s)" name="parent-groups" :value="newItem.groupNames" :items="items" @input="(value) => newItem.groupNames = value" :multiple="true" filterType="Group" />
|
<item-picker key="newItem-groups" title="Parent Group(s)" name="parent-groups" :value="newItem.groupNames" :items="items" @input="(value) => newItem.groupNames = value" :multiple="true" filterType="Group" />
|
||||||
</f7-list>
|
</f7-list>
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<span slot="media" class="item-initial">{{ (channel.label) ? channel.label[0] : (channelType.label) ? channelType.label[0] : '?' }}</span>
|
<span slot="media" class="item-initial">{{ (channel.label) ? channel.label[0] : (channelType.label) ? channelType.label[0] : '?' }}</span>
|
||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
<f7-list-item divider title="Item" />
|
<f7-list-item divider title="Item" />
|
||||||
<item :item="item" :context="context" :no-state="true" :link="'/settings/items/' + item.name" />
|
<item :item="item" :context="context" :link="'/settings/items/' + item.name" />
|
||||||
</ul>
|
</ul>
|
||||||
</f7-list>
|
</f7-list>
|
||||||
</f7-card-content>
|
</f7-card-content>
|
||||||
|
|
Loading…
Reference in New Issue