@openhab-ui/setup-and-maintenance
Version:
Configuration and maintenance interface for openHAB
33 lines • 20.5 kB
HTML
<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1,user-scalable=yes"><link rel="icon" href="img/favicon.ico"><link rel="manifest" href="/manifest.json"><link rel="preload" href="fonts/fa-regular-400.woff2" as="font" type="font/woff2" crossorigin="anonymous"><link rel="preload" href="fonts/fa-solid-900.woff2" as="font" type="font/woff2" crossorigin="anonymous"><link rel="preload" href="fonts/roboto-v18-latin-ext_greek_cyrillic_cyrillic-ext_greek-ext_latin_vietnamese-regular.woff2" as="font" type="font/woff2" crossorigin="anonymous"><link rel="preload" href="fonts/roboto-v18-latin-ext_greek_cyrillic_cyrillic-ext_greek-ext_latin_vietnamese-500.woff2" as="font" type="font/woff2" crossorigin="anonymous"><link rel="preload" href="fonts/roboto-v18-latin-ext_greek_cyrillic_cyrillic-ext_greek-ext_latin_vietnamese-700.woff2" as="font" type="font/woff2" crossorigin="anonymous"><link rel="preload" href="img/pattern_opacity.png" as="image"><link rel="preload" href="img/openhab-logo.svg" as="image"><link rel="stylesheet" href="css/main.css" type="text/css"><link rel="stylesheet" href="css/main_deferred.css" type="text/css"><script type="module" src="js/app.js" async></script><script type="module" src="js/vue.js" async></script><script type="module" src="js/ohcomponents.js" async></script><script type="module" src="js/uicomponents.js" async></script><script type="module">async function applyTheme() {
if (localStorage.getItem("darktheme") === "true") {
let darkthemecss = document.getElementById("darkthemecss");
if (!darkthemecss) {
let head = document.getElementsByTagName('head')[0];
let link = document.createElement('style');
link.id = "darkthemecss";
link.innerHTML = await fetch('css/dark.css').then(d => d.text());
head.appendChild(link);
document.dispatchEvent(new Event("themechanged"));
}
} else {
let darkthemecss = document.getElementById("darkthemecss");
if (darkthemecss) darkthemecss.remove();
}
if (localStorage.getItem("widetheme") === "true") {
document.querySelector("body").classList.add("wide");
} else {
document.querySelector("body").classList.remove("wide");
}
window.requestAnimationFrame(() => {
window.dispatchEvent(new Event("resize"));
});
}
window.toggleWideTheme = function (event) {
event.preventDefault();
let isEnabled = localStorage.getItem("widetheme") === "true";
localStorage.setItem("widetheme", !isEnabled);
applyTheme();
}
applyTheme();
window.addEventListener('storage', e => { if (e.key == "darktheme") applyTheme(); });
document.addEventListener('themechange', e => applyTheme());</script><title>openHAB - Empowering the smart home</title></head><body><link rel="stylesheet" href="css/listgridview.css" type="text/css"><link rel="stylesheet" href="css/items.css" type="text/css"><nav class="sidebar leftright"><h4>Actions</h4><ul><li><a href="#new-item"><i class="fas fa-plus"></i> New Item</a></li></ul><p>Sort list</p><ul><li><oh-change-filter target="oh-list-bind" sort="label" direction="↓↑"><i class="fas fa-sort-alpha-down"></i> By name</oh-change-filter></li><li><oh-change-filter target="oh-list-bind" sort="category" direction="↓↑"><i class="fas fa-sort-amount-down"></i> By category</oh-change-filter></li><li><oh-change-filter target="oh-list-bind" sort="type" direction="↓↑"><i class="fas fa-sort-amount-down"></i> By type</oh-change-filter></li><li><oh-change-filter target="oh-list-bind" sort="state" direction="↓↑"><i class="fas fa-sort-amount-down"></i> By state</oh-change-filter></li></ul><p>Predefined filters</p><ul><li><oh-change-filter target="ui-filter" filter="type:Switch">Show switches</oh-change-filter></li><li><oh-change-filter target="ui-filter" filter="type:Dimmer">Show dimmers</oh-change-filter></li><li><oh-change-filter target="ui-filter" filter="type:Number">Show numbers</oh-change-filter></li><li><oh-change-filter target="ui-filter" filter="type:String">Show texts</oh-change-filter></li><li><oh-change-filter target="ui-filter" filter="type:Rollershutter">Show rollershutters</oh-change-filter></li></ul></nav><header class="navbarui"><a class="sidebar-button" href="#" onclick="toggleSidebar(event)"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon" style="max-width: 20px;"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg> </a><a class="home" id="home" href="index.html"><div alt="openHAB" class="logo"></div></a><nav><oh-nav-auto-link></oh-nav-auto-link><div><a id="navmaintenance" href="maintenance.html">Maintenance</a></div><div><a id="navbindings" href="bindings.html">Add-ons</a></div><div><a id="navinbox" href="inbox.html" style="display: inline-flex;align-items: center;">Inbox<oh-form-bind adapter="modeladapter_forms/inboxcounter" objectid=""></oh-form-bind><oh-vue-form></oh-vue-form><template><span class="ml-2 badge badge-pill badge-orange">{{inboxcounter}}</span></template></a></div><div><a id="navthings" href="things.html">Things</a></div><div><a id="navitems" href="items.html">Items</a></div><div><a id="navscheduler" href="schedules.html">Scheduler</a></div><div><a id="navscenes" href="scenes.html">Scenes</a></div><div><a id="navrules" href="rules.html">Automation</a></div></nav></header><nav-ajax-page-load></nav-ajax-page-load><div id="alert-area" class="alert-area"></div><template id="alert-template"><div class="alert-box"><div class="alert-content"><slot></slot></div><a class="alert-close no-loader" data-close href="#"></a></div></template><section class="header"><div><oh-prop-bind attribute="label" queryparameter="title"></oh-prop-bind><nav-breadcrumb label="Add & remove Items. Change tags, titles and Group affiliations"></nav-breadcrumb></div><span class="link roundbtn" onclick="toggleWideTheme(event)"><i class="fas fa-arrows-alt-h"></i></span><oh-doc-link toggle class="link helpbtn roundbtn" title="Open/Close context help"><i class="fas fa-times"></i><i class="fas fa-question"></i></oh-doc-link></section><main><div id="new-item" class="modal" role="dialog"><div class="modal-dialog" role="document"><oh-vue-bind adapter="modeladapter_mixins/newitem"></oh-vue-bind><oh-vue></oh-vue><template><form class="modal-content was-validated" @submit="create"><vue-inprogress></vue-inprogress><div class="modal-header"><h5 class="modal-title">New item</h5><a href="#" class="close" aria-label="Close"><span aria-hidden="true">×</span></a></div><div class="modal-body"><div class="form-group row"><label class="col-sm-2 col-form-label"><abbr title="Reference this Item via this identifier">UID</abbr></label><div class="col-sm-10"><input class="form-control" v-model="name" name="name" pattern=".{2,}" required placeholder="Item UID"></div></div><div class="form-group row"><label class="col-sm-2 col-form-label">Label</label><div class="col-sm-10"><input class="form-control" v-model="label" name="label" pattern=".{2,}" required placeholder="Label"></div></div><div class="form-group row"><label class="col-sm-2 col-form-label">Type</label><div class="col-sm-10"><oh-dropdown-bind adapter="modeladapter_lists/item-types"></oh-dropdown-bind><ui-dropdown name="type" class="w-100" btnclass="btn btn-sm" icons="itemtypes" viewkey="label" valuekey="id" desckey="description" :value="type" @input="this.type=$event.target.value"></ui-dropdown></div></div></div><div class="modal-footer"><button type="submit" :class="{disabled:notready}" class="btn btn-primary">Create</button> <a class="btn btn-secondary" href="#">Close</a></div></form></template></div></div><div id="change-icon" class="modal" role="dialog"><div class="modal-dialog" role="document"><oh-form-bind id="change-icon-source" adapter="modeladapter_forms/icons" objectid=""></oh-form-bind><oh-vue-form></oh-vue-form><template><div class="modal-content"><div class="modal-header"><h5 class="modal-title">Select icon ({{context.label}})</h5><a href="#" class="close" aria-label="Close"><span aria-hidden="true">×</span></a></div><div class="modal-body"><div style="display:flex;flex-wrap: wrap;max-height: 500px;overflow-y: auto"><button v-for="cat of value" :class="{active:category==cat}" class="btn btn-outline-primary" @click="category=cat"><img style="width: 64px;height: 64px;" :src="iconpath(cat)"></button></div></div><div class="modal-footer"><input style="flex:1" class="ml-2" placeholder="no icon" @input="category=$event.target.value" :value="category"> <a href="#" class="btn btn-primary" @click="applyIcon">Select</a> <a href="#" class="btn btn-secondary" @click="notifyClose">Close</a></div></div></template></div></div><ui-filter class="mt-4" placeholder="Filter..." grid="Grid view" list="List view" textual="Textual representation" select="Selection mode" additionalbuttons="Control,Type,Groups,Meta,Semantic"><button class="btn btn-danger" data-action="remove"><i class="fas fa-trash"></i> Remove<oh-event-bind eventname="selectionchanged" setcontent></oh-event-bind><span class="badge badge-light ml-2">0</span></button></ui-filter><oh-list-bind adapter="modeladapter_lists/items-full" maxitems="100" filtercriteria="label"></oh-list-bind><oh-vue-list><div slot="app"><list></list></div><template slot="list"><h4 class="pt-5" style="flex-direction: column;align-items: center;" v-if="status == OhListStatus.PENDING_WAITING" slot="app">Loading<div class="loader"></div></h4><div class="pt-5" style="flex-direction: column;align-items: center;" v-else-if="status == OhListStatus.NOTCONNECTED_WAITING" slot="app"><h4><i class="fas fa-exclamation-circle"></i> Not connected</h4><div class="bs-callout bs-callout-info mt-4" style="display:inline-block;max-width: 500px">You are not connected to an openHAB instance. <a href="login.html">Connect now</a></div></div><div class="pt-5" style="flex-direction: column;align-items: center;" v-else-if="status == OhListStatus.ERROR" slot="app"><h4><i class="fas fa-exclamation-circle"></i> Loading failed</h4><div>{{message}}</div><div class="bs-callout bs-callout-info mt-4" style="display:inline-block;max-width: 700px"><p>An error while loading a list can happen because of multiple reasons.</p><dl><dt>A programming error</dt><dd>We are really sorry for that. Please report it in our bug-tracker, thank you.</dd><dt>Your openHAB doesn't understand</dt><dd>Please make sure this version is compatible to your openHAB version and you have installed all minimum-required Add-ons for this interface to work.</dd><dt>Your openHAB / internet is slow</dt><dd>We can't really do much here. A request times out after 5 seconds. Please find out why your openHAB is soo slow. Reload the page to try again.</dd></dl></div></div><ui-codeeditor v-else-if="viewmode=='textual'" :modelschema.prop="modelschema" ref="editor" :content.prop="toTextual()" @state="editorContentChanged($event.target)"></ui-codeeditor><div v-else class="w-100"><slot name="beforelist" :list="$list"></slot><div v-if="status==OhListStatus.READY && items.length==0" class="emptylist"><slot name="empty"><p>No content found. You might find the help text interesting.</p><ui-context-help url="contexthelp/items.md" class="card"></ui-context-help></slot></div><transition-group name="fade" tag="div" id="listcontainer" :class="[{selectionmode:selectmode},viewmode]"><template v-if="Array.isArray(items)"><oh-vue-listitem v-for="item in items" :key="item.name" :class="{single:items.length==1}" :listitem="item"></oh-vue-listitem></template><template v-else v-for="(channelGroup,groupid) in items"><h2 v-if="channelGroup.label" style="grid-column: 1 / -1" :key="groupid">{{channelGroup.label}} <small>{{channelGroup.description}}</small></h2><oh-vue-listitem v-for="item in channelGroup" :key="item.name" :class="{single:channelGroup.length==1}" :listitem="item"></oh-vue-listitem></template></transition-group><div v-if="items.hasmore" class="text-center"><button class="btn btn-primary-hover" @click="showMore()">Show 50 more …</button></div><slot name="afterlist" :list="$list"></slot></div></template><template slot="item"><article :id="item.name" :class="[{haschanges: changed},{pulseAnimation: pulseAnimation}]"><vue-inprogress></vue-inprogress><header><span :title="item.label+': Edit the name and press enter'" contenteditable="true" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" @blur="setLabel" @keypress.enter.prevent="item.label=$event.target.innerText">{{item.label}}</span></header><section class="actions unsaved btn-group"><button class="btn btn-success" title="Save changes" @click="save()"><i class="fas fa-save"></i></button> <button class="btn btn-danger" title="Discard changes" @click="discard()"><i class="fas fa-undo"></i></button></section><section class="actions btn-group"><oh-doc-link v-if="$list.secondarymode==2" title="About item groups" show href="contexthelp/itemgroupfunctions.md" class="btn btn-info-hover"><i class="fas fa-question-circle"></i></oh-doc-link><oh-doc-link v-if="$list.secondarymode==3" title="About item meta data" show href="contexthelp/itemmeta.md" class="btn btn-info-hover"><i class="fas fa-question-circle"></i></oh-doc-link><oh-doc-link v-if="$list.secondarymode==4" title="About semantic tagging" show href="contexthelp/semantictagging.md" class="btn btn-info-hover"><i class="fas fa-question-circle"></i></oh-doc-link><oh-doc-link show class="btn btn-info-hover" title="Tags and Storage association" href="items_info.fragment.html" :context.prop='{id:item.name,adapter:"modeladapter_forms/item"}'><i class="fas fa-info"></i></oh-doc-link><button class="btn btn-danger-hover" title="Remove item" @click="remove()"><i class="fas fa-trash"></i></button></section><section class="description"><ui-tabs upsidedown :activetab.prop="$list.secondarymode"><div class="tab-content" slot="tabs"><section class="itemcontrol"><a class="icon" href="#change-icon" @click="showIconDialog"><img alt="Edit icon" title="Edit icon" :src="iconpath"></a><div v-if="item.type=='Group' && !item.groupType">Normally you would see a control option here. This is a Group item though.</div><div class="cmdwrapper" v-else><div v-if="item.type=='Group'" class="mb-2 text-truncate">State: N/A</div><div v-else class="mb-2 text-truncate">State: {{item.state}}</div><div v-if="itemcommands" class="input-group mb-3"><ui-dropdown btnclass="form-control" style="flex:1" :options="itemcommands" label="Command" class="commandInput"></ui-dropdown><div class="input-group-append"><button class="btn btn-outline-secondary btn-outline-visible" type="button" @click.prevent="sendCommand"><i class="fas fa-upload"></i></button></div></div><div v-else class="input-group mb-3"><input type="text" class="form-control commandInput" placeholder="Command to send" aria-label="Command to send"><div class="input-group-append"><button class="btn btn-outline-secondary btn-outline-visible" type="button" @click.prevent="sendCommand"><i class="fas fa-upload"></i></button></div></div></div></section><section><div>This is a<ui-dropdown btnclass="btn btn-sm link" icons="itemtypes" viewkey="label" valuekey="id" desckey="description" :value="item.type" :options.prop="$list.itemtypes" label="No type" @input="item.type = $event.target.value"></ui-dropdown><template v-if="isGroup">of type<ui-dropdown btnclass="btn btn-sm link" icons="itemtypes" viewkey="label" valuekey="id" desckey="description" :options.prop="$list.grouptypes" :value="item.groupType" label="Unknown" @input="setGroup($event.target.value)"></ui-dropdown>,<div v-if="item.groupType && item.groupType.length">with 𝒇<ui-dropdown btnclass="btn btn-sm link" viewkey="label" valuekey="id" desckey="description" :options.prop="groupfunctions" :value="item.function ? item.function.name : null" label="No function" @input="$set(item,'function',{name:$event.target.value,params:[]})"></ui-dropdown><oh-doc-link title="About group functions" show href="contexthelp/itemgroupfunctions.md" class="link ml-2 mr-2"><i class="fas fa-question-circle"></i></oh-doc-link><span v-if="hasFunctionParameters">with parameters <label v-for="(param, index) of functionparameters" :key="param.label" :title="param.description">{{param.label}}<ui-dropdown v-if="param.type=='allowedState'" btnclass="btn btn-sm link" :options="param.allowedStates" :value="param.value" label="Select" @input="setFunctionParameter(index, $event.target.value)"></ui-dropdown><input v-else style="max-width: 60px" :value="param.value" :placeholder="param.description"></label></span></div></template></div></section><section><ui-multiselect viewkey="label" desckey="name" valuekey="name" :options.prop="$list.groupItems" placeholder="Add this item to other Groups" :value.prop="item.groupNames" @input="$set(item,'groupNames', $event.target.value)"></ui-multiselect></section><section class="itemmeta"><div class="add"><label>Add value:</label> <input placeholder="namespace" ref="namespacename"> <input placeholder="value" ref="namespacevalue"> <button title="Add metadata value" class="btn btn-outline-success btn-sm" @click.prevent="addMeta"><i class="fas fa-plus"></i></button></div><div v-for="namespace of namespaces"><template v-if="!namespace.hasconfig"><h6>Namespace: {{namespace.name}}</h6><div v-for="value of namespace.values">{{value.description}}: {{value.value}} <button title="Remove value" class="btn btn-outline-danger btn-sm resetdefault" @click.prevent="removeMeta(namespace.name,value.id)"><i class="fas fa-trash"></i></button></div></template><div class="elements" v-else><template v-for="param of namespace.parameters"><vue-config-element :param="param" :value="namespace.values[param.name]" @input="setMeta(namespace.name,param.type,param.name,$event)"></vue-config-element><label :title="param.description">{{param.description}}</label> <button v-if="namespace.values[param.name]" title="Reset to default" class="btn btn-outline-danger btn-sm resetdefault" @click.prevent="removeMeta(namespace.name,param.name)"><i class="fas fa-undo"></i></button></template></div></div></section><section class="itemsemantic"><div class="content" v-if="$list.semantic"><div>Location</div><div style="padding-left: 0.5em">Property</div><div style="padding-left: 0.5em">Point</div><div style="padding-left: 0.5em">Equipment</div><ui-multiselect viewkey="tag" desckey="description" valuekey="tag" :options.prop="Array.from($list.semantic.Location.values())" placeholder="Select…" data-type="Location" :value.prop="getSemanticLocation" @input="setSemanticTag"></ui-multiselect><ui-multiselect viewkey="tag" desckey="description" valuekey="tag" :options.prop="Array.from($list.semantic.Property.values())" placeholder="Select…" data-type="Property" :value.prop="getSemanticProperty" @input="setSemanticTag"></ui-multiselect><ui-multiselect viewkey="tag" desckey="description" valuekey="tag" :options.prop="Array.from($list.semantic.Point.values())" placeholder="Select…" data-type="Point" :value.prop="getSemanticPoint" @input="setSemanticTag"></ui-multiselect><ui-multiselect viewkey="tag" desckey="description" valuekey="tag" :options.prop="Array.from($list.semantic.Equipment.values())" placeholder="Select…" data-type="Equipment" :value.prop="getSemanticEquipment" @input="setSemanticTag"></ui-multiselect></div><div v-else>Seem to not be available on your openHAB version :/</div></section></div></ui-tabs></section></article></template></oh-vue-list></main><footer></footer><aside class="contexthelp"><div class="fixedwrapper"><ui-context-help url="contexthelp/items.md"></ui-context-help><div class="btnbar mt-4 mr-2"><oh-doc-link class="btn btn-danger helpbtn2 mr-2" toggle><i class="fas fa-times"></i> Close</oh-doc-link></div></div></aside></body></html>