Polymer 3 modulize (#1154)
* Version bump to 20180510.1 * Fix hass util * Fix translations * Bye paper-time-input * Add webpack config * Add webpack to package.json * Fix translation import * Disable web animations polyfill bad import * Disable importHref import * Update webpack config to build authorize.js * Build translations json * Build frontend correctly * Run eslint --fix * Load markdown JS on demand (#1155) * Add HTML imports (#1160) * Fix localize (#1161) * Fix Roboto in build (#1162) * Load web animations polyfill (#1163) * P3: Fix chart js (#1164) * P3: Fix Chart JS * Update timeline package * P3: panel resolver (#1165) * WIP * Initial importing of panels * Fix panel resolver * Fix automation and script editor (#1166) * Expose Polymer and Polymer.Element on window (#1167) * Remove unused import * eslint --fix * Es5 build (#1168) * Build for ES5 * Fix build_frontend * Remove stale comment * Migrate to use paper-material-styles (#1170) * Send parsed date to history/logbook (#1171) * Fork app storage behavior (#1172) * Add paper input with type time (#1173) * Fix authorize * Lint * Sort imports * Lint * Remove eslint-html * Do not lint authorize.html * Fix polymer lint * Try chrome 62 for wct * P3: Add patched iconset (#1175) * Add patched iconset * Lint * Test with latest Chrome again * Use less window.hassUtil * Teporarily use my fecha fork * Import correct intl.messageFormat * Update wct-browser-legacy to 1.0.0 * Include polyfill in right place * Fix IntlMessageFormat * Fix test not having a global scope * Rollup <_< * Fork app-localize-behavior * Disable wct tests * Lint
This commit is contained in:
parent
205d6a8347
commit
a4afc2e37a
@ -1,12 +1,12 @@
|
||||
{
|
||||
"extends": "./.eslintrc-hound.json",
|
||||
"plugins": [
|
||||
"html",
|
||||
"react"
|
||||
],
|
||||
"env": {
|
||||
"browser": true
|
||||
},
|
||||
"parser": "babel-eslint",
|
||||
"rules": {
|
||||
"import/no-unresolved": 2,
|
||||
"linebreak-style": 0
|
||||
|
||||
15
.travis.yml
15
.travis.yml
@ -3,24 +3,23 @@ language: node_js
|
||||
cache:
|
||||
yarn: true
|
||||
directories:
|
||||
- bower_components
|
||||
install:
|
||||
- yarn install
|
||||
- ./node_modules/.bin/bower install
|
||||
- bower_components
|
||||
install: yarn install
|
||||
script:
|
||||
- npm run build
|
||||
- npm run test
|
||||
- xvfb-run wct
|
||||
- if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then wct --plugin sauce; fi
|
||||
# - xvfb-run wct --module-resolution=node --npm
|
||||
# - 'if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then wct --module-resolution=node --npm --plugin sauce; fi'
|
||||
services:
|
||||
- docker
|
||||
before_deploy:
|
||||
- docker pull lokalise/lokalise-cli@sha256:2198814ebddfda56ee041a4b427521757dd57f75415ea9693696a64c550cef21
|
||||
- 'docker pull lokalise/lokalise-cli@sha256:2198814ebddfda56ee041a4b427521757dd57f75415ea9693696a64c550cef21'
|
||||
deploy:
|
||||
provider: script
|
||||
script: script/travis_deploy
|
||||
on:
|
||||
'on':
|
||||
branch: master
|
||||
dist: trusty
|
||||
addons:
|
||||
sauce_connect: true
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
const gulp = require('gulp');
|
||||
const path = require('path');
|
||||
const replace = require('gulp-batch-replace');
|
||||
const rename = require('gulp-rename');
|
||||
|
||||
@ -11,8 +12,12 @@ const {
|
||||
const es5Extra = "<script src='/frontend_es5/custom-elements-es5-adapter.js'></script>";
|
||||
|
||||
async function buildAuth(es6) {
|
||||
let stream = await bundledStreamFromHTML('src/authorize.html');
|
||||
stream = stream.pipe(replace([['<!--EXTRA_SCRIPTS-->', es6 ? '' : es5Extra]]));
|
||||
const frontendPath = es6 ? 'hass_frontend_latest' : 'hass_frontend_es5';
|
||||
const stream = gulp.src(path.resolve(config.polymer_dir, 'src/authorize.html'))
|
||||
.pipe(replace([
|
||||
['<!--EXTRA_SCRIPTS-->', es6 ? '' : es5Extra],
|
||||
['/home-assistant-polymer/build/webpack/ha-authorize.js', `/${frontendPath}/authorize.js`],
|
||||
]));
|
||||
|
||||
return minifyStream(stream, /* es6= */ es6)
|
||||
.pipe(rename('authorize.html'))
|
||||
|
||||
@ -31,6 +31,7 @@ function renamePanel(path) {
|
||||
}
|
||||
|
||||
function build(es6) {
|
||||
return;
|
||||
const strategy = composeStrategies([
|
||||
generateShellMergeStrategy(polymerConfig.shell),
|
||||
stripImportsStrategy([
|
||||
|
||||
@ -8,8 +8,7 @@ const { minifyStream } = require('../common/transform');
|
||||
|
||||
const buildReplaces = {
|
||||
'/home-assistant-polymer/build/core.js': 'core.js',
|
||||
'/home-assistant-polymer/src/home-assistant.html': 'frontend.html',
|
||||
'/home-assistant-polymer/src/resources/ha-chart-scripts.html': 'ha-chart-scripts.html',
|
||||
'/home-assistant-polymer/build/webpack/app.js': 'app.js',
|
||||
};
|
||||
|
||||
function generateIndex(es6) {
|
||||
|
||||
@ -29,22 +29,13 @@ const staticFingerprinted = [
|
||||
|
||||
const staticFingerprintedEs6 = [
|
||||
'core.js',
|
||||
'frontend.html',
|
||||
'ha-chart-scripts.html',
|
||||
'app.js',
|
||||
];
|
||||
|
||||
const staticFingerprintedEs5 = [
|
||||
'compatibility.js',
|
||||
'core.js',
|
||||
'frontend.html',
|
||||
'ha-chart-scripts.html',
|
||||
];
|
||||
|
||||
// These panels will always be registered inside HA and thus can
|
||||
// be safely assumed to be able to preload.
|
||||
const panelsFingerprinted = [
|
||||
'dev-event', 'dev-info', 'dev-service', 'dev-state', 'dev-template',
|
||||
'dev-mqtt', 'kiosk',
|
||||
'app.js',
|
||||
];
|
||||
|
||||
function processStatic(fn, rootDir, urlDir) {
|
||||
|
||||
@ -248,8 +248,7 @@ gulp.task(taskName, ['build-translation-fingerprints'], function () {
|
||||
fragments: TRANSLATION_FRAGMENTS,
|
||||
translations: data,
|
||||
})))
|
||||
.pipe(insert.wrap('<script>\nwindow.translationMetadata = ', ';\n</script>'))
|
||||
.pipe(rename('translationMetadata.html'))
|
||||
.pipe(rename('translationMetadata.json'))
|
||||
.pipe(gulp.dest(workDir));
|
||||
});
|
||||
tasks.push(taskName);
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
import '../../src/components/hassio-card-content.js';
|
||||
import '../../src/resources/hassio-style.js';
|
||||
import '../../src/util/hass-mixins.js';
|
||||
|
||||
<link rel='import' href='../../src/components/hassio-card-content.html'>
|
||||
<link rel='import' href='../../src/resources/hassio-style.html'>
|
||||
|
||||
<dom-module id="hassio-addon-repository">
|
||||
<template>
|
||||
class HassioAddonRepository extends window.hassMixins.NavigateMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style hassio-style">
|
||||
paper-card {
|
||||
cursor: pointer;
|
||||
@ -17,35 +18,27 @@
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
</style>
|
||||
<template is='dom-if' if='[[addons.length]]'>
|
||||
<div class='card-group'>
|
||||
<div class='title'>
|
||||
<template is="dom-if" if="[[addons.length]]">
|
||||
<div class="card-group">
|
||||
<div class="title">
|
||||
[[repo.name]]
|
||||
<div class='description'>
|
||||
<div class="description">
|
||||
Maintained by [[repo.maintainer]]
|
||||
<a class='repo' href='[[repo.url]]' target='_blank'>[[repo.url]]</a>
|
||||
<a class="repo" href="[[repo.url]]" target="_blank">[[repo.url]]</a>
|
||||
</div>
|
||||
</div>
|
||||
<template is='dom-repeat' items='[[addons]]' as='addon' sort='sortAddons'>
|
||||
<paper-card on-click='addonTapped'>
|
||||
<div class='card-content'>
|
||||
<hassio-card-content
|
||||
title='[[addon.name]]'
|
||||
description='[[addon.description]]'
|
||||
icon='[[computeIcon(addon)]]'
|
||||
icon-title='[[computeIconTitle(addon)]]'
|
||||
icon-class='[[computeIconClass(addon)]]'
|
||||
></hassio-card-content>
|
||||
<template is="dom-repeat" items="[[addons]]" as="addon" sort="sortAddons">
|
||||
<paper-card on-click="addonTapped">
|
||||
<div class="card-content">
|
||||
<hassio-card-content title="[[addon.name]]" description="[[addon.description]]" icon="[[computeIcon(addon)]]" icon-title="[[computeIconTitle(addon)]]" icon-class="[[computeIconClass(addon)]]"></hassio-card-content>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HassioAddonRepository extends window.hassMixins.NavigateMixin(Polymer.Element) {
|
||||
static get is() { return 'hassio-addon-repository'; }
|
||||
|
||||
static get properties() {
|
||||
@ -79,4 +72,3 @@ class HassioAddonRepository extends window.hassMixins.NavigateMixin(Polymer.Elem
|
||||
}
|
||||
|
||||
customElements.define(HassioAddonRepository.is, HassioAddonRepository);
|
||||
</script>
|
||||
@ -1,33 +1,26 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
import '../../src/util/hass-mixins.js';
|
||||
import './hassio-addon-repository.js';
|
||||
import './hassio-repositories-editor.js';
|
||||
|
||||
<link rel="import" href="./hassio-repositories-editor.html">
|
||||
<link rel="import" href="./hassio-addon-repository.html">
|
||||
|
||||
<dom-module id="hassio-addon-store">
|
||||
<template>
|
||||
class HassioAddonStore extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
hassio-addon-repository {
|
||||
margin-top: 24px;
|
||||
}
|
||||
</style>
|
||||
<hassio-repositories-editor
|
||||
hass='[[hass]]'
|
||||
repos='[[repos]]'
|
||||
></hassio-repositories-editor>
|
||||
<hassio-repositories-editor hass="[[hass]]" repos="[[repos]]"></hassio-repositories-editor>
|
||||
|
||||
<template is='dom-repeat' items='[[repos]]' as='repo' sort='sortRepos'>
|
||||
<hassio-addon-repository
|
||||
repo='[[repo]]'
|
||||
addons='[[computeAddons(repo.slug)]]'
|
||||
></hassio-addon-repository>
|
||||
<template is="dom-repeat" items="[[repos]]" as="repo" sort="sortRepos">
|
||||
<hassio-addon-repository repo="[[repo]]" addons="[[computeAddons(repo.slug)]]"></hassio-addon-repository>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HassioAddonStore extends Polymer.Element {
|
||||
static get is() { return 'hassio-addon-store'; }
|
||||
|
||||
static get properties() {
|
||||
@ -90,4 +83,3 @@ class HassioAddonStore extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HassioAddonStore.is, HassioAddonStore);
|
||||
</script>
|
||||
@ -1,108 +0,0 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
<link rel='import' href='../../bower_components/paper-input/paper-input.html'>
|
||||
<link rel='import' href='../../bower_components/iron-icon/iron-icon.html'>
|
||||
|
||||
<link rel="import" href="../../src/components/buttons/ha-call-api-button.html">
|
||||
|
||||
<link rel='import' href='../../src/components/hassio-card-content.html'>
|
||||
<link rel='import' href='../../src/resources/hassio-style.html'>
|
||||
|
||||
<dom-module id="hassio-repositories-editor">
|
||||
<template>
|
||||
<style include="ha-style hassio-style">
|
||||
.add {
|
||||
padding: 12px 16px;
|
||||
}
|
||||
iron-icon {
|
||||
color: var(--secondary-text-color);
|
||||
margin-right: 16px;
|
||||
display: inline-block;
|
||||
}
|
||||
paper-input {
|
||||
width: calc(100% - 49px);
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
<div class='card-group'>
|
||||
<div class='title'>
|
||||
Repositories
|
||||
<div class='description'>
|
||||
Configure which add-on repositories to fetch data from:
|
||||
</div>
|
||||
</div>
|
||||
<template id='list' is='dom-repeat' items='[[repoList]]' as='repo' sort='sortRepos'>
|
||||
<paper-card>
|
||||
<div class='card-content'>
|
||||
<hassio-card-content
|
||||
title='[[repo.name]]'
|
||||
description='[[repo.url]]'
|
||||
icon='mdi:github-circle'
|
||||
></hassio-card-content>
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path='hassio/supervisor/options'
|
||||
data='[[computeRemoveRepoData(repoList, repo.url)]]'
|
||||
class='warning'
|
||||
>Remove</ha-call-api-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
<paper-card>
|
||||
<div class='card-content add'>
|
||||
<iron-icon icon='mdi:github-circle'></iron-icon>
|
||||
<paper-input label='Add new repository by URL' value='{{repoUrl}}'></paper-input>
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path='hassio/supervisor/options'
|
||||
data='[[computeAddRepoData(repoList, repoUrl)]]'
|
||||
>Add</ha-call-api-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HassioRepositoriesEditor extends Polymer.Element {
|
||||
static get is() { return 'hassio-repositories-editor'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
repos: {
|
||||
type: Array,
|
||||
observer: 'reposChanged',
|
||||
},
|
||||
repoList: Array,
|
||||
repoUrl: String,
|
||||
};
|
||||
}
|
||||
|
||||
reposChanged(repos) {
|
||||
this.repoList = repos.filter(repo => repo.slug !== 'core' && repo.slug !== 'local');
|
||||
this.repoUrl = '';
|
||||
}
|
||||
|
||||
sortRepos(a, b) {
|
||||
return a.name < b.name ? -1 : 1;
|
||||
}
|
||||
|
||||
computeRemoveRepoData(repoList, url) {
|
||||
const list = repoList.filter(repo => repo.url !== url).map(repo => repo.url);
|
||||
return { addons_repositories: list };
|
||||
}
|
||||
|
||||
computeAddRepoData(repoList, url) {
|
||||
const list = repoList.map(repo => repo.url);
|
||||
list.push(url);
|
||||
return { addons_repositories: list };
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HassioRepositoriesEditor.is, HassioRepositoriesEditor);
|
||||
</script>
|
||||
93
hassio/addon-store/hassio-repositories-editor.js
Normal file
93
hassio/addon-store/hassio-repositories-editor.js
Normal file
@ -0,0 +1,93 @@
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../../src/components/buttons/ha-call-api-button.js';
|
||||
import '../../src/components/hassio-card-content.js';
|
||||
import '../../src/resources/hassio-style.js';
|
||||
|
||||
class HassioRepositoriesEditor extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style hassio-style">
|
||||
.add {
|
||||
padding: 12px 16px;
|
||||
}
|
||||
iron-icon {
|
||||
color: var(--secondary-text-color);
|
||||
margin-right: 16px;
|
||||
display: inline-block;
|
||||
}
|
||||
paper-input {
|
||||
width: calc(100% - 49px);
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
<div class="card-group">
|
||||
<div class="title">
|
||||
Repositories
|
||||
<div class="description">
|
||||
Configure which add-on repositories to fetch data from:
|
||||
</div>
|
||||
</div>
|
||||
<template id="list" is="dom-repeat" items="[[repoList]]" as="repo" sort="sortRepos">
|
||||
<paper-card>
|
||||
<div class="card-content">
|
||||
<hassio-card-content title="[[repo.name]]" description="[[repo.url]]" icon="mdi:github-circle"></hassio-card-content>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<ha-call-api-button hass="[[hass]]" path="hassio/supervisor/options" data="[[computeRemoveRepoData(repoList, repo.url)]]" class="warning">Remove</ha-call-api-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
<paper-card>
|
||||
<div class="card-content add">
|
||||
<iron-icon icon="mdi:github-circle"></iron-icon>
|
||||
<paper-input label="Add new repository by URL" value="{{repoUrl}}"></paper-input>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<ha-call-api-button hass="[[hass]]" path="hassio/supervisor/options" data="[[computeAddRepoData(repoList, repoUrl)]]">Add</ha-call-api-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'hassio-repositories-editor'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
repos: {
|
||||
type: Array,
|
||||
observer: 'reposChanged',
|
||||
},
|
||||
repoList: Array,
|
||||
repoUrl: String,
|
||||
};
|
||||
}
|
||||
|
||||
reposChanged(repos) {
|
||||
this.repoList = repos.filter(repo => repo.slug !== 'core' && repo.slug !== 'local');
|
||||
this.repoUrl = '';
|
||||
}
|
||||
|
||||
sortRepos(a, b) {
|
||||
return a.name < b.name ? -1 : 1;
|
||||
}
|
||||
|
||||
computeRemoveRepoData(repoList, url) {
|
||||
const list = repoList.filter(repo => repo.url !== url).map(repo => repo.url);
|
||||
return { addons_repositories: list };
|
||||
}
|
||||
|
||||
computeAddRepoData(repoList, url) {
|
||||
const list = repoList.map(repo => repo.url);
|
||||
list.push(url);
|
||||
return { addons_repositories: list };
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HassioRepositoriesEditor.is, HassioRepositoriesEditor);
|
||||
@ -1,16 +1,19 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
|
||||
<link rel='import' href='../../bower_components/paper-listbox/paper-listbox.html'>
|
||||
<link rel='import' href='../../bower_components/paper-item/paper-item.html'>
|
||||
<link rel='import' href='../../bower_components/neon-animation/web-animations.html'>
|
||||
import 'web-animations-js/web-animations-next-lite.min.js';
|
||||
|
||||
<link rel='import' href='../../src/resources/ha-style.html'>
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id="hassio-addon-audio">
|
||||
<template>
|
||||
import '../../src/resources/ha-style.js';
|
||||
import '../../src/util/hass-mixins.js';
|
||||
|
||||
class HassioAddonAudio extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style">
|
||||
:host,
|
||||
paper-card,
|
||||
@ -28,38 +31,34 @@
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
<paper-card heading='Audio'>
|
||||
<paper-card heading="Audio">
|
||||
<div class="card-content">
|
||||
<template is='dom-if' if='[[error]]'>
|
||||
<div class='errors'>[[error]]</div>
|
||||
<template is="dom-if" if="[[error]]">
|
||||
<div class="errors">[[error]]</div>
|
||||
</template>
|
||||
|
||||
|
||||
<paper-dropdown-menu label="Input">
|
||||
<paper-listbox slot="dropdown-content" attr-for-selected="device" selected="{{selectedInput}}">
|
||||
<template is='dom-repeat' items='[[inputDevices]]'>
|
||||
<paper-item device$="[[item.device]]">[[item.name]]</paper-item>
|
||||
<template is="dom-repeat" items="[[inputDevices]]">
|
||||
<paper-item device\$="[[item.device]]">[[item.name]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
<paper-dropdown-menu label="Output">
|
||||
<paper-listbox slot="dropdown-content" attr-for-selected="device" selected="{{selectedOutput}}">
|
||||
<template is='dom-repeat' items='[[outputDevices]]'>
|
||||
<paper-item device$="[[item.device]]">[[item.name]]</paper-item>
|
||||
<template is="dom-repeat" items="[[outputDevices]]">
|
||||
<paper-item device\$="[[item.device]]">[[item.name]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<paper-button
|
||||
on-click='_saveSettings'
|
||||
>Save</paper-button>
|
||||
<paper-button on-click="_saveSettings">Save</paper-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HassioAddonAudio extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'hassio-addon-audio'; }
|
||||
|
||||
static get properties() {
|
||||
@ -116,4 +115,3 @@ class HassioAddonAudio extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HassioAddonAudio.is, HassioAddonAudio);
|
||||
</script>
|
||||
@ -1,12 +1,14 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
import '@polymer/iron-autogrow-textarea/iron-autogrow-textarea.js';
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../src/components/buttons/ha-call-api-button.html">
|
||||
import '../../src/components/buttons/ha-call-api-button.js';
|
||||
|
||||
<dom-module id="hassio-addon-config">
|
||||
<template>
|
||||
class HassioAddonConfig extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style">
|
||||
:host {
|
||||
display: block;
|
||||
@ -30,31 +32,21 @@
|
||||
color: var(--google-red-500);
|
||||
}
|
||||
</style>
|
||||
<paper-card heading='Config'>
|
||||
<paper-card heading="Config">
|
||||
<div class="card-content">
|
||||
<template is='dom-if' if='[[error]]'>
|
||||
<div class='errors'>[[error]]</div>
|
||||
<template is="dom-if" if="[[error]]">
|
||||
<div class="errors">[[error]]</div>
|
||||
</template>
|
||||
<iron-autogrow-textarea id='config' value="{{config}}"></iron-autogrow-textarea>
|
||||
<iron-autogrow-textarea id="config" value="{{config}}"></iron-autogrow-textarea>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path="hassio/addons/[[addonSlug]]/options"
|
||||
data='[[resetData]]'
|
||||
>Reset to defaults</ha-call-api-button>
|
||||
<paper-button
|
||||
on-click='saveTapped'
|
||||
disabled='[[!configParsed]]'
|
||||
>Save</paper-button>
|
||||
<ha-call-api-button class="warning" hass="[[hass]]" path="hassio/addons/[[addonSlug]]/options" data="[[resetData]]">Reset to defaults</ha-call-api-button>
|
||||
<paper-button on-click="saveTapped" disabled="[[!configParsed]]">Save</paper-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HassioAddonConfig extends Polymer.Element {
|
||||
static get is() { return 'hassio-addon-config'; }
|
||||
|
||||
static get properties() {
|
||||
@ -106,4 +98,3 @@ class HassioAddonConfig extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HassioAddonConfig.is, HassioAddonConfig);
|
||||
</script>
|
||||
@ -1,275 +0,0 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/iron-icon/iron-icon.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
<link rel='import' href='../../bower_components/paper-card/paper-card.html'>
|
||||
<link rel='import' href='../../bower_components/paper-toggle-button/paper-toggle-button.html'>
|
||||
|
||||
<link rel="import" href="../../src/components/buttons/ha-call-api-button.html">
|
||||
<link rel='import' href='../../src/components/ha-markdown.html'>
|
||||
<link rel='import' href='../../src/resources/ha-style.html'>
|
||||
<link rel='import' href='../../src/components/hassio-card-content.html'>
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
|
||||
<dom-module id="hassio-addon-info">
|
||||
<template>
|
||||
<style include='ha-style'>
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
paper-card {
|
||||
display: block;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.addon-header {
|
||||
@apply --paper-font-headline;
|
||||
}
|
||||
.light-color {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.addon-version {
|
||||
float: right;
|
||||
font-size: 15px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.description {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.logo img {
|
||||
max-height: 60px;
|
||||
margin: 16px 0;
|
||||
display: block;
|
||||
}
|
||||
.state div{
|
||||
width: 150px;
|
||||
display: inline-block;
|
||||
}
|
||||
paper-toggle-button {
|
||||
display: inline;
|
||||
}
|
||||
iron-icon.running {
|
||||
color: var(--paper-green-400);
|
||||
}
|
||||
iron-icon.stopped {
|
||||
color: var(--google-red-300);
|
||||
}
|
||||
ha-call-api-button {
|
||||
font-weight: 500;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
.right {
|
||||
float: right;
|
||||
}
|
||||
</style>
|
||||
<template is='dom-if' if='[[computeUpdateAvailable(addon)]]'>
|
||||
<paper-card heading='Update available! 🎉'>
|
||||
<div class='card-content'>
|
||||
<hassio-card-content
|
||||
title='[[addon.name]] [[addon.last_version]] is available'
|
||||
description='You are currently running version [[addon.version]]'
|
||||
icon='mdi:arrow-up-bold-circle'
|
||||
icon-class='update'
|
||||
></hassio-card-content>
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path='hassio/addons/[[addonSlug]]/update'
|
||||
>Update</ha-call-api-button>
|
||||
<template is='dom-if' if='[[addon.changelog]]'>
|
||||
<paper-button on-click='openChangelog'>Changelog</paper-button>
|
||||
</template>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
|
||||
<paper-card>
|
||||
<div class='card-content'>
|
||||
<div class='addon-header'>[[addon.name]]
|
||||
<div class='addon-version light-color'>
|
||||
<template is='dom-if' if='[[addon.version]]'>
|
||||
[[addon.version]]
|
||||
<template is='dom-if' if='[[isRunning]]'>
|
||||
<iron-icon
|
||||
title='Add-on is running'
|
||||
class='running'
|
||||
icon='mdi:circle'
|
||||
></iron-icon>
|
||||
</template>
|
||||
<template is='dom-if' if='[[!isRunning]]'>
|
||||
<iron-icon
|
||||
title='Add-on is stopped'
|
||||
class='stopped'
|
||||
icon='mdi:circle'
|
||||
></iron-icon>
|
||||
</template>
|
||||
</template>
|
||||
<template is='dom-if' if='[[!addon.version]]'>
|
||||
[[addon.last_version]]
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class='description light-color'>
|
||||
[[addon.description]].<br/>
|
||||
Visit <a href='[[addon.url]]' target='_blank'>[[addon.name]] page</a> for details.
|
||||
</div>
|
||||
<template is='dom-if' if='[[addon.logo]]'>
|
||||
<a href='[[addon.url]]' target='_blank' class='logo'>
|
||||
<img src='/api/hassio/addons/[[addonSlug]]/logo'/>
|
||||
</a>
|
||||
</template>
|
||||
<template is='dom-if' if='[[addon.version]]'>
|
||||
<div class='state'>
|
||||
<div>Start on boot</div>
|
||||
<paper-toggle-button
|
||||
on-change='startOnBootToggled'
|
||||
checked='[[computeStartOnBoot(addon.boot)]]'
|
||||
></paper-toggle-button>
|
||||
</div>
|
||||
<div class='state'>
|
||||
<div>Auto update</div>
|
||||
<paper-toggle-button
|
||||
on-change='autoUpdateToggled'
|
||||
checked='[[addon.auto_update]]'
|
||||
></paper-toggle-button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<template is='dom-if' if='[[addon.version]]'>
|
||||
<paper-button
|
||||
class='warning'
|
||||
on-click='_unistallClicked'
|
||||
>Uninstall</paper-button>
|
||||
<template is='dom-if' if='[[addon.build]]'>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path='hassio/addons/[[addonSlug]]/rebuild'
|
||||
>Rebuild</ha-call-api-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[isRunning]]'>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path='hassio/addons/[[addonSlug]]/restart'
|
||||
>Restart</ha-call-api-button>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path='hassio/addons/[[addonSlug]]/stop'
|
||||
>Stop</ha-call-api-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[!isRunning]]'>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path='hassio/addons/[[addonSlug]]/start'
|
||||
>Start</ha-call-api-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[computeShowWebUI(addon.webui, isRunning)]]'>
|
||||
<a
|
||||
href='[[pathWebui(addon.webui)]]'
|
||||
tabindex='-1'
|
||||
target='_blank'
|
||||
class='right'
|
||||
><paper-button>Open web UI</paper-button></a>
|
||||
</template>
|
||||
</template>
|
||||
<template is='dom-if' if='[[!addon.version]]'>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path='hassio/addons/[[addonSlug]]/install'
|
||||
>Install</ha-call-api-button>
|
||||
</template>
|
||||
</div>
|
||||
</paper-card>
|
||||
<template is='dom-if' if='[[addon.long_description]]'>
|
||||
<paper-card>
|
||||
<div class='card-content'>
|
||||
<ha-markdown content='[[addon.long_description]]'></ha-markdown>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HassioAddonInfo extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'hassio-addon-info'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
addon: Object,
|
||||
addonSlug: String,
|
||||
isRunning: {
|
||||
type: Boolean,
|
||||
computed: 'computeIsRunning(addon)',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
computeIsRunning(addon) {
|
||||
return addon && addon.state === 'started';
|
||||
}
|
||||
|
||||
computeUpdateAvailable(addon) {
|
||||
return addon && !addon.detached && addon.version && addon.version !== addon.last_version;
|
||||
}
|
||||
|
||||
pathWebui(webui) {
|
||||
return webui && webui.replace('[HOST]', document.location.hostname);
|
||||
}
|
||||
|
||||
computeShowWebUI(webui, isRunning) {
|
||||
return webui && isRunning;
|
||||
}
|
||||
|
||||
computeStartOnBoot(state) {
|
||||
return state === 'auto';
|
||||
}
|
||||
|
||||
startOnBootToggled() {
|
||||
const data = { boot: this.addon.boot === 'auto' ? 'manual' : 'auto' };
|
||||
this.hass.callApi('POST', `hassio/addons/${this.addonSlug}/options`, data);
|
||||
}
|
||||
|
||||
autoUpdateToggled() {
|
||||
const data = { auto_update: !this.addon.auto_update };
|
||||
this.hass.callApi('POST', `hassio/addons/${this.addonSlug}/options`, data);
|
||||
}
|
||||
|
||||
openChangelog() {
|
||||
this.hass.callApi('get', `hassio/addons/${this.addonSlug}/changelog`)
|
||||
.then(
|
||||
resp => resp
|
||||
, () => 'Error getting changelog'
|
||||
).then((content) => {
|
||||
this.fire('hassio-markdown-dialog', {
|
||||
title: 'Changelog',
|
||||
content: content,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_unistallClicked() {
|
||||
if (!confirm('Are you sure you want to uninstall this add-on?')) {
|
||||
return;
|
||||
}
|
||||
const path = `hassio/addons/${this.addonSlug}/uninstall`;
|
||||
const eventData = {
|
||||
path: path,
|
||||
};
|
||||
this.hass.callApi('post', path).then((resp) => {
|
||||
eventData.success = true;
|
||||
eventData.response = resp;
|
||||
}, (resp) => {
|
||||
eventData.success = false;
|
||||
eventData.response = resp;
|
||||
}).then(() => {
|
||||
this.fire('hass-api-called', eventData);
|
||||
});
|
||||
}
|
||||
}
|
||||
customElements.define(HassioAddonInfo.is, HassioAddonInfo);
|
||||
</script>
|
||||
225
hassio/addon-view/hassio-addon-info.js
Normal file
225
hassio/addon-view/hassio-addon-info.js
Normal file
@ -0,0 +1,225 @@
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-toggle-button/paper-toggle-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../../src/components/buttons/ha-call-api-button.js';
|
||||
import '../../src/components/ha-markdown.js';
|
||||
import '../../src/components/hassio-card-content.js';
|
||||
import '../../src/resources/ha-style.js';
|
||||
import '../../src/util/hass-mixins.js';
|
||||
|
||||
class HassioAddonInfo extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style">
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
paper-card {
|
||||
display: block;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.addon-header {
|
||||
@apply --paper-font-headline;
|
||||
}
|
||||
.light-color {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.addon-version {
|
||||
float: right;
|
||||
font-size: 15px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.description {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.logo img {
|
||||
max-height: 60px;
|
||||
margin: 16px 0;
|
||||
display: block;
|
||||
}
|
||||
.state div{
|
||||
width: 150px;
|
||||
display: inline-block;
|
||||
}
|
||||
paper-toggle-button {
|
||||
display: inline;
|
||||
}
|
||||
iron-icon.running {
|
||||
color: var(--paper-green-400);
|
||||
}
|
||||
iron-icon.stopped {
|
||||
color: var(--google-red-300);
|
||||
}
|
||||
ha-call-api-button {
|
||||
font-weight: 500;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
.right {
|
||||
float: right;
|
||||
}
|
||||
</style>
|
||||
<template is="dom-if" if="[[computeUpdateAvailable(addon)]]">
|
||||
<paper-card heading="Update available! 🎉">
|
||||
<div class="card-content">
|
||||
<hassio-card-content title="[[addon.name]] [[addon.last_version]] is available" description="You are currently running version [[addon.version]]" icon="mdi:arrow-up-bold-circle" icon-class="update"></hassio-card-content>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<ha-call-api-button hass="[[hass]]" path="hassio/addons/[[addonSlug]]/update">Update</ha-call-api-button>
|
||||
<template is="dom-if" if="[[addon.changelog]]">
|
||||
<paper-button on-click="openChangelog">Changelog</paper-button>
|
||||
</template>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
|
||||
<paper-card>
|
||||
<div class="card-content">
|
||||
<div class="addon-header">[[addon.name]]
|
||||
<div class="addon-version light-color">
|
||||
<template is="dom-if" if="[[addon.version]]">
|
||||
[[addon.version]]
|
||||
<template is="dom-if" if="[[isRunning]]">
|
||||
<iron-icon title="Add-on is running" class="running" icon="mdi:circle"></iron-icon>
|
||||
</template>
|
||||
<template is="dom-if" if="[[!isRunning]]">
|
||||
<iron-icon title="Add-on is stopped" class="stopped" icon="mdi:circle"></iron-icon>
|
||||
</template>
|
||||
</template>
|
||||
<template is="dom-if" if="[[!addon.version]]">
|
||||
[[addon.last_version]]
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="description light-color">
|
||||
[[addon.description]].<br>
|
||||
Visit <a href="[[addon.url]]" target="_blank">[[addon.name]] page</a> for details.
|
||||
</div>
|
||||
<template is="dom-if" if="[[addon.logo]]">
|
||||
<a href="[[addon.url]]" target="_blank" class="logo">
|
||||
<img src="/api/hassio/addons/[[addonSlug]]/logo">
|
||||
</a>
|
||||
</template>
|
||||
<template is="dom-if" if="[[addon.version]]">
|
||||
<div class="state">
|
||||
<div>Start on boot</div>
|
||||
<paper-toggle-button on-change="startOnBootToggled" checked="[[computeStartOnBoot(addon.boot)]]"></paper-toggle-button>
|
||||
</div>
|
||||
<div class="state">
|
||||
<div>Auto update</div>
|
||||
<paper-toggle-button on-change="autoUpdateToggled" checked="[[addon.auto_update]]"></paper-toggle-button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<template is="dom-if" if="[[addon.version]]">
|
||||
<paper-button class="warning" on-click="_unistallClicked">Uninstall</paper-button>
|
||||
<template is="dom-if" if="[[addon.build]]">
|
||||
<ha-call-api-button class="warning" hass="[[hass]]" path="hassio/addons/[[addonSlug]]/rebuild">Rebuild</ha-call-api-button>
|
||||
</template>
|
||||
<template is="dom-if" if="[[isRunning]]">
|
||||
<ha-call-api-button class="warning" hass="[[hass]]" path="hassio/addons/[[addonSlug]]/restart">Restart</ha-call-api-button>
|
||||
<ha-call-api-button class="warning" hass="[[hass]]" path="hassio/addons/[[addonSlug]]/stop">Stop</ha-call-api-button>
|
||||
</template>
|
||||
<template is="dom-if" if="[[!isRunning]]">
|
||||
<ha-call-api-button hass="[[hass]]" path="hassio/addons/[[addonSlug]]/start">Start</ha-call-api-button>
|
||||
</template>
|
||||
<template is="dom-if" if="[[computeShowWebUI(addon.webui, isRunning)]]">
|
||||
<a href="[[pathWebui(addon.webui)]]" tabindex="-1" target="_blank" class="right"><paper-button>Open web UI</paper-button></a>
|
||||
</template>
|
||||
</template>
|
||||
<template is="dom-if" if="[[!addon.version]]">
|
||||
<ha-call-api-button hass="[[hass]]" path="hassio/addons/[[addonSlug]]/install">Install</ha-call-api-button>
|
||||
</template>
|
||||
</div>
|
||||
</paper-card>
|
||||
<template is="dom-if" if="[[addon.long_description]]">
|
||||
<paper-card>
|
||||
<div class="card-content">
|
||||
<ha-markdown content="[[addon.long_description]]"></ha-markdown>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'hassio-addon-info'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
addon: Object,
|
||||
addonSlug: String,
|
||||
isRunning: {
|
||||
type: Boolean,
|
||||
computed: 'computeIsRunning(addon)',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
computeIsRunning(addon) {
|
||||
return addon && addon.state === 'started';
|
||||
}
|
||||
|
||||
computeUpdateAvailable(addon) {
|
||||
return addon && !addon.detached && addon.version && addon.version !== addon.last_version;
|
||||
}
|
||||
|
||||
pathWebui(webui) {
|
||||
return webui && webui.replace('[HOST]', document.location.hostname);
|
||||
}
|
||||
|
||||
computeShowWebUI(webui, isRunning) {
|
||||
return webui && isRunning;
|
||||
}
|
||||
|
||||
computeStartOnBoot(state) {
|
||||
return state === 'auto';
|
||||
}
|
||||
|
||||
startOnBootToggled() {
|
||||
const data = { boot: this.addon.boot === 'auto' ? 'manual' : 'auto' };
|
||||
this.hass.callApi('POST', `hassio/addons/${this.addonSlug}/options`, data);
|
||||
}
|
||||
|
||||
autoUpdateToggled() {
|
||||
const data = { auto_update: !this.addon.auto_update };
|
||||
this.hass.callApi('POST', `hassio/addons/${this.addonSlug}/options`, data);
|
||||
}
|
||||
|
||||
openChangelog() {
|
||||
this.hass.callApi('get', `hassio/addons/${this.addonSlug}/changelog`)
|
||||
.then(
|
||||
resp => resp
|
||||
, () => 'Error getting changelog'
|
||||
).then((content) => {
|
||||
this.fire('hassio-markdown-dialog', {
|
||||
title: 'Changelog',
|
||||
content: content,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_unistallClicked() {
|
||||
if (!confirm('Are you sure you want to uninstall this add-on?')) {
|
||||
return;
|
||||
}
|
||||
const path = `hassio/addons/${this.addonSlug}/uninstall`;
|
||||
const eventData = {
|
||||
path: path,
|
||||
};
|
||||
this.hass.callApi('post', path).then((resp) => {
|
||||
eventData.success = true;
|
||||
eventData.response = resp;
|
||||
}, (resp) => {
|
||||
eventData.success = false;
|
||||
eventData.response = resp;
|
||||
}).then(() => {
|
||||
this.fire('hass-api-called', eventData);
|
||||
});
|
||||
}
|
||||
}
|
||||
customElements.define(HassioAddonInfo.is, HassioAddonInfo);
|
||||
@ -1,30 +1,30 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../src/resources/ha-style.html'>
|
||||
import '../../src/resources/ha-style.js';
|
||||
|
||||
<dom-module id="hassio-addon-logs">
|
||||
<template>
|
||||
class HassioAddonLogs extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style">
|
||||
:host,
|
||||
paper-card {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<paper-card heading='Log'>
|
||||
<paper-card heading="Log">
|
||||
<div class="card-content">
|
||||
<pre>[[log]]</pre>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<paper-button on-click='refresh'>Refresh</paper-button>
|
||||
<paper-button on-click="refresh">Refresh</paper-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HassioAddonLogs extends Polymer.Element {
|
||||
static get is() { return 'hassio-addon-logs'; }
|
||||
|
||||
static get properties() {
|
||||
@ -56,4 +56,3 @@ class HassioAddonLogs extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HassioAddonLogs.is, HassioAddonLogs);
|
||||
</script>
|
||||
@ -1,14 +1,15 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../bower_components/paper-input/paper-input.html">
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
<link rel='import' href='../../src/resources/ha-style.html'>
|
||||
import '../../src/components/buttons/ha-call-api-button.js';
|
||||
import '../../src/resources/ha-style.js';
|
||||
import '../../src/util/hass-mixins.js';
|
||||
|
||||
<link rel="import" href="../../src/components/buttons/ha-call-api-button.html">
|
||||
|
||||
<dom-module id="hassio-addon-network">
|
||||
<template>
|
||||
class HassioAddonNetwork extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style">
|
||||
:host {
|
||||
display: block;
|
||||
@ -25,52 +26,37 @@
|
||||
@apply --layout-justified;
|
||||
}
|
||||
</style>
|
||||
<paper-card heading='Network'>
|
||||
<paper-card heading="Network">
|
||||
<div class="card-content">
|
||||
<template is='dom-if' if='[[error]]'>
|
||||
<div class='errors'>[[error]]</div>
|
||||
<template is="dom-if" if="[[error]]">
|
||||
<div class="errors">[[error]]</div>
|
||||
</template>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<tbody><tr>
|
||||
<th>Container</th>
|
||||
<th>Host</th>
|
||||
</tr>
|
||||
<template
|
||||
is='dom-repeat'
|
||||
items='[[config]]'
|
||||
>
|
||||
<template is="dom-repeat" items="[[config]]">
|
||||
<tr>
|
||||
<td>
|
||||
[[item.container]]
|
||||
</td>
|
||||
<td>
|
||||
<paper-input
|
||||
value='{{item.host}}'
|
||||
no-label-float
|
||||
></paper-input>
|
||||
<paper-input value="{{item.host}}" no-label-float=""></paper-input>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
</tbody></table>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path="hassio/addons/[[addonSlug]]/options"
|
||||
data="[[resetData]]"
|
||||
>Reset to defaults</ha-call-api-button>
|
||||
<paper-button
|
||||
on-click='saveTapped'
|
||||
>Save</paper-button>
|
||||
<ha-call-api-button class="warning" hass="[[hass]]" path="hassio/addons/[[addonSlug]]/options" data="[[resetData]]">Reset to defaults</ha-call-api-button>
|
||||
<paper-button on-click="saveTapped">Save</paper-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HassioAddonNetwork extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'hassio-addon-network'; }
|
||||
|
||||
static get properties() {
|
||||
@ -122,4 +108,3 @@ class HassioAddonNetwork extends window.hassMixins.EventsMixin(Polymer.Element)
|
||||
}
|
||||
|
||||
customElements.define(HassioAddonNetwork.is, HassioAddonNetwork);
|
||||
</script>
|
||||
@ -1,165 +0,0 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../bower_components/app-route/app-route.html'>
|
||||
<link rel='import' href='../../bower_components/app-layout/app-header-layout/app-header-layout.html'>
|
||||
<link rel='import' href='../../bower_components/app-layout/app-header/app-header.html'>
|
||||
<link rel='import' href='../../bower_components/app-layout/app-toolbar/app-toolbar.html'>
|
||||
<link rel='import' href='../../bower_components/paper-icon-button/paper-icon-button.html'>
|
||||
|
||||
<link rel='import' href='../../src/components/ha-menu-button.html'>
|
||||
<link rel='import' href='../../src/resources/ha-style.html'>
|
||||
|
||||
<link rel="import" href="./hassio-addon-info.html">
|
||||
<link rel="import" href="./hassio-addon-config.html">
|
||||
<link rel="import" href="./hassio-addon-audio.html">
|
||||
<link rel="import" href="./hassio-addon-network.html">
|
||||
<link rel="import" href="./hassio-addon-logs.html">
|
||||
<link rel='import' href='../hassio-markdown-dialog.html'>
|
||||
|
||||
<dom-module id="hassio-addon-view">
|
||||
<template>
|
||||
<style include="iron-flex ha-style">
|
||||
:host {
|
||||
color: var(--primary-text-color);
|
||||
--paper-card-header-color: var(--primary-text-color);
|
||||
}
|
||||
.content {
|
||||
padding: 24px 0 32px;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
hassio-addon-info,
|
||||
hassio-addon-network,
|
||||
hassio-addon-audio,
|
||||
hassio-addon-config {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
</style>
|
||||
<app-route
|
||||
route='[[route]]'
|
||||
pattern='/addon/:slug'
|
||||
data="{{routeData}}"
|
||||
active='{{routeMatches}}'
|
||||
></app-route>
|
||||
<app-header-layout has-scrolling-region>
|
||||
<app-header fixed slot='header'>
|
||||
<app-toolbar>
|
||||
<ha-menu-button narrow='[[narrow]]' show-menu='[[showMenu]]'></ha-menu-button>
|
||||
<paper-icon-button
|
||||
icon='mdi:arrow-left'
|
||||
on-click='backTapped'
|
||||
></paper-icon-button>
|
||||
<div main-title>Hass.io: add-on details</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
<div class='content'>
|
||||
<hassio-addon-info
|
||||
hass='[[hass]]'
|
||||
addon='[[addon]]'
|
||||
addon-slug='[[routeData.slug]]'
|
||||
></hassio-addon-info>
|
||||
|
||||
<template is='dom-if' if='[[addon.version]]'>
|
||||
<hassio-addon-config
|
||||
hass='[[hass]]'
|
||||
addon='[[addon]]'
|
||||
addon-slug='[[routeData.slug]]'
|
||||
></hassio-addon-config>
|
||||
|
||||
<template is='dom-if' if='[[addon.audio]]'>
|
||||
<hassio-addon-audio
|
||||
hass='[[hass]]'
|
||||
addon='[[addon]]'
|
||||
></hassio-addon-audio>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[addon.network]]'>
|
||||
<hassio-addon-network
|
||||
hass='[[hass]]'
|
||||
addon='[[addon]]'
|
||||
addon-slug='[[routeData.slug]]'
|
||||
></hassio-addon-network>
|
||||
</template>
|
||||
|
||||
<hassio-addon-logs
|
||||
hass='[[hass]]'
|
||||
addon-slug='[[routeData.slug]]'
|
||||
></hassio-addon-logs>
|
||||
</template>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
|
||||
<hassio-markdown-dialog
|
||||
title='[[markdownTitle]]'
|
||||
content='[[markdownContent]]'
|
||||
></hassio-markdown-dialog>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HassioAddonView extends Polymer.Element {
|
||||
static get is() { return 'hassio-addon-view'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
showMenu: Boolean,
|
||||
narrow: Boolean,
|
||||
route: Object,
|
||||
routeData: {
|
||||
type: Object,
|
||||
observer: 'routeDataChanged',
|
||||
},
|
||||
routeMatches: Boolean,
|
||||
addon: Object,
|
||||
|
||||
markdownTitle: String,
|
||||
markdownContent: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
ready() {
|
||||
super.ready();
|
||||
this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
|
||||
this.addEventListener('hassio-markdown-dialog', ev => this.openMarkdown(ev));
|
||||
}
|
||||
|
||||
apiCalled(ev) {
|
||||
const path = ev.detail.path;
|
||||
|
||||
if (!path) return;
|
||||
|
||||
if (path.substr(path.lastIndexOf('/') + 1) === 'uninstall') {
|
||||
this.backTapped();
|
||||
} else {
|
||||
this.routeDataChanged(this.routeData);
|
||||
}
|
||||
}
|
||||
|
||||
routeDataChanged(routeData) {
|
||||
if (!this.routeMatches || !routeData || !routeData.slug) return;
|
||||
this.hass.callApi('get', `hassio/addons/${routeData.slug}/info`)
|
||||
.then((info) => {
|
||||
this.addon = info.data;
|
||||
}, () => {
|
||||
this.addon = null;
|
||||
});
|
||||
}
|
||||
|
||||
backTapped() {
|
||||
history.back();
|
||||
}
|
||||
|
||||
openMarkdown(ev) {
|
||||
this.setProperties({
|
||||
markdownTitle: ev.detail.title,
|
||||
markdownContent: ev.detail.content,
|
||||
});
|
||||
this.shadowRoot.querySelector('hassio-markdown-dialog').openDialog();
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HassioAddonView.is, HassioAddonView);
|
||||
</script>
|
||||
134
hassio/addon-view/hassio-addon-view.js
Normal file
134
hassio/addon-view/hassio-addon-view.js
Normal file
@ -0,0 +1,134 @@
|
||||
import '@polymer/app-layout/app-header-layout/app-header-layout.js';
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/app-route/app-route.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../../src/components/ha-menu-button.js';
|
||||
import '../../src/resources/ha-style.js';
|
||||
import '../hassio-markdown-dialog.js';
|
||||
import './hassio-addon-audio.js';
|
||||
import './hassio-addon-config.js';
|
||||
import './hassio-addon-info.js';
|
||||
import './hassio-addon-logs.js';
|
||||
import './hassio-addon-network.js';
|
||||
|
||||
class HassioAddonView extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
:host {
|
||||
color: var(--primary-text-color);
|
||||
--paper-card-header-color: var(--primary-text-color);
|
||||
}
|
||||
.content {
|
||||
padding: 24px 0 32px;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
hassio-addon-info,
|
||||
hassio-addon-network,
|
||||
hassio-addon-audio,
|
||||
hassio-addon-config {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
</style>
|
||||
<app-route route="[[route]]" pattern="/addon/:slug" data="{{routeData}}" active="{{routeMatches}}"></app-route>
|
||||
<app-header-layout has-scrolling-region="">
|
||||
<app-header fixed="" slot="header">
|
||||
<app-toolbar>
|
||||
<ha-menu-button narrow="[[narrow]]" show-menu="[[showMenu]]"></ha-menu-button>
|
||||
<paper-icon-button icon="mdi:arrow-left" on-click="backTapped"></paper-icon-button>
|
||||
<div main-title="">Hass.io: add-on details</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
<div class="content">
|
||||
<hassio-addon-info hass="[[hass]]" addon="[[addon]]" addon-slug="[[routeData.slug]]"></hassio-addon-info>
|
||||
|
||||
<template is="dom-if" if="[[addon.version]]">
|
||||
<hassio-addon-config hass="[[hass]]" addon="[[addon]]" addon-slug="[[routeData.slug]]"></hassio-addon-config>
|
||||
|
||||
<template is="dom-if" if="[[addon.audio]]">
|
||||
<hassio-addon-audio hass="[[hass]]" addon="[[addon]]"></hassio-addon-audio>
|
||||
</template>
|
||||
|
||||
<template is="dom-if" if="[[addon.network]]">
|
||||
<hassio-addon-network hass="[[hass]]" addon="[[addon]]" addon-slug="[[routeData.slug]]"></hassio-addon-network>
|
||||
</template>
|
||||
|
||||
<hassio-addon-logs hass="[[hass]]" addon-slug="[[routeData.slug]]"></hassio-addon-logs>
|
||||
</template>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
|
||||
<hassio-markdown-dialog title="[[markdownTitle]]" content="[[markdownContent]]"></hassio-markdown-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'hassio-addon-view'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
showMenu: Boolean,
|
||||
narrow: Boolean,
|
||||
route: Object,
|
||||
routeData: {
|
||||
type: Object,
|
||||
observer: 'routeDataChanged',
|
||||
},
|
||||
routeMatches: Boolean,
|
||||
addon: Object,
|
||||
|
||||
markdownTitle: String,
|
||||
markdownContent: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
ready() {
|
||||
super.ready();
|
||||
this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
|
||||
this.addEventListener('hassio-markdown-dialog', ev => this.openMarkdown(ev));
|
||||
}
|
||||
|
||||
apiCalled(ev) {
|
||||
const path = ev.detail.path;
|
||||
|
||||
if (!path) return;
|
||||
|
||||
if (path.substr(path.lastIndexOf('/') + 1) === 'uninstall') {
|
||||
this.backTapped();
|
||||
} else {
|
||||
this.routeDataChanged(this.routeData);
|
||||
}
|
||||
}
|
||||
|
||||
routeDataChanged(routeData) {
|
||||
if (!this.routeMatches || !routeData || !routeData.slug) return;
|
||||
this.hass.callApi('get', `hassio/addons/${routeData.slug}/info`)
|
||||
.then((info) => {
|
||||
this.addon = info.data;
|
||||
}, () => {
|
||||
this.addon = null;
|
||||
});
|
||||
}
|
||||
|
||||
backTapped() {
|
||||
history.back();
|
||||
}
|
||||
|
||||
openMarkdown(ev) {
|
||||
this.setProperties({
|
||||
markdownTitle: ev.detail.title,
|
||||
markdownContent: ev.detail.content,
|
||||
});
|
||||
this.shadowRoot.querySelector('hassio-markdown-dialog').openDialog();
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HassioAddonView.is, HassioAddonView);
|
||||
@ -1,45 +1,39 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../bower_components/paper-card/paper-card.html'>
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
<link rel='import' href='../../src/components/hassio-card-content.html'>
|
||||
<link rel='import' href='../../src/resources/hassio-style.html'>
|
||||
import '../../src/components/hassio-card-content.js';
|
||||
import '../../src/resources/hassio-style.js';
|
||||
import '../../src/util/hass-mixins.js';
|
||||
|
||||
<dom-module id='hassio-addons'>
|
||||
<template>
|
||||
<style include='ha-style hassio-style'>
|
||||
class HassioAddons extends window.hassMixins.NavigateMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style hassio-style">
|
||||
paper-card {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
<div class='content card-group'>
|
||||
<div class='title'>Add-ons</div>
|
||||
<template is='dom-if' if='[[!addons.length]]'>
|
||||
<div class="content card-group">
|
||||
<div class="title">Add-ons</div>
|
||||
<template is="dom-if" if="[[!addons.length]]">
|
||||
<paper-card>
|
||||
<div class='card-content'>
|
||||
You don't have any add-ons installed yet. Head over to <a href='#' on-click='openStore'>the add-on store</a> to get started!
|
||||
<div class="card-content">
|
||||
You don't have any add-ons installed yet. Head over to <a href="#" on-click="openStore">the add-on store</a> to get started!
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
<template is='dom-repeat' items='[[addons]]' as='addon' sort='sortAddons'>
|
||||
<paper-card on-click='addonTapped'>
|
||||
<div class='card-content'>
|
||||
<hassio-card-content
|
||||
title='[[addon.name]]'
|
||||
description='[[addon.description]]'
|
||||
icon='[[computeIcon(addon)]]'
|
||||
icon-title='[[computeIconTitle(addon)]]'
|
||||
icon-class='[[computeIconClass(addon)]]'
|
||||
></hassio-card-content>
|
||||
<template is="dom-repeat" items="[[addons]]" as="addon" sort="sortAddons">
|
||||
<paper-card on-click="addonTapped">
|
||||
<div class="card-content">
|
||||
<hassio-card-content title="[[addon.name]]" description="[[addon.description]]" icon="[[computeIcon(addon)]]" icon-title="[[computeIconTitle(addon)]]" icon-class="[[computeIconClass(addon)]]"></hassio-card-content>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HassioAddons extends window.hassMixins.NavigateMixin(Polymer.Element) {
|
||||
static get is() { return 'hassio-addons'; }
|
||||
|
||||
static get properties() {
|
||||
@ -79,4 +73,3 @@ class HassioAddons extends window.hassMixins.NavigateMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HassioAddons.is, HassioAddons);
|
||||
</script>
|
||||
@ -1,40 +0,0 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
|
||||
<link rel="import" href="./hassio-addons.html">
|
||||
<link rel="import" href="./hassio-hass-update.html">
|
||||
|
||||
<dom-module id="hassio-dashboard">
|
||||
<template>
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
<div class='content'>
|
||||
<hassio-hass-update
|
||||
hass='[[hass]]'
|
||||
hass-info='[[hassInfo]]'
|
||||
></hassio-hass-update>
|
||||
<hassio-addons
|
||||
hass='[[hass]]'
|
||||
addons='[[supervisorInfo.addons]]'
|
||||
></hassio-addons>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HassioDashboard extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'hassio-dashboard'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
supervisorInfo: Object,
|
||||
hassInfo: Object,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HassioDashboard.is, HassioDashboard);
|
||||
</script>
|
||||
33
hassio/dashboard/hassio-dashboard.js
Normal file
33
hassio/dashboard/hassio-dashboard.js
Normal file
@ -0,0 +1,33 @@
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import './hassio-addons.js';
|
||||
import './hassio-hass-update.js';
|
||||
|
||||
class HassioDashboard extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
<div class="content">
|
||||
<hassio-hass-update hass="[[hass]]" hass-info="[[hassInfo]]"></hassio-hass-update>
|
||||
<hassio-addons hass="[[hass]]" addons="[[supervisorInfo.addons]]"></hassio-addons>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'hassio-dashboard'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
supervisorInfo: Object,
|
||||
hassInfo: Object,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HassioDashboard.is, HassioDashboard);
|
||||
@ -1,93 +0,0 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
|
||||
<link rel="import" href="../../src/components/buttons/ha-call-api-button.html">
|
||||
<link rel='import' href='../../src/components/hassio-card-content.html'>
|
||||
<link rel='import' href='../../src/resources/hassio-style.html'>
|
||||
|
||||
<dom-module id="hassio-hass-update">
|
||||
<template>
|
||||
<style include="ha-style hassio-style">
|
||||
paper-card {
|
||||
display: block;
|
||||
height: 100%;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
.errors {
|
||||
color: var(--google-red-500);
|
||||
margin-top: 16px;
|
||||
}
|
||||
</style>
|
||||
<template is='dom-if' if='[[computeUpdateAvailable(hassInfo)]]'>
|
||||
<div class='content'>
|
||||
<div class='card-group'>
|
||||
<div class='title'>Update available! 🎉</div>
|
||||
<paper-card>
|
||||
<div class='card-content'>
|
||||
<hassio-card-content
|
||||
title='Home Assistant [[hassInfo.last_version]] is available'
|
||||
description='You are currently running version [[hassInfo.version]]'
|
||||
icon='mdi:home-assistant'
|
||||
icon-class='hassupdate'
|
||||
></hassio-card-content>
|
||||
<template is='dom-if' if='[[error]]'>
|
||||
<div class='error'>Error: [[error]]</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path='hassio/homeassistant/update'
|
||||
>Update</ha-call-api-button>
|
||||
<a
|
||||
href='https://github.com/home-assistant/home-assistant/releases'
|
||||
target='_blank'
|
||||
><paper-button>Release notes</paper-button></a>
|
||||
</div>
|
||||
</paper-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HassioHassUpdate extends Polymer.Element {
|
||||
static get is() { return 'hassio-hass-update'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
hassInfo: Object,
|
||||
error: String,
|
||||
};
|
||||
}
|
||||
|
||||
ready() {
|
||||
super.ready();
|
||||
this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
|
||||
}
|
||||
|
||||
apiCalled(ev) {
|
||||
if (ev.detail.success) {
|
||||
this.errors = null;
|
||||
return;
|
||||
}
|
||||
|
||||
const response = ev.detail.response;
|
||||
|
||||
if (typeof response.body === 'object') {
|
||||
this.errors = response.body.message || 'Unknown error';
|
||||
} else {
|
||||
this.errors = response.body;
|
||||
}
|
||||
}
|
||||
|
||||
computeUpdateAvailable(hassInfo) {
|
||||
return hassInfo.version !== hassInfo.last_version;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HassioHassUpdate.is, HassioHassUpdate);
|
||||
</script>
|
||||
81
hassio/dashboard/hassio-hass-update.js
Normal file
81
hassio/dashboard/hassio-hass-update.js
Normal file
@ -0,0 +1,81 @@
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../../src/components/buttons/ha-call-api-button.js';
|
||||
import '../../src/components/hassio-card-content.js';
|
||||
import '../../src/resources/hassio-style.js';
|
||||
|
||||
class HassioHassUpdate extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style hassio-style">
|
||||
paper-card {
|
||||
display: block;
|
||||
height: 100%;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
.errors {
|
||||
color: var(--google-red-500);
|
||||
margin-top: 16px;
|
||||
}
|
||||
</style>
|
||||
<template is="dom-if" if="[[computeUpdateAvailable(hassInfo)]]">
|
||||
<div class="content">
|
||||
<div class="card-group">
|
||||
<div class="title">Update available! 🎉</div>
|
||||
<paper-card>
|
||||
<div class="card-content">
|
||||
<hassio-card-content title="Home Assistant [[hassInfo.last_version]] is available" description="You are currently running version [[hassInfo.version]]" icon="mdi:home-assistant" icon-class="hassupdate"></hassio-card-content>
|
||||
<template is="dom-if" if="[[error]]">
|
||||
<div class="error">Error: [[error]]</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<ha-call-api-button hass="[[hass]]" path="hassio/homeassistant/update">Update</ha-call-api-button>
|
||||
<a href="https://github.com/home-assistant/home-assistant/releases" target="_blank"><paper-button>Release notes</paper-button></a>
|
||||
</div>
|
||||
</paper-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'hassio-hass-update'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
hassInfo: Object,
|
||||
error: String,
|
||||
};
|
||||
}
|
||||
|
||||
ready() {
|
||||
super.ready();
|
||||
this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
|
||||
}
|
||||
|
||||
apiCalled(ev) {
|
||||
if (ev.detail.success) {
|
||||
this.errors = null;
|
||||
return;
|
||||
}
|
||||
|
||||
const response = ev.detail.response;
|
||||
|
||||
if (typeof response.body === 'object') {
|
||||
this.errors = response.body.message || 'Unknown error';
|
||||
} else {
|
||||
this.errors = response.body;
|
||||
}
|
||||
}
|
||||
|
||||
computeUpdateAvailable(hassInfo) {
|
||||
return hassInfo.version !== hassInfo.last_version;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HassioHassUpdate.is, HassioHassUpdate);
|
||||
@ -1,21 +1,17 @@
|
||||
<link rel="import" href="../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="./hassio-main.html">
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id="hassio-app">
|
||||
<template>
|
||||
<template is='dom-if' if='[[hass]]'>
|
||||
<hassio-main
|
||||
hass='[[hass]]'
|
||||
narrow='[[narrow]]'
|
||||
show-menu='[[showMenu]]'
|
||||
route='[[route]]'
|
||||
></hassio-main>
|
||||
import './hassio-main.js';
|
||||
|
||||
class HassioApp extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<template is="dom-if" if="[[hass]]">
|
||||
<hassio-main hass="[[hass]]" narrow="[[narrow]]" show-menu="[[showMenu]]" route="[[route]]"></hassio-main>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HassioApp extends Polymer.Element {
|
||||
static get is() { return 'hassio-app'; }
|
||||
|
||||
static get properties() {
|
||||
@ -49,4 +45,3 @@ class HassioApp extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HassioApp.is, HassioApp);
|
||||
</script>
|
||||
@ -1,7 +1,6 @@
|
||||
<link rel="import" href="../bower_components/polymer/polymer-element.html">
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<script>
|
||||
class HassioData extends Polymer.Element {
|
||||
class HassioData extends PolymerElement {
|
||||
static get is() { return 'hassio-data'; }
|
||||
|
||||
static get properties() {
|
||||
@ -61,4 +60,3 @@ class HassioData extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HassioData.is, HassioData);
|
||||
</script>
|
||||
@ -1,132 +0,0 @@
|
||||
<link rel="import" href="../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../bower_components/app-route/app-route.html">
|
||||
|
||||
<link rel="import" href="../src/layouts/hass-loading-screen.html">
|
||||
<link rel='import' href='../src/util/hass-util.html'>
|
||||
|
||||
<link rel='import' href='./hassio-data.html'>
|
||||
<link rel='import' href='./hassio-pages-with-tabs.html'>
|
||||
<link rel='import' href='./addon-view/hassio-addon-view.html'>
|
||||
|
||||
<dom-module id="hassio-main">
|
||||
<template>
|
||||
<app-route
|
||||
route='[[route]]'
|
||||
pattern='/:page'
|
||||
data="{{routeData}}"
|
||||
></app-route>
|
||||
<hassio-data
|
||||
id='data'
|
||||
hass='[[hass]]'
|
||||
supervisor='{{supervisorInfo}}'
|
||||
homeassistant='{{hassInfo}}'
|
||||
host='{{hostInfo}}'
|
||||
></hassio-data>
|
||||
|
||||
<template is='dom-if' if='[[!loaded]]'>
|
||||
<hass-loading-screen
|
||||
narrow='[[narrow]]'
|
||||
show-menu='[[showMenu]]'
|
||||
></hass-loading-screen>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[loaded]]'>
|
||||
<template is='dom-if' if='[[!equalsAddon(routeData.page)]]'>
|
||||
<hassio-pages-with-tabs
|
||||
hass='[[hass]]'
|
||||
narrow='[[narrow]]'
|
||||
show-menu='[[showMenu]]'
|
||||
page='[[routeData.page]]'
|
||||
supervisor-info='[[supervisorInfo]]'
|
||||
hass-info='[[hassInfo]]'
|
||||
host-info='[[hostInfo]]'
|
||||
></hassio-pages-with-tabs>
|
||||
</template>
|
||||
<template is='dom-if' if='[[equalsAddon(routeData.page)]]'>
|
||||
<hassio-addon-view
|
||||
hass='[[hass]]'
|
||||
narrow='[[narrow]]'
|
||||
show-menu='[[showMenu]]'
|
||||
route='[[route]]'
|
||||
></hassio-addon-view>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HassioMain extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'hassio-main'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
narrow: Boolean,
|
||||
showMenu: Boolean,
|
||||
route: {
|
||||
type: Object,
|
||||
// Fake route object
|
||||
value: {
|
||||
prefix: '/hassio',
|
||||
path: '/dashboard',
|
||||
__queryParams: {}
|
||||
},
|
||||
observer: 'routeChanged',
|
||||
},
|
||||
routeData: Object,
|
||||
supervisorInfo: Object,
|
||||
hostInfo: Object,
|
||||
hassInfo: Object,
|
||||
loaded: {
|
||||
type: Boolean,
|
||||
computed: 'computeIsLoaded(supervisorInfo, hostInfo, hassInfo)',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
ready() {
|
||||
super.ready();
|
||||
window.hassUtil.applyThemesOnElement(this, this.hass.themes, this.hass.selectedTheme, true);
|
||||
this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.routeChanged(this.route);
|
||||
}
|
||||
|
||||
apiCalled(ev) {
|
||||
if (ev.detail.success) {
|
||||
let tries = 1;
|
||||
|
||||
const tryUpdate = () => {
|
||||
this.$.data.refresh().catch(function () {
|
||||
tries += 1;
|
||||
setTimeout(tryUpdate, Math.min(tries, 5) * 1000);
|
||||
});
|
||||
};
|
||||
|
||||
tryUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
computeIsLoaded(supervisorInfo, hostInfo, hassInfo) {
|
||||
return (supervisorInfo !== null &&
|
||||
hostInfo !== null &&
|
||||
hassInfo !== null);
|
||||
}
|
||||
|
||||
routeChanged(route) {
|
||||
if (route.path === '' && route.prefix === '/hassio') {
|
||||
history.replaceState(null, null, '/hassio/dashboard');
|
||||
this.fire('location-changed');
|
||||
}
|
||||
}
|
||||
|
||||
equalsAddon(page) {
|
||||
return page && page === 'addon';
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HassioMain.is, HassioMain);
|
||||
</script>
|
||||
104
hassio/hassio-main.js
Normal file
104
hassio/hassio-main.js
Normal file
@ -0,0 +1,104 @@
|
||||
import '@polymer/app-route/app-route.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../src/layouts/hass-loading-screen.js';
|
||||
import '../src/util/hass-util.js';
|
||||
import './addon-view/hassio-addon-view.js';
|
||||
import './hassio-data.js';
|
||||
import './hassio-pages-with-tabs.js';
|
||||
|
||||
class HassioMain extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<app-route route="[[route]]" pattern="/:page" data="{{routeData}}"></app-route>
|
||||
<hassio-data id="data" hass="[[hass]]" supervisor="{{supervisorInfo}}" homeassistant="{{hassInfo}}" host="{{hostInfo}}"></hassio-data>
|
||||
|
||||
<template is="dom-if" if="[[!loaded]]">
|
||||
<hass-loading-screen narrow="[[narrow]]" show-menu="[[showMenu]]"></hass-loading-screen>
|
||||
</template>
|
||||
|
||||
<template is="dom-if" if="[[loaded]]">
|
||||
<template is="dom-if" if="[[!equalsAddon(routeData.page)]]">
|
||||
<hassio-pages-with-tabs hass="[[hass]]" narrow="[[narrow]]" show-menu="[[showMenu]]" page="[[routeData.page]]" supervisor-info="[[supervisorInfo]]" hass-info="[[hassInfo]]" host-info="[[hostInfo]]"></hassio-pages-with-tabs>
|
||||
</template>
|
||||
<template is="dom-if" if="[[equalsAddon(routeData.page)]]">
|
||||
<hassio-addon-view hass="[[hass]]" narrow="[[narrow]]" show-menu="[[showMenu]]" route="[[route]]"></hassio-addon-view>
|
||||
</template>
|
||||
</template>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'hassio-main'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
narrow: Boolean,
|
||||
showMenu: Boolean,
|
||||
route: {
|
||||
type: Object,
|
||||
// Fake route object
|
||||
value: {
|
||||
prefix: '/hassio',
|
||||
path: '/dashboard',
|
||||
__queryParams: {}
|
||||
},
|
||||
observer: 'routeChanged',
|
||||
},
|
||||
routeData: Object,
|
||||
supervisorInfo: Object,
|
||||
hostInfo: Object,
|
||||
hassInfo: Object,
|
||||
loaded: {
|
||||
type: Boolean,
|
||||
computed: 'computeIsLoaded(supervisorInfo, hostInfo, hassInfo)',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
ready() {
|
||||
super.ready();
|
||||
window.hassUtil.applyThemesOnElement(this, this.hass.themes, this.hass.selectedTheme, true);
|
||||
this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.routeChanged(this.route);
|
||||
}
|
||||
|
||||
apiCalled(ev) {
|
||||
if (ev.detail.success) {
|
||||
let tries = 1;
|
||||
|
||||
const tryUpdate = () => {
|
||||
this.$.data.refresh().catch(function () {
|
||||
tries += 1;
|
||||
setTimeout(tryUpdate, Math.min(tries, 5) * 1000);
|
||||
});
|
||||
};
|
||||
|
||||
tryUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
computeIsLoaded(supervisorInfo, hostInfo, hassInfo) {
|
||||
return (supervisorInfo !== null &&
|
||||
hostInfo !== null &&
|
||||
hassInfo !== null);
|
||||
}
|
||||
|
||||
routeChanged(route) {
|
||||
if (route.path === '' && route.prefix === '/hassio') {
|
||||
history.replaceState(null, null, '/hassio/dashboard');
|
||||
this.fire('location-changed');
|
||||
}
|
||||
}
|
||||
|
||||
equalsAddon(page) {
|
||||
return page && page === 'addon';
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HassioMain.is, HassioMain);
|
||||
@ -1,15 +1,17 @@
|
||||
<link rel='import' href='../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../bower_components/paper-dialog/paper-dialog.html'>
|
||||
<link rel='import' href='../bower_components/app-layout/app-toolbar/app-toolbar.html'>
|
||||
<link rel='import' href='../bower_components/paper-icon-button/paper-icon-button.html'>
|
||||
<link rel='import' href='../bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html'>
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/paper-dialog-scrollable/paper-dialog-scrollable.js';
|
||||
import '@polymer/paper-dialog/paper-dialog.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../src/components/ha-markdown.html'>
|
||||
<link rel='import' href='../src/resources/ha-style.html'>
|
||||
import '../src/components/ha-markdown.js';
|
||||
import '../src/resources/ha-style.js';
|
||||
|
||||
<dom-module id='hassio-markdown-dialog'>
|
||||
<template>
|
||||
<style include='ha-style-dialog'>
|
||||
class HassioMarkdownDialog extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style-dialog">
|
||||
paper-dialog {
|
||||
min-width: 350px;
|
||||
font-size: 14px;
|
||||
@ -48,26 +50,18 @@
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<paper-dialog
|
||||
id='dialog'
|
||||
with-backdrop
|
||||
>
|
||||
<paper-dialog id="dialog" with-backdrop="">
|
||||
<app-toolbar>
|
||||
<paper-icon-button
|
||||
icon='mdi:close'
|
||||
dialog-dismiss
|
||||
></paper-icon-button>
|
||||
<div main-title>[[title]]</div>
|
||||
<paper-icon-button icon="mdi:close" dialog-dismiss=""></paper-icon-button>
|
||||
<div main-title="">[[title]]</div>
|
||||
</app-toolbar>
|
||||
<paper-dialog-scrollable>
|
||||
<ha-markdown content='[[content]]'></ha-markdown>
|
||||
<ha-markdown content="[[content]]"></ha-markdown>
|
||||
</paper-dialog-scrollable>
|
||||
</paper-dialog>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HassioMarkdownDialog extends Polymer.Element {
|
||||
static get is() { return 'hassio-markdown-dialog'; }
|
||||
|
||||
static get properties() {
|
||||
@ -82,4 +76,3 @@ class HassioMarkdownDialog extends Polymer.Element {
|
||||
}
|
||||
}
|
||||
customElements.define(HassioMarkdownDialog.is, HassioMarkdownDialog);
|
||||
</script>
|
||||
@ -1,163 +0,0 @@
|
||||
<link rel='import' href='../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../bower_components/app-layout/app-header-layout/app-header-layout.html'>
|
||||
<link rel='import' href='../bower_components/app-layout/app-header/app-header.html'>
|
||||
<link rel='import' href='../bower_components/app-layout/app-toolbar/app-toolbar.html'>
|
||||
<link rel='import' href='../bower_components/paper-tabs/paper-tabs.html'>
|
||||
<link rel='import' href='../bower_components/paper-tabs/paper-tab.html'>
|
||||
<link rel='import' href='../bower_components/paper-icon-button/paper-icon-button.html'>
|
||||
|
||||
<link rel='import' href='../src/components/ha-menu-button.html'>
|
||||
<link rel='import' href='../src/util/hass-mixins.html'>
|
||||
<link rel='import' href='../src/resources/ha-style.html'>
|
||||
|
||||
<link rel='import' href='./dashboard/hassio-dashboard.html'>
|
||||
<link rel='import' href='./snapshots/hassio-snapshots.html'>
|
||||
<link rel='import' href='./snapshots/hassio-snapshot.html'>
|
||||
<link rel='import' href='./addon-store/hassio-addon-store.html'>
|
||||
<link rel='import' href='./system/hassio-system.html'>
|
||||
<link rel='import' href='./hassio-markdown-dialog.html'>
|
||||
|
||||
<dom-module id='hassio-pages-with-tabs'>
|
||||
<template>
|
||||
<style include='iron-flex iron-positioning ha-style'>
|
||||
:host {
|
||||
color: var(--primary-text-color);
|
||||
--paper-card-header-color: var(--primary-text-color);
|
||||
}
|
||||
paper-tabs {
|
||||
margin-left: 12px;
|
||||
--paper-tabs-selection-bar-color: #FFF;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
</style>
|
||||
<app-header-layout has-scrolling-region>
|
||||
<app-header fixed slot='header'>
|
||||
<app-toolbar>
|
||||
<ha-menu-button narrow='[[narrow]]' show-menu='[[showMenu]]'></ha-menu-button>
|
||||
<div main-title>Hass.io</div>
|
||||
<template is='dom-if' if='[[showRefreshButton(page)]]'>
|
||||
<paper-icon-button
|
||||
icon='mdi:refresh'
|
||||
on-click='refreshClicked'
|
||||
></paper-icon-button>
|
||||
</template>
|
||||
</app-toolbar>
|
||||
<paper-tabs
|
||||
scrollable
|
||||
selected='[[page]]'
|
||||
attr-for-selected='page-name'
|
||||
on-iron-activate='handlePageSelected'
|
||||
>
|
||||
<paper-tab page-name='dashboard'>Dashboard</paper-tab>
|
||||
<paper-tab page-name='snapshots'>Snapshots</paper-tab>
|
||||
<paper-tab page-name='store'>Add-on store</paper-tab>
|
||||
<paper-tab page-name='system'>System</paper-tab>
|
||||
</paper-tabs>
|
||||
</app-header>
|
||||
<template is='dom-if' if='[[equals(page, "dashboard")]]'>
|
||||
<hassio-dashboard
|
||||
hass='[[hass]]'
|
||||
supervisor-info='[[supervisorInfo]]'
|
||||
hass-info='[[hassInfo]]'
|
||||
></hassio-dashboard>
|
||||
</template>
|
||||
<template is='dom-if' if='[[equals(page, "snapshots")]]'>
|
||||
<hassio-snapshots
|
||||
hass='[[hass]]'
|
||||
installed-addons='[[supervisorInfo.addons]]'
|
||||
snapshot-slug='{{snapshotSlug}}'
|
||||
snapshot-deleted='{{snapshotDeleted}}'
|
||||
></hassio-snapshots>
|
||||
</template>
|
||||
<template is='dom-if' if='[[equals(page, "store")]]'>
|
||||
<hassio-addon-store
|
||||
hass='[[hass]]'
|
||||
></hassio-addon-store>
|
||||
</template>
|
||||
<template is='dom-if' if='[[equals(page, "system")]]'>
|
||||
<hassio-system
|
||||
hass='[[hass]]'
|
||||
supervisor-info='[[supervisorInfo]]'
|
||||
host-info='[[hostInfo]]'
|
||||
></hassio-system>
|
||||
</template>
|
||||
</app-header-layout>
|
||||
|
||||
<hassio-markdown-dialog
|
||||
title='[[markdownTitle]]'
|
||||
content='[[markdownContent]]'
|
||||
></hassio-markdown-dialog>
|
||||
|
||||
<template is='dom-if' if='[[equals(page, "snapshots")]]'>
|
||||
<hassio-snapshot
|
||||
hass='[[hass]]'
|
||||
snapshot-slug='{{snapshotSlug}}'
|
||||
snapshot-deleted='{{snapshotDeleted}}'
|
||||
></hassio-snapshot>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HassioPagesWithTabs extends window.hassMixins.NavigateMixin(Polymer.Element) {
|
||||
static get is() { return 'hassio-pages-with-tabs'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
showMenu: Boolean,
|
||||
narrow: Boolean,
|
||||
page: String,
|
||||
supervisorInfo: Object,
|
||||
hostInfo: Object,
|
||||
hassInfo: Object,
|
||||
snapshotSlug: String,
|
||||
snapshotDeleted: Boolean,
|
||||
|
||||
markdownTitle: String,
|
||||
markdownContent: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
ready() {
|
||||
super.ready();
|
||||
this.addEventListener('hassio-markdown-dialog', ev => this.openMarkdown(ev));
|
||||
}
|
||||
|
||||
handlePageSelected(ev) {
|
||||
const newPage = ev.detail.item.getAttribute('page-name');
|
||||
if (newPage !== this.page) {
|
||||
this.navigate(`/hassio/${newPage}`);
|
||||
}
|
||||
}
|
||||
|
||||
equals(a, b) {
|
||||
return a === b;
|
||||
}
|
||||
|
||||
showRefreshButton(page) {
|
||||
return page === 'store' || page === 'snapshots';
|
||||
}
|
||||
|
||||
refreshClicked() {
|
||||
if (this.page === 'snapshots') {
|
||||
this.shadowRoot.querySelector('hassio-snapshots').refreshData();
|
||||
} else {
|
||||
this.shadowRoot.querySelector('hassio-addon-store').refreshData();
|
||||
}
|
||||
}
|
||||
|
||||
openMarkdown(ev) {
|
||||
this.setProperties({
|
||||
markdownTitle: ev.detail.title,
|
||||
markdownContent: ev.detail.content,
|
||||
});
|
||||
this.shadowRoot.querySelector('hassio-markdown-dialog').openDialog();
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HassioPagesWithTabs.is, HassioPagesWithTabs);
|
||||
</script>
|
||||
131
hassio/hassio-pages-with-tabs.js
Normal file
131
hassio/hassio-pages-with-tabs.js
Normal file
@ -0,0 +1,131 @@
|
||||
import '@polymer/app-layout/app-header-layout/app-header-layout.js';
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-tabs/paper-tab.js';
|
||||
import '@polymer/paper-tabs/paper-tabs.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../src/components/ha-menu-button.js';
|
||||
import '../src/resources/ha-style.js';
|
||||
import '../src/util/hass-mixins.js';
|
||||
import './addon-store/hassio-addon-store.js';
|
||||
import './dashboard/hassio-dashboard.js';
|
||||
import './hassio-markdown-dialog.js';
|
||||
import './snapshots/hassio-snapshot.js';
|
||||
import './snapshots/hassio-snapshots.js';
|
||||
import './system/hassio-system.js';
|
||||
|
||||
class HassioPagesWithTabs extends window.hassMixins.NavigateMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex iron-positioning ha-style">
|
||||
:host {
|
||||
color: var(--primary-text-color);
|
||||
--paper-card-header-color: var(--primary-text-color);
|
||||
}
|
||||
paper-tabs {
|
||||
margin-left: 12px;
|
||||
--paper-tabs-selection-bar-color: #FFF;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
</style>
|
||||
<app-header-layout has-scrolling-region="">
|
||||
<app-header fixed="" slot="header">
|
||||
<app-toolbar>
|
||||
<ha-menu-button narrow="[[narrow]]" show-menu="[[showMenu]]"></ha-menu-button>
|
||||
<div main-title="">Hass.io</div>
|
||||
<template is="dom-if" if="[[showRefreshButton(page)]]">
|
||||
<paper-icon-button icon="mdi:refresh" on-click="refreshClicked"></paper-icon-button>
|
||||
</template>
|
||||
</app-toolbar>
|
||||
<paper-tabs scrollable="" selected="[[page]]" attr-for-selected="page-name" on-iron-activate="handlePageSelected">
|
||||
<paper-tab page-name="dashboard">Dashboard</paper-tab>
|
||||
<paper-tab page-name="snapshots">Snapshots</paper-tab>
|
||||
<paper-tab page-name="store">Add-on store</paper-tab>
|
||||
<paper-tab page-name="system">System</paper-tab>
|
||||
</paper-tabs>
|
||||
</app-header>
|
||||
<template is="dom-if" if="[[equals(page, "dashboard")]]">
|
||||
<hassio-dashboard hass="[[hass]]" supervisor-info="[[supervisorInfo]]" hass-info="[[hassInfo]]"></hassio-dashboard>
|
||||
</template>
|
||||
<template is="dom-if" if="[[equals(page, "snapshots")]]">
|
||||
<hassio-snapshots hass="[[hass]]" installed-addons="[[supervisorInfo.addons]]" snapshot-slug="{{snapshotSlug}}" snapshot-deleted="{{snapshotDeleted}}"></hassio-snapshots>
|
||||
</template>
|
||||
<template is="dom-if" if="[[equals(page, "store")]]">
|
||||
<hassio-addon-store hass="[[hass]]"></hassio-addon-store>
|
||||
</template>
|
||||
<template is="dom-if" if="[[equals(page, "system")]]">
|
||||
<hassio-system hass="[[hass]]" supervisor-info="[[supervisorInfo]]" host-info="[[hostInfo]]"></hassio-system>
|
||||
</template>
|
||||
</app-header-layout>
|
||||
|
||||
<hassio-markdown-dialog title="[[markdownTitle]]" content="[[markdownContent]]"></hassio-markdown-dialog>
|
||||
|
||||
<template is="dom-if" if="[[equals(page, "snapshots")]]">
|
||||
<hassio-snapshot hass="[[hass]]" snapshot-slug="{{snapshotSlug}}" snapshot-deleted="{{snapshotDeleted}}"></hassio-snapshot>
|
||||
</template>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'hassio-pages-with-tabs'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
showMenu: Boolean,
|
||||
narrow: Boolean,
|
||||
page: String,
|
||||
supervisorInfo: Object,
|
||||
hostInfo: Object,
|
||||
hassInfo: Object,
|
||||
snapshotSlug: String,
|
||||
snapshotDeleted: Boolean,
|
||||
|
||||
markdownTitle: String,
|
||||
markdownContent: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
ready() {
|
||||
super.ready();
|
||||
this.addEventListener('hassio-markdown-dialog', ev => this.openMarkdown(ev));
|
||||
}
|
||||
|
||||
handlePageSelected(ev) {
|
||||
const newPage = ev.detail.item.getAttribute('page-name');
|
||||
if (newPage !== this.page) {
|
||||
this.navigate(`/hassio/${newPage}`);
|
||||
}
|
||||
}
|
||||
|
||||
equals(a, b) {
|
||||
return a === b;
|
||||
}
|
||||
|
||||
showRefreshButton(page) {
|
||||
return page === 'store' || page === 'snapshots';
|
||||
}
|
||||
|
||||
refreshClicked() {
|
||||
if (this.page === 'snapshots') {
|
||||
this.shadowRoot.querySelector('hassio-snapshots').refreshData();
|
||||
} else {
|
||||
this.shadowRoot.querySelector('hassio-addon-store').refreshData();
|
||||
}
|
||||
}
|
||||
|
||||
openMarkdown(ev) {
|
||||
this.setProperties({
|
||||
markdownTitle: ev.detail.title,
|
||||
markdownContent: ev.detail.content,
|
||||
});
|
||||
this.shadowRoot.querySelector('hassio-markdown-dialog').openDialog();
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HassioPagesWithTabs.is, HassioPagesWithTabs);
|
||||
@ -16,20 +16,21 @@
|
||||
<body>
|
||||
<hassio-app></hassio-app>
|
||||
<script>
|
||||
function addScript(src) {
|
||||
var e = document.createElement('script');
|
||||
e.src = src;
|
||||
document.head.appendChild(e);
|
||||
}
|
||||
var webComponentsSupported = (
|
||||
'customElements' in window &&
|
||||
'import' in document.createElement('link') &&
|
||||
'content' in document.createElement('template'));
|
||||
if (!webComponentsSupported) {
|
||||
addScript('/static/webcomponents-lite.js');
|
||||
}
|
||||
function addScript(src) {
|
||||
var e = document.createElement('script');
|
||||
e.src = src;
|
||||
document.head.appendChild(e);
|
||||
}
|
||||
var webComponentsSupported = (
|
||||
'customElements' in window &&
|
||||
'import' in document.createElement('link') &&
|
||||
'content' in document.createElement('template'));
|
||||
if (!webComponentsSupported) {
|
||||
addScript('/static/webcomponents-bundle.js');
|
||||
}
|
||||
</script>
|
||||
<link rel='import' href='./hassio-app.html'>
|
||||
<!-- This is broken. -->
|
||||
<script src="./hassio-app.js"></script>
|
||||
<link rel='import' href='/static/mdi.html' async>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,17 +1,19 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../bower_components/paper-dialog/paper-dialog.html'>
|
||||
<link rel='import' href='../../bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html'>
|
||||
<link rel='import' href='../../bower_components/app-layout/app-toolbar/app-toolbar.html'>
|
||||
<link rel='import' href='../../bower_components/paper-icon-button/paper-icon-button.html'>
|
||||
<link rel='import' href='../../bower_components/paper-checkbox/paper-checkbox.html'>
|
||||
<link rel='import' href='../../bower_components/paper-button/paper-button.html'>
|
||||
<link rel="import" href='../../bower_components/paper-input/paper-input.html'>
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-checkbox/paper-checkbox.js';
|
||||
import '@polymer/paper-dialog-scrollable/paper-dialog-scrollable.js';
|
||||
import '@polymer/paper-dialog/paper-dialog.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../src/resources/ha-style.html'>
|
||||
import '../../src/resources/ha-style.js';
|
||||
|
||||
<dom-module id='hassio-snapshot'>
|
||||
<template>
|
||||
<style include='ha-style-dialog'>
|
||||
class HassioSnapshot extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style-dialog">
|
||||
paper-dialog {
|
||||
min-width: 350px;
|
||||
font-size: 14px;
|
||||
@ -54,72 +56,58 @@
|
||||
color: var(--google-red-500);
|
||||
}
|
||||
</style>
|
||||
<paper-dialog id='dialog' with-backdrop on-iron-overlay-closed='_dialogClosed'>
|
||||
<paper-dialog id="dialog" with-backdrop="" on-iron-overlay-closed="_dialogClosed">
|
||||
<app-toolbar>
|
||||
<paper-icon-button
|
||||
icon='mdi:close'
|
||||
dialog-dismiss
|
||||
></paper-icon-button>
|
||||
<div main-title>[[_computeName(snapshot)]]</div>
|
||||
<paper-icon-button icon="mdi:close" dialog-dismiss=""></paper-icon-button>
|
||||
<div main-title="">[[_computeName(snapshot)]]</div>
|
||||
</app-toolbar>
|
||||
<div class='details'>
|
||||
[[_computeType(snapshot.type)]] ([[_computeSize(snapshot.size)]])<br/>
|
||||
<div class="details">
|
||||
[[_computeType(snapshot.type)]] ([[_computeSize(snapshot.size)]])<br>
|
||||
[[_formatDatetime(snapshot.date)]]
|
||||
</div>
|
||||
<div>Home Assistant:</div>
|
||||
<paper-checkbox checked='{{restoreHass}}'>
|
||||
<paper-checkbox checked="{{restoreHass}}">
|
||||
Home Assistant [[snapshot.homeassistant]]
|
||||
</paper-checkbox>
|
||||
<template is='dom-if' if='[[snapshot.addons.length]]'>
|
||||
<template is="dom-if" if="[[snapshot.addons.length]]">
|
||||
<div>Folders:</div>
|
||||
<template is='dom-repeat' items='[[snapshot.folders]]'>
|
||||
<paper-checkbox checked='{{item.checked}}'>
|
||||
<template is="dom-repeat" items="[[snapshot.folders]]">
|
||||
<paper-checkbox checked="{{item.checked}}">
|
||||
[[item.name]]
|
||||
</paper-checkbox>
|
||||
</template>
|
||||
</template>
|
||||
<template is='dom-if' if='[[snapshot.addons.length]]'>
|
||||
<template is="dom-if" if="[[snapshot.addons.length]]">
|
||||
<div>Add-ons:</div>
|
||||
<paper-dialog-scrollable>
|
||||
<template is='dom-repeat' items='[[snapshot.addons]]' sort='_sortAddons'>
|
||||
<paper-checkbox checked='{{item.checked}}'>
|
||||
<template is="dom-repeat" items="[[snapshot.addons]]" sort="_sortAddons">
|
||||
<paper-checkbox checked="{{item.checked}}">
|
||||
[[item.name]]
|
||||
<span class='details'>([[item.version]])</span>
|
||||
<span class="details">([[item.version]])</span>
|
||||
</paper-checkbox>
|
||||
</template>
|
||||
</paper-dialog-scrollable>
|
||||
</template>
|
||||
<template is='dom-if' if='[[snapshot.protected]]'>
|
||||
<paper-input autofocus label='Password' type='password' value='{{snapshotPassword}}'></paper-input>
|
||||
<template is="dom-if" if="[[snapshot.protected]]">
|
||||
<paper-input autofocus="" label="Password" type="password" value="{{snapshotPassword}}"></paper-input>
|
||||
</template>
|
||||
<template is='dom-if' if='[[error]]'>
|
||||
<p class='error'>Error: [[error]]</p>
|
||||
<template is="dom-if" if="[[error]]">
|
||||
<p class="error">Error: [[error]]</p>
|
||||
</template>
|
||||
<div class='buttons'>
|
||||
<paper-icon-button
|
||||
icon='mdi:delete'
|
||||
on-click='_deleteClicked'
|
||||
class='warning'
|
||||
title='Delete snapshot'
|
||||
></paper-icon-button>
|
||||
<a href='[[_computeDownloadUrl(snapshotSlug)]]' download='[[_computeDownloadName(snapshot)]]'>
|
||||
<paper-icon-button
|
||||
icon='mdi:download'
|
||||
class='download'
|
||||
title='Download snapshot'
|
||||
></paper-icon-button>
|
||||
<div class="buttons">
|
||||
<paper-icon-button icon="mdi:delete" on-click="_deleteClicked" class="warning" title="Delete snapshot"></paper-icon-button>
|
||||
<a href="[[_computeDownloadUrl(snapshotSlug)]]" download="[[_computeDownloadName(snapshot)]]">
|
||||
<paper-icon-button icon="mdi:download" class="download" title="Download snapshot"></paper-icon-button>
|
||||
</a>
|
||||
<paper-button on-click='_partialRestoreClicked'>Restore selected</paper-button>
|
||||
<template is='dom-if' if='[[_isFullSnapshot(snapshot.type)]]'>
|
||||
<paper-button on-click='_fullRestoreClicked'>Wipe & restore</paper-button>
|
||||
<paper-button on-click="_partialRestoreClicked">Restore selected</paper-button>
|
||||
<template is="dom-if" if="[[_isFullSnapshot(snapshot.type)]]">
|
||||
<paper-button on-click="_fullRestoreClicked">Wipe & restore</paper-button>
|
||||
</template>
|
||||
</div>
|
||||
</paper-dialog>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HassioSnapshot extends Polymer.Element {
|
||||
static get is() { return 'hassio-snapshot'; }
|
||||
|
||||
static get properties() {
|
||||
@ -267,4 +255,3 @@ class HassioSnapshot extends Polymer.Element {
|
||||
}
|
||||
}
|
||||
customElements.define(HassioSnapshot.is, HassioSnapshot);
|
||||
</script>
|
||||
@ -1,19 +1,20 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="../../bower_components/paper-input/paper-input.html">
|
||||
<link rel='import' href='../../bower_components/paper-radio-group/paper-radio-group.html'>
|
||||
<link rel='import' href='../../bower_components/paper-radio-button/paper-radio-button.html'>
|
||||
<link rel='import' href='../../bower_components/paper-checkbox/paper-checkbox.html'>
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-checkbox/paper-checkbox.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import '@polymer/paper-radio-button/paper-radio-button.js';
|
||||
import '@polymer/paper-radio-group/paper-radio-group.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
import '../../src/components/hassio-card-content.js';
|
||||
import '../../src/resources/hassio-style.js';
|
||||
import '../../src/util/hass-mixins.js';
|
||||
|
||||
<link rel='import' href='../../src/components/hassio-card-content.html'>
|
||||
<link rel='import' href='../../src/resources/hassio-style.html'>
|
||||
|
||||
<dom-module id="hassio-snapshots">
|
||||
<template>
|
||||
<style include='ha-style hassio-style'>
|
||||
class HassioSnapshots extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style hassio-style">
|
||||
paper-radio-group {
|
||||
display: block;
|
||||
}
|
||||
@ -30,83 +31,75 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
<div class='content'>
|
||||
<div class='card-group'>
|
||||
<div class='title'>
|
||||
<div class="content">
|
||||
<div class="card-group">
|
||||
<div class="title">
|
||||
Create snapshot
|
||||
<div class='description'>
|
||||
<div class="description">
|
||||
Snapshots allow you to easily backup and
|
||||
restore all data of your Hass.io instance.
|
||||
</div>
|
||||
</div>
|
||||
<paper-card>
|
||||
<div class='card-content'>
|
||||
<paper-input autofocus label='Name' value='{{snapshotName}}'></paper-input>
|
||||
<div class="card-content">
|
||||
<paper-input autofocus="" label="Name" value="{{snapshotName}}"></paper-input>
|
||||
Type:
|
||||
<paper-radio-group selected='{{snapshotType}}'>
|
||||
<paper-radio-button name='full'>
|
||||
<paper-radio-group selected="{{snapshotType}}">
|
||||
<paper-radio-button name="full">
|
||||
Full snapshot
|
||||
</paper-radio-button>
|
||||
<paper-radio-button name='partial'>
|
||||
<paper-radio-button name="partial">
|
||||
Partial snapshot
|
||||
</paper-radio-button>
|
||||
</paper-radio-group>
|
||||
<template is='dom-if' if='[[!_fullSelected(snapshotType)]]'>
|
||||
<template is="dom-if" if="[[!_fullSelected(snapshotType)]]">
|
||||
Folders:
|
||||
<template is='dom-repeat' items='[[folderList]]'>
|
||||
<paper-checkbox checked='{{item.checked}}'>
|
||||
<template is="dom-repeat" items="[[folderList]]">
|
||||
<paper-checkbox checked="{{item.checked}}">
|
||||
[[item.name]]
|
||||
</paper-checkbox>
|
||||
</template>
|
||||
Add-ons:
|
||||
<template is='dom-repeat' items='[[addonList]]' sort='_sortAddons'>
|
||||
<paper-checkbox checked='{{item.checked}}'>
|
||||
<template is="dom-repeat" items="[[addonList]]" sort="_sortAddons">
|
||||
<paper-checkbox checked="{{item.checked}}">
|
||||
[[item.name]]
|
||||
</paper-checkbox>
|
||||
</template>
|
||||
</template>
|
||||
Security:
|
||||
<paper-checkbox checked='{{snapshotHasPassword}}'>Password protection</paper-checkbox>
|
||||
<template is='dom-if' if='[[snapshotHasPassword]]'>
|
||||
<paper-input label='Password' type='password' value='{{snapshotPassword}}'></paper-input>
|
||||
<paper-checkbox checked="{{snapshotHasPassword}}">Password protection</paper-checkbox>
|
||||
<template is="dom-if" if="[[snapshotHasPassword]]">
|
||||
<paper-input label="Password" type="password" value="{{snapshotPassword}}"></paper-input>
|
||||
</template>
|
||||
<template is='dom-if' if='[[error]]'>
|
||||
<p class='error'>[[error]]</p>
|
||||
<template is="dom-if" if="[[error]]">
|
||||
<p class="error">[[error]]</p>
|
||||
</template>
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<paper-button disabled='[[creatingSnapshot]]' on-click='_createSnapshot'>Create</paper-button>
|
||||
<div class="card-actions">
|
||||
<paper-button disabled="[[creatingSnapshot]]" on-click="_createSnapshot">Create</paper-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</div>
|
||||
|
||||
<div class='card-group'>
|
||||
<div class='title'>Available snapshots</div>
|
||||
<template is='dom-if' if='[[!snapshots.length]]'>
|
||||
<div class="card-group">
|
||||
<div class="title">Available snapshots</div>
|
||||
<template is="dom-if" if="[[!snapshots.length]]">
|
||||
<paper-card>
|
||||
<div class='card-content'>You don't have any snapshots yet.</div>
|
||||
<div class="card-content">You don't have any snapshots yet.</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
<template is='dom-repeat' items='[[snapshots]]' as='snapshot' sort='_sortSnapshots'>
|
||||
<paper-card class='pointer' on-click='_snapshotClicked'>
|
||||
<div class='card-content'>
|
||||
<hassio-card-content
|
||||
title='[[_computeName(snapshot)]]'
|
||||
description='[[_computeDetails(snapshot)]]'
|
||||
datetime='[[snapshot.date]]'
|
||||
icon='[[_computeIcon(snapshot.type)]]'
|
||||
icon-class='snapshot'
|
||||
></hassio-card-content>
|
||||
<template is="dom-repeat" items="[[snapshots]]" as="snapshot" sort="_sortSnapshots">
|
||||
<paper-card class="pointer" on-click="_snapshotClicked">
|
||||
<div class="card-content">
|
||||
<hassio-card-content title="[[_computeName(snapshot)]]" description="[[_computeDetails(snapshot)]]" datetime="[[snapshot.date]]" icon="[[_computeIcon(snapshot.type)]]" icon-class="snapshot"></hassio-card-content>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HassioSnapshots extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'hassio-snapshots'; }
|
||||
|
||||
static get properties() {
|
||||
@ -269,4 +262,3 @@ class HassioSnapshots extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HassioSnapshots.is, HassioSnapshots);
|
||||
</script>
|
||||
@ -1,12 +1,14 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
<link rel="import" href="../../src/components/buttons/ha-call-api-button.html">
|
||||
import '../../src/components/buttons/ha-call-api-button.js';
|
||||
import '../../src/util/hass-mixins.js';
|
||||
|
||||
<dom-module id="hassio-host-info">
|
||||
<template>
|
||||
class HassioHostInfo extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
paper-card {
|
||||
display: inline-block;
|
||||
@ -43,8 +45,8 @@
|
||||
<paper-card>
|
||||
<div class="card-content">
|
||||
<h2>Host system</h2>
|
||||
<table class='info'>
|
||||
<tr>
|
||||
<table class="info">
|
||||
<tbody><tr>
|
||||
<td>Hostname</td>
|
||||
<td>[[data.hostname]]</td>
|
||||
</tr>
|
||||
@ -56,44 +58,27 @@
|
||||
<td>Deployment</td>
|
||||
<td>[[data.deployment]]</td>
|
||||
</tr>
|
||||
</table>
|
||||
<paper-button
|
||||
raised
|
||||
on-click='_showHardware'
|
||||
class='info'
|
||||
>Show hardware</paper-button>
|
||||
<template is='dom-if' if='[[errors]]'>
|
||||
<div class='errors'>Error: [[errors]]</div>
|
||||
</tbody></table>
|
||||
<paper-button raised="" on-click="_showHardware" class="info">Show hardware</paper-button>
|
||||
<template is="dom-if" if="[[errors]]">
|
||||
<div class="errors">Error: [[errors]]</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<template is='dom-if' if='[[computeRebootAvailable(data)]]'>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path="hassio/host/reboot"
|
||||
>Reboot</ha-call-api-button>
|
||||
<template is="dom-if" if="[[computeRebootAvailable(data)]]">
|
||||
<ha-call-api-button class="warning" hass="[[hass]]" path="hassio/host/reboot">Reboot</ha-call-api-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[computeShutdownAvailable(data)]]'>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path="hassio/host/shutdown"
|
||||
>Shutdown</ha-call-api-button>
|
||||
<template is="dom-if" if="[[computeShutdownAvailable(data)]]">
|
||||
<ha-call-api-button class="warning" hass="[[hass]]" path="hassio/host/shutdown">Shutdown</ha-call-api-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[computeUpdateAvailable(data)]]'>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path="hassio/host/update"
|
||||
>Update</ha-call-api-button>
|
||||
<template is="dom-if" if="[[computeUpdateAvailable(data)]]">
|
||||
<ha-call-api-button hass="[[hass]]" path="hassio/host/update">Update</ha-call-api-button>
|
||||
</template>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HassioHostInfo extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'hassio-host-info'; }
|
||||
|
||||
static get properties() {
|
||||
@ -170,4 +155,3 @@ class HassioHostInfo extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HassioHostInfo.is, HassioHostInfo);
|
||||
</script>
|
||||
@ -1,12 +1,14 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
<link rel="import" href="../../src/components/buttons/ha-call-api-button.html">
|
||||
import '../../src/components/buttons/ha-call-api-button.js';
|
||||
import '../../src/util/hass-mixins.js';
|
||||
|
||||
<dom-module id="hassio-supervisor-info">
|
||||
<template>
|
||||
class HassioSupervisorInfo extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
paper-card {
|
||||
display: inline-block;
|
||||
@ -37,8 +39,8 @@
|
||||
<paper-card>
|
||||
<div class="card-content">
|
||||
<h2>Hass.io supervisor</h2>
|
||||
<table class='info'>
|
||||
<tr>
|
||||
<table class="info">
|
||||
<tbody><tr>
|
||||
<td>Version</td>
|
||||
<td>
|
||||
[[data.version]]
|
||||
@ -48,49 +50,33 @@
|
||||
<td>Latest version</td>
|
||||
<td>[[data.last_version]]</td>
|
||||
</tr>
|
||||
<template is='dom-if' if='[[!_equals(data.channel, "stable")]]'>
|
||||
<template is="dom-if" if="[[!_equals(data.channel, "stable")]]">
|
||||
<tr>
|
||||
<td>Channel</td>
|
||||
<td>[[data.channel]]</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
<template is='dom-if' if='[[errors]]'>
|
||||
<div class='errors'>Error: [[errors]]</div>
|
||||
</tbody></table>
|
||||
<template is="dom-if" if="[[errors]]">
|
||||
<div class="errors">Error: [[errors]]</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path="hassio/supervisor/reload"
|
||||
>Reload</ha-call-api-button>
|
||||
<template is='dom-if' if='[[computeUpdateAvailable(data)]]'>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path="hassio/supervisor/update"
|
||||
>Update</ha-call-api-button>
|
||||
<ha-call-api-button hass="[[hass]]" path="hassio/supervisor/reload">Reload</ha-call-api-button>
|
||||
<template is="dom-if" if="[[computeUpdateAvailable(data)]]">
|
||||
<ha-call-api-button hass="[[hass]]" path="hassio/supervisor/update">Update</ha-call-api-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[_equals(data.channel, "beta")]]'>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path='hassio/supervisor/options'
|
||||
data='[[leaveBeta]]'
|
||||
>Leave beta channel</ha-call-api-button>
|
||||
<template is="dom-if" if="[[_equals(data.channel, "beta")]]">
|
||||
<ha-call-api-button hass="[[hass]]" path="hassio/supervisor/options" data="[[leaveBeta]]">Leave beta channel</ha-call-api-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[_equals(data.channel, "stable")]]'>
|
||||
<paper-button
|
||||
on-click='_joinBeta'
|
||||
class='warning'
|
||||
title='Get beta updates for Home Assistant (RCs), supervisor and host'
|
||||
>Join beta channel</paper-button>
|
||||
<template is="dom-if" if="[[_equals(data.channel, "stable")]]">
|
||||
<paper-button on-click="_joinBeta" class="warning" title="Get beta updates for Home Assistant (RCs), supervisor and host">Join beta channel</paper-button>
|
||||
</template>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HassioSupervisorInfo extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'hassio-supervisor-info'; }
|
||||
|
||||
static get properties() {
|
||||
@ -167,4 +153,3 @@ This inludes beta releases for:
|
||||
}
|
||||
|
||||
customElements.define(HassioSupervisorInfo.is, HassioSupervisorInfo);
|
||||
</script>
|
||||
@ -1,27 +1,27 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel='import' href='../../bower_components/paper-card/paper-card.html'>
|
||||
<link rel='import' href='../../bower_components/paper-button/paper-button.html'>
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id="hassio-supervisor-log">
|
||||
<template>
|
||||
class HassioSupervisorLog extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style">
|
||||
paper-card {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<paper-card>
|
||||
<div class='card-content'>
|
||||
<div class="card-content">
|
||||
<pre>[[log]]</pre>
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<paper-button on-click='refreshTapped'>Refresh</paper-button>
|
||||
<div class="card-actions">
|
||||
<paper-button on-click="refreshTapped">Refresh</paper-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HassioSupervisorLog extends Polymer.Element {
|
||||
static get is() { return 'hassio-supervisor-log'; }
|
||||
|
||||
static get properties() {
|
||||
@ -51,4 +51,3 @@ class HassioSupervisorLog extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HassioSupervisorLog.is, HassioSupervisorLog);
|
||||
</script>
|
||||
@ -1,54 +0,0 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
|
||||
<link rel="import" href="./hassio-host-info.html">
|
||||
<link rel="import" href="./hassio-supervisor-info.html">
|
||||
<link rel='import' href='./hassio-supervisor-log.html'>
|
||||
|
||||
<dom-module id="hassio-system">
|
||||
<template>
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
margin: 4px;
|
||||
}
|
||||
.title {
|
||||
margin-top: 24px;
|
||||
color: var(--primary-text-color);
|
||||
font-size: 2em;
|
||||
padding-left: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
||||
<div class='content'>
|
||||
<div class='title'>Information</div>
|
||||
<hassio-supervisor-info
|
||||
hass='[[hass]]'
|
||||
data='[[supervisorInfo]]'
|
||||
></hassio-supervisor-info>
|
||||
<hassio-host-info
|
||||
hass='[[hass]]'
|
||||
data='[[hostInfo]]'
|
||||
></hassio-host-info>
|
||||
<div class='title'>System log</div>
|
||||
<hassio-supervisor-log
|
||||
hass='[[hass]]'
|
||||
></hassio-supervisor-log>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HassioSystem extends Polymer.Element {
|
||||
static get is() { return 'hassio-system'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
supervisorInfo: Object,
|
||||
hostInfo: Object,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HassioSystem.is, HassioSystem);
|
||||
</script>
|
||||
45
hassio/system/hassio-system.js
Normal file
45
hassio/system/hassio-system.js
Normal file
@ -0,0 +1,45 @@
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import './hassio-host-info.js';
|
||||
import './hassio-supervisor-info.js';
|
||||
import './hassio-supervisor-log.js';
|
||||
|
||||
class HassioSystem extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
margin: 4px;
|
||||
}
|
||||
.title {
|
||||
margin-top: 24px;
|
||||
color: var(--primary-text-color);
|
||||
font-size: 2em;
|
||||
padding-left: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
||||
<div class="content">
|
||||
<div class="title">Information</div>
|
||||
<hassio-supervisor-info hass="[[hass]]" data="[[supervisorInfo]]"></hassio-supervisor-info>
|
||||
<hassio-host-info hass="[[hass]]" data="[[hostInfo]]"></hassio-host-info>
|
||||
<div class="title">System log</div>
|
||||
<hassio-supervisor-log hass="[[hass]]"></hassio-supervisor-log>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'hassio-system'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
supervisorInfo: Object,
|
||||
hostInfo: Object,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HassioSystem.is, HassioSystem);
|
||||
12
index.html
12
index.html
@ -87,27 +87,23 @@
|
||||
if (!webComponentsSupported) {
|
||||
var e = document.createElement('script');
|
||||
e.onerror = initError;
|
||||
e.src = '/static/webcomponents-lite.js';
|
||||
e.src = '/static/webcomponents-bundle.js';
|
||||
if ('import' in document.createElement('link')) {
|
||||
document.write(e.outerHTML);
|
||||
} else {
|
||||
document.head.appendChild(e);
|
||||
}
|
||||
}
|
||||
if ('serviceWorker' in navigator) {
|
||||
/* if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', function () {
|
||||
navigator.serviceWorker.register('/service_worker.js');
|
||||
});
|
||||
}
|
||||
window.CHART_SCRIPT = '/home-assistant-polymer/src/resources/ha-chart-scripts.html';
|
||||
} */
|
||||
</script>
|
||||
<!--<script src='/home-assistant-polymer/build/_demo_data_compiled.js'></script>-->
|
||||
<!--EXTRA_SCRIPTS-->
|
||||
<script src='/home-assistant-polymer/build/core.js'></script>
|
||||
<link rel='import' href='/home-assistant-polymer/src/home-assistant.html' onerror='initError()'>
|
||||
{% if panel_url -%}
|
||||
<link rel='import' href='{{ panel_url }}' async>
|
||||
{% endif -%}
|
||||
<script src='/home-assistant-polymer/build/webpack/app.js'></script>
|
||||
<link rel='import' href='/home-assistant-polymer/hass_frontend/mdi.html' async>
|
||||
{% for extra_url in extra_urls -%}
|
||||
<link rel='import' href='{{ extra_url }}' async>
|
||||
|
||||
91
package.json
91
package.json
@ -1,48 +1,104 @@
|
||||
{
|
||||
"name": "home-assistant-polymer",
|
||||
"version": "1.0.0",
|
||||
"description": "A frontend for Home Assistant using the Polymer framework",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/home-assistant/home-assistant-polymer"
|
||||
},
|
||||
"name": "home-assistant-frontend",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"clean": "rm -rf build/* build-temp/* build-es5/* build-temp-es5/* build-translations/*",
|
||||
"gulp": "gulp",
|
||||
"build": "BUILD_DEV=0 gulp",
|
||||
"build": "BUILD_DEV=0 gulp && NODE_ENV=production webpack -p",
|
||||
"build_demo": "BUILD_DEV=0 BUILD_DEMO=1 gulp",
|
||||
"dev": "npm run gulp ru_all gen-service-worker",
|
||||
"dev-watch": "npm run gulp watch_ru_all gen-service-worker",
|
||||
"dev-es5": "npm run gulp ru_all_es5 gen-service-worker-es5",
|
||||
"dev-watch-es5": "npm run gulp watch_ru_all_es5 gen-service-worker-es5",
|
||||
"lint_js": "eslint src panels js hassio test-mocha --ext js,html",
|
||||
"lint_html": "find src panels hassio -name '*.html' | grep -v hassio/index.html | xargs polymer lint --input",
|
||||
"lint_js": "eslint src panels js hassio test-mocha",
|
||||
"lint_html": "polymer lint",
|
||||
"mocha": "node_modules/.bin/mocha --opts test-mocha/mocha.opts",
|
||||
"test": "npm run lint_js && npm run lint_html && npm run mocha"
|
||||
},
|
||||
"author": "Paulus Schoutsen <Paulus@PaulusSchoutsen.nl> (http://paulusschoutsen.nl)",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@polymer/app-layout": "^3.0.0-pre.18",
|
||||
"@polymer/app-localize-behavior": "^3.0.0-pre.18",
|
||||
"@polymer/app-route": "^3.0.0-pre.18",
|
||||
"@polymer/app-storage": "^3.0.0-pre.18",
|
||||
"@polymer/font-roboto": "^3.0.0-pre.18",
|
||||
"@polymer/font-roboto-local": "^3.0.0-pre.19",
|
||||
"@polymer/iron-autogrow-textarea": "^3.0.0-pre.18",
|
||||
"@polymer/iron-flex-layout": "^3.0.0-pre.18",
|
||||
"@polymer/iron-icon": "^3.0.0-pre.18",
|
||||
"@polymer/iron-iconset-svg": "^3.0.0-pre.19",
|
||||
"@polymer/iron-image": "^3.0.0-pre.18",
|
||||
"@polymer/iron-input": "^3.0.0-pre.18",
|
||||
"@polymer/iron-label": "^3.0.0-pre.18",
|
||||
"@polymer/iron-media-query": "^3.0.0-pre.18",
|
||||
"@polymer/iron-pages": "^3.0.0-pre.18",
|
||||
"@polymer/iron-resizable-behavior": "^3.0.0-pre.19",
|
||||
"@polymer/neon-animation": "^3.0.0-pre.18",
|
||||
"@polymer/paper-button": "^3.0.0-pre.18",
|
||||
"@polymer/paper-card": "^3.0.0-pre.18",
|
||||
"@polymer/paper-checkbox": "^3.0.0-pre.18",
|
||||
"@polymer/paper-dialog": "^3.0.0-pre.18",
|
||||
"@polymer/paper-dialog-behavior": "^3.0.0-pre.19",
|
||||
"@polymer/paper-dialog-scrollable": "^3.0.0-pre.18",
|
||||
"@polymer/paper-drawer-panel": "^3.0.0-pre.18",
|
||||
"@polymer/paper-dropdown-menu": "^3.0.0-pre.18",
|
||||
"@polymer/paper-fab": "^3.0.0-pre.18",
|
||||
"@polymer/paper-icon-button": "^3.0.0-pre.18",
|
||||
"@polymer/paper-input": "^3.0.0-pre.18",
|
||||
"@polymer/paper-item": "^3.0.0-pre.18",
|
||||
"@polymer/paper-listbox": "^3.0.0-pre.18",
|
||||
"@polymer/paper-menu-button": "^3.0.0-pre.18",
|
||||
"@polymer/paper-progress": "^3.0.0-pre.18",
|
||||
"@polymer/paper-radio-button": "^3.0.0-pre.18",
|
||||
"@polymer/paper-radio-group": "^3.0.0-pre.18",
|
||||
"@polymer/paper-ripple": "^3.0.0-pre.19",
|
||||
"@polymer/paper-scroll-header-panel": "^3.0.0-pre.18",
|
||||
"@polymer/paper-slider": "^3.0.0-pre.18",
|
||||
"@polymer/paper-spinner": "^3.0.0-pre.18",
|
||||
"@polymer/paper-styles": "^3.0.0-pre.18",
|
||||
"@polymer/paper-tabs": "^3.0.0-pre.18",
|
||||
"@polymer/paper-toast": "^3.0.0-pre.18",
|
||||
"@polymer/paper-toggle-button": "^3.0.0-pre.18",
|
||||
"@polymer/polymer": "^3.0.0",
|
||||
"@vaadin/vaadin-combo-box": "4.0.1-pre.1",
|
||||
"@vaadin/vaadin-date-picker": "3.0.0-pre.3",
|
||||
"@webcomponents/shadycss": "^1.0.0",
|
||||
"@webcomponents/webcomponentsjs": "^2.0.0",
|
||||
"chart.js": "~2.7.2",
|
||||
"chartjs-chart-timeline": "0.2.0",
|
||||
"es6-object-assign": "^1.1.0",
|
||||
"fecha": "^2.3.3",
|
||||
"home-assistant-js-websocket": "^1.2.1",
|
||||
"intl-messageformat": "^2.2.0",
|
||||
"leaflet": "^1.0.2",
|
||||
"marked": "^0.3.19",
|
||||
"mdn-polyfills": "^5.5.0",
|
||||
"moment": "^2.20.0",
|
||||
"preact": "^8.2.6",
|
||||
"unfetch": "^3.0.0"
|
||||
"unfetch": "^3.0.0",
|
||||
"web-animations-js": "^2.3.1",
|
||||
"xss": "^0.3.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-eslint": "^8.2.3",
|
||||
"babel-loader": "^7.1.4",
|
||||
"babel-plugin-external-helpers": "^6.22.0",
|
||||
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
||||
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
||||
"babel-plugin-transform-react-jsx": "^6.24.1",
|
||||
"babel-preset-env": "^1.6.1",
|
||||
"bower": "^1.8.2",
|
||||
"chai": "^4.1.2",
|
||||
"css-slam": "^2.0.2",
|
||||
"del": "^3.0.0",
|
||||
"eslint": "^4.11.0",
|
||||
"eslint-config-airbnb-base": "^12.1.0",
|
||||
"eslint-plugin-html": "^4.0.0",
|
||||
"eslint-plugin-import": "^2.8.0",
|
||||
"eslint-plugin-react": "^7.0.0",
|
||||
"gulp": "^3.9.1",
|
||||
@ -71,7 +127,7 @@
|
||||
"polymer-analyzer": "^2.3.0",
|
||||
"polymer-build": "^2.1.0",
|
||||
"polymer-bundler": "^3.1.0",
|
||||
"polymer-cli": "^1.5.6",
|
||||
"polymer-cli": "^1.7.0",
|
||||
"pump": "^3.0.0",
|
||||
"reify": "^0.14.1",
|
||||
"require-dir": "^1.0.0",
|
||||
@ -86,6 +142,19 @@
|
||||
"sw-precache": "^5.2.0",
|
||||
"uglify-es": "^3.1.9",
|
||||
"uglify-js": "^3.1.9",
|
||||
"web-component-tester": "^6.4.0"
|
||||
}
|
||||
"wct-browser-legacy": "^1.0.0",
|
||||
"web-component-tester": "^6.6.0",
|
||||
"webpack": "^4.8.1",
|
||||
"webpack-cli": "^2.1.3"
|
||||
},
|
||||
"resolutions": {
|
||||
"inherits": "2.0.3",
|
||||
"samsam": "1.1.3",
|
||||
"supports-color": "3.1.2",
|
||||
"type-detect": "1.0.0",
|
||||
"@webcomponents/webcomponentsjs": "2.0.0-beta.2",
|
||||
"@vaadin/vaadin-overlay": "3.0.2-pre.2",
|
||||
"fecha": "https://github.com/balloob/fecha/archive/51d14fd0eb4781e2ecf265d1c3080706259133b5.tar.gz"
|
||||
},
|
||||
"main": "src/home-assistant.js"
|
||||
}
|
||||
|
||||
@ -1,32 +1,38 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-header/app-header.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item.html">
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item-body.html">
|
||||
<link rel="import" href="../../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-input/paper-input.html">
|
||||
<link rel="import" href="../../../bower_components/paper-input/paper-textarea.html">
|
||||
<link rel="import" href="../../../bower_components/paper-radio-button/paper-radio-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-radio-group/paper-radio-group.html">
|
||||
<link rel="import" href="../../../bower_components/paper-dropdown-menu/paper-dropdown-menu-light.html">
|
||||
<link rel="import" href="../../../bower_components/paper-listbox/paper-listbox.html">
|
||||
<link rel="import" href="../../../bower_components/paper-menu-button/paper-menu-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-fab/paper-fab.html">
|
||||
<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/iron-autogrow-textarea/iron-autogrow-textarea.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu-light.js';
|
||||
import '@polymer/paper-fab/paper-fab.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import '@polymer/paper-input/paper-textarea.js';
|
||||
import '@polymer/paper-item/paper-item-body.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import '@polymer/paper-menu-button/paper-menu-button.js';
|
||||
import '@polymer/paper-radio-button/paper-radio-button.js';
|
||||
import '@polymer/paper-radio-group/paper-radio-group.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../../src/components/entity/ha-entity-picker.html'>
|
||||
<link rel='import' href='../../../src/components/ha-combo-box.html'>
|
||||
<link rel='import' href='../../../src/components/ha-markdown.html'>
|
||||
<link rel='import' href='../../../src/components/ha-service-picker.html'>
|
||||
<link rel='import' href='../../../src/layouts/ha-app-layout.html'>
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
import '../../../src/components/entity/ha-entity-picker.js';
|
||||
import '../../../src/components/ha-combo-box.js';
|
||||
import '../../../src/components/ha-markdown.js';
|
||||
import '../../../src/components/ha-service-picker.js';
|
||||
import '../../../src/layouts/ha-app-layout.js';
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
import '../ha-config-js.js';
|
||||
import '../ha-config-section.js';
|
||||
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
<link rel="import" href="../ha-config-js.html">
|
||||
|
||||
<dom-module id="ha-automation-editor">
|
||||
<template>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaAutomationEditor extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style">
|
||||
.errors {
|
||||
padding: 20px;
|
||||
@ -83,42 +89,25 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<ha-app-layout has-scrolling-region>
|
||||
<app-header slot="header" fixed>
|
||||
<ha-app-layout has-scrolling-region="">
|
||||
<app-header slot="header" fixed="">
|
||||
<app-toolbar>
|
||||
<paper-icon-button
|
||||
icon='mdi:arrow-left'
|
||||
on-click='backTapped'
|
||||
></paper-icon-button>
|
||||
<div main-title>[[name]]</div>
|
||||
<paper-icon-button icon="mdi:arrow-left" on-click="backTapped"></paper-icon-button>
|
||||
<div main-title="">[[name]]</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<div class='content'>
|
||||
<template is='dom-if' if='[[errors]]'>
|
||||
<div class='errors'>[[errors]]</div>
|
||||
<div class="content">
|
||||
<template is="dom-if" if="[[errors]]">
|
||||
<div class="errors">[[errors]]</div>
|
||||
</template>
|
||||
<div id='root'></div>
|
||||
<div id="root"></div>
|
||||
</div>
|
||||
<paper-fab slot="fab"
|
||||
is-wide$='[[isWide]]'
|
||||
dirty$='[[dirty]]'
|
||||
icon='mdi:content-save'
|
||||
title="[[localize('ui.panel.config.automation.editor.save')]]"
|
||||
on-click='saveAutomation'
|
||||
></paper-fab>
|
||||
<paper-fab slot="fab" is-wide\$="[[isWide]]" dirty\$="[[dirty]]" icon="mdi:content-save" title="[[localize('ui.panel.config.automation.editor.save')]]" on-click="saveAutomation"></paper-fab>
|
||||
</ha-app-layout>
|
||||
`;
|
||||
}
|
||||
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaAutomationEditor extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(Polymer.Element)) {
|
||||
static get is() { return 'ha-automation-editor'; }
|
||||
|
||||
static get properties() {
|
||||
@ -296,4 +285,3 @@ class HaAutomationEditor extends
|
||||
}
|
||||
|
||||
customElements.define(HaAutomationEditor.is, HaAutomationEditor);
|
||||
</script>
|
||||
@ -1,20 +1,26 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-header/app-header.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item.html">
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item-body.html">
|
||||
<link rel="import" href="../../../bower_components/paper-fab/paper-fab.html">
|
||||
<link rel="import" href="../../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-fab/paper-fab.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-item/paper-item-body.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../../src/layouts/ha-app-layout.html'>
|
||||
<link rel='import' href='../../../src/components/ha-markdown.html'>
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
import '../../../src/components/ha-markdown.js';
|
||||
import '../../../src/layouts/ha-app-layout.js';
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
import '../ha-config-section.js';
|
||||
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
|
||||
<dom-module id="ha-automation-picker">
|
||||
<template>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaAutomationPicker extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.NavigateMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style">
|
||||
:host {
|
||||
display: block;
|
||||
@ -45,61 +51,43 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<ha-app-layout has-scrolling-region>
|
||||
<app-header slot="header" fixed>
|
||||
<ha-app-layout has-scrolling-region="">
|
||||
<app-header slot="header" fixed="">
|
||||
<app-toolbar>
|
||||
<paper-icon-button
|
||||
icon='mdi:arrow-left'
|
||||
on-click='_backTapped'
|
||||
></paper-icon-button>
|
||||
<div main-title>[[localize('ui.panel.config.automation.caption')]]</div>
|
||||
<paper-icon-button icon="mdi:arrow-left" on-click="_backTapped"></paper-icon-button>
|
||||
<div main-title="">[[localize('ui.panel.config.automation.caption')]]</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<ha-config-section
|
||||
is-wide='[[isWide]]'
|
||||
>
|
||||
<div slot='header'>[[localize('ui.panel.config.automation.picker.header')]]</div>
|
||||
<div slot='introduction'>
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<div slot="header">[[localize('ui.panel.config.automation.picker.header')]]</div>
|
||||
<div slot="introduction">
|
||||
<ha-markdown content="[[localize('ui.panel.config.automation.picker.introduction')]]"></ha-markdown>
|
||||
</div>
|
||||
|
||||
<paper-card heading="[[localize('ui.panel.config.automation.picker.pick_automation')]]">
|
||||
<template is='dom-if' if='[[!automations.length]]'>
|
||||
<div class='card-content'>
|
||||
<template is="dom-if" if="[[!automations.length]]">
|
||||
<div class="card-content">
|
||||
<p>[[localize('ui.panel.config.automation.picker.no_automations')]]</p>
|
||||
</div>
|
||||
</template>
|
||||
<template is='dom-repeat' items='[[automations]]' as='automation'>
|
||||
<template is="dom-repeat" items="[[automations]]" as="automation">
|
||||
<paper-item>
|
||||
<paper-item-body two-line on-click='automationTapped'>
|
||||
<paper-item-body two-line="" on-click="automationTapped">
|
||||
<div>[[computeName(automation)]]</div>
|
||||
<div secondary>[[computeDescription(automation)]]</div>
|
||||
<div secondary="">[[computeDescription(automation)]]</div>
|
||||
</paper-item-body>
|
||||
<iron-icon icon='mdi:chevron-right'></iron-icon>
|
||||
<iron-icon icon="mdi:chevron-right"></iron-icon>
|
||||
</paper-item>
|
||||
</template>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
|
||||
<paper-fab slot="fab"
|
||||
is-wide$='[[isWide]]'
|
||||
icon='mdi:plus'
|
||||
title="[[localize('ui.panel.config.automation.picker.add_automation')]]"
|
||||
on-click='addAutomation'
|
||||
></paper-fab>
|
||||
<paper-fab slot="fab" is-wide\$="[[isWide]]" icon="mdi:plus" title="[[localize('ui.panel.config.automation.picker.add_automation')]]" on-click="addAutomation"></paper-fab>
|
||||
</ha-app-layout>
|
||||
`;
|
||||
}
|
||||
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaAutomationPicker extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.NavigateMixin(Polymer.Element)) {
|
||||
static get is() { return 'ha-automation-picker'; }
|
||||
|
||||
static get properties() {
|
||||
@ -151,4 +139,3 @@ class HaAutomationPicker extends
|
||||
}
|
||||
|
||||
customElements.define(HaAutomationPicker.is, HaAutomationPicker);
|
||||
</script>
|
||||
@ -1,52 +1,32 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel='import' href='../../../bower_components/app-route/app-route.html'>
|
||||
import '@polymer/app-route/app-route.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="./ha-automation-picker.html">
|
||||
<link rel="import" href="./ha-automation-editor.html">
|
||||
import './ha-automation-editor.js';
|
||||
import './ha-automation-picker.js';
|
||||
|
||||
<dom-module id="ha-config-automation">
|
||||
<template>
|
||||
class HaConfigAutomation extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
ha-automation-picker,
|
||||
ha-automation-editor {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
<app-route
|
||||
route='[[route]]'
|
||||
pattern='/automation/edit/:automation'
|
||||
data="{{_routeData}}"
|
||||
active="{{_edittingAutomation}}"
|
||||
></app-route>
|
||||
<app-route
|
||||
route='[[route]]'
|
||||
pattern='/automation/new'
|
||||
active="{{_creatingNew}}"
|
||||
></app-route>
|
||||
<app-route route="[[route]]" pattern="/automation/edit/:automation" data="{{_routeData}}" active="{{_edittingAutomation}}"></app-route>
|
||||
<app-route route="[[route]]" pattern="/automation/new" active="{{_creatingNew}}"></app-route>
|
||||
|
||||
<template is='dom-if' if='[[!showEditor]]'>
|
||||
<ha-automation-picker
|
||||
hass='[[hass]]'
|
||||
narrow='[[narrow]]'
|
||||
show-menu='[[showMenu]]'
|
||||
automations='[[automations]]'
|
||||
is-wide='[[isWide]]'
|
||||
></ha-automation-picker>
|
||||
<template is="dom-if" if="[[!showEditor]]">
|
||||
<ha-automation-picker hass="[[hass]]" narrow="[[narrow]]" show-menu="[[showMenu]]" automations="[[automations]]" is-wide="[[isWide]]"></ha-automation-picker>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[showEditor]]' restamp>
|
||||
<ha-automation-editor
|
||||
hass='[[hass]]'
|
||||
automation='[[automation]]'
|
||||
is-wide='[[isWide]]'
|
||||
creating-new='[[_creatingNew]]'
|
||||
></ha-automation-editor>
|
||||
<template is="dom-if" if="[[showEditor]]" restamp="">
|
||||
<ha-automation-editor hass="[[hass]]" automation="[[automation]]" is-wide="[[isWide]]" creating-new="[[_creatingNew]]"></ha-automation-editor>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaConfigAutomation extends Polymer.Element {
|
||||
static get is() { return 'ha-config-automation'; }
|
||||
|
||||
static get properties() {
|
||||
@ -124,4 +104,3 @@ class HaConfigAutomation extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HaConfigAutomation.is, HaConfigAutomation);
|
||||
</script>
|
||||
@ -1,17 +1,18 @@
|
||||
<link rel="import" href='../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href='../../../bower_components/paper-card/paper-card.html'>
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item-body.html">
|
||||
<link rel="import" href='../../../bower_components/paper-button/paper-button.html'>
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-item/paper-item-body.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../../src/layouts/hass-subpage.html">
|
||||
<link rel="import" href="../../../src/util/hass-mixins.html">
|
||||
<link rel="import" href='../../../src/resources/ha-style.html'>
|
||||
<link rel="import" href='../../../src/components/buttons/ha-call-api-button.html'>
|
||||
import '../../../src/components/buttons/ha-call-api-button.js';
|
||||
import '../../../src/layouts/hass-subpage.js';
|
||||
import '../../../src/resources/ha-style.js';
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
import '../ha-config-section.js';
|
||||
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
|
||||
<dom-module id="ha-config-cloud-account">
|
||||
<template>
|
||||
class HaConfigCloudAccount extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
padding-bottom: 24px;
|
||||
@ -49,59 +50,53 @@
|
||||
color: var(--primary-color);
|
||||
}
|
||||
</style>
|
||||
<hass-subpage header='Cloud Account'>
|
||||
<div class='content'>
|
||||
<ha-config-section
|
||||
is-wide='[[isWide]]'
|
||||
>
|
||||
<span slot='header'>Home Assistant Cloud</span>
|
||||
<span slot='introduction'>
|
||||
<hass-subpage header="Cloud Account">
|
||||
<div class="content">
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<span slot="header">Home Assistant Cloud</span>
|
||||
<span slot="introduction">
|
||||
Thank you for supporting Home Assistant. It's because of people like you that we are able to run this project and make a great home automation experience for everyone. Thank you!
|
||||
</span>
|
||||
|
||||
<paper-card heading='Account'>
|
||||
<div class='account-row'>
|
||||
<paper-item-body two-line>
|
||||
<paper-card heading="Account">
|
||||
<div class="account-row">
|
||||
<paper-item-body two-line="">
|
||||
[[account.email]]
|
||||
<div secondary class='wrap'>
|
||||
<span class='nowrap'>Subscription expires on </span>
|
||||
<span class='nowrap'>[[_formatExpiration(account.sub_exp)]]</span>
|
||||
<div secondary="" class="wrap">
|
||||
<span class="nowrap">Subscription expires on </span>
|
||||
<span class="nowrap">[[_formatExpiration(account.sub_exp)]]</span>
|
||||
</div>
|
||||
</paper-item-body>
|
||||
<paper-button
|
||||
on-click='handleLogout'
|
||||
>Sign out</paper-button>
|
||||
<paper-button on-click="handleLogout">Sign out</paper-button>
|
||||
</div>
|
||||
|
||||
<div class='account-row'>
|
||||
<div class="account-row">
|
||||
<paper-item-body>
|
||||
Cloud connection status
|
||||
</paper-item-body>
|
||||
<div class='status'>[[account.cloud]]</div>
|
||||
<div class="status">[[account.cloud]]</div>
|
||||
</div>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
|
||||
<ha-config-section
|
||||
is-wide='[[isWide]]'
|
||||
>
|
||||
<span slot='header'>Integrations</span>
|
||||
<span slot='introduction'>
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<span slot="header">Integrations</span>
|
||||
<span slot="introduction">
|
||||
Integrations for Home Assistant Cloud allow you to connect with services in the cloud
|
||||
without having to expose your Home Assistant instance publicly on the internet.
|
||||
</span>
|
||||
|
||||
<paper-card heading='Alexa'>
|
||||
<paper-card heading="Alexa">
|
||||
<div class="card-content">
|
||||
With the Alexa integration for Home Assistant Cloud you'll be able to control all your Home Assistant devices via any Alexa-enabled device.
|
||||
<ul>
|
||||
<li>
|
||||
<a href='https://alexa.amazon.com/spa/index.html#skills/dp/B0772J1QKB/?ref=skill_dsk_skb_sr_2' target='_blank'>
|
||||
<a href="https://alexa.amazon.com/spa/index.html#skills/dp/B0772J1QKB/?ref=skill_dsk_skb_sr_2" target="_blank">
|
||||
Activate the Home Assistant skill for Alexa
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href='https://www.home-assistant.io/cloud/alexa/' target='_blank'>
|
||||
<a href="https://www.home-assistant.io/cloud/alexa/" target="_blank">
|
||||
Config documentation
|
||||
</a>
|
||||
</li>
|
||||
@ -110,38 +105,33 @@
|
||||
</div>
|
||||
</paper-card>
|
||||
|
||||
<paper-card heading='Google Assistant'>
|
||||
<paper-card heading="Google Assistant">
|
||||
<div class="card-content">
|
||||
With the Google Assistant integration for Home Assistant Cloud you'll be able to control all your Home Assistant devices via any Google Assistant-enabled device.
|
||||
<ul>
|
||||
<li>
|
||||
<a href='https://assistant.google.com/services/a/uid/00000091fd5fb875' target='_blank'>
|
||||
<a href="https://assistant.google.com/services/a/uid/00000091fd5fb875" target="_blank">
|
||||
Activate the Home Assistant skill for Google Assistant
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href='https://www.home-assistant.io/cloud/google_assistant/' target='_blank'>
|
||||
<a href="https://www.home-assistant.io/cloud/google_assistant/" target="_blank">
|
||||
Config documentation
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<p><em>This integration requires a Google Assistant-enabled device like the Google Home or Android phone.</em></p>
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path='cloud/google_actions/sync'
|
||||
>Sync devices</ha-call-api-button>
|
||||
<div class="card-actions">
|
||||
<ha-call-api-button hass="[[hass]]" path="cloud/google_actions/sync">Sync devices</ha-call-api-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
</div>
|
||||
</hass-subpage>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaConfigCloudAccount extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-config-cloud-account'; }
|
||||
|
||||
static get properties() {
|
||||
@ -182,4 +172,3 @@ class HaConfigCloudAccount extends window.hassMixins.EventsMixin(Polymer.Element
|
||||
}
|
||||
|
||||
customElements.define(HaConfigCloudAccount.is, HaConfigCloudAccount);
|
||||
</script>
|
||||
@ -1,14 +1,16 @@
|
||||
<link rel="import" href='../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href='../../../bower_components/paper-card/paper-card.html'>
|
||||
<link rel="import" href='../../../bower_components/paper-input/paper-input.html'>
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../../src/layouts/hass-subpage.html">
|
||||
<link rel="import" href="../../../src/util/hass-mixins.html">
|
||||
<link rel="import" href='../../../src/resources/ha-style.html'>
|
||||
<link rel="import" href='../../../src/components/buttons/ha-progress-button.html'>
|
||||
import '../../../src/components/buttons/ha-progress-button.js';
|
||||
import '../../../src/layouts/hass-subpage.js';
|
||||
import '../../../src/resources/ha-style.js';
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
|
||||
<dom-module id="ha-config-cloud-forgot-password">
|
||||
<template>
|
||||
class HaConfigCloudForgotPassword extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
padding-bottom: 24px;
|
||||
@ -40,38 +42,25 @@
|
||||
}
|
||||
</style>
|
||||
<hass-subpage header="Forgot Password">
|
||||
<div class='content'>
|
||||
<div class="content">
|
||||
<paper-card>
|
||||
<div class='card-content'>
|
||||
<div class="card-content">
|
||||
<h1>Forgot your password?</h1>
|
||||
<p>
|
||||
Enter your email address and we will send you a link to reset your password.
|
||||
</p>
|
||||
<div class='error' hidden$='[[!_error]]'>[[_error]]</div>
|
||||
<paper-input
|
||||
autofocus
|
||||
id='email'
|
||||
label='E-mail'
|
||||
value='{{email}}'
|
||||
type='email'
|
||||
on-keydown='_keyDown'
|
||||
error-message='Invalid email'
|
||||
></paper-input>
|
||||
<div class="error" hidden\$="[[!_error]]">[[_error]]</div>
|
||||
<paper-input autofocus="" id="email" label="E-mail" value="{{email}}" type="email" on-keydown="_keyDown" error-message="Invalid email"></paper-input>
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<ha-progress-button
|
||||
on-click='_handleEmailPasswordReset'
|
||||
progress='[[_requestInProgress]]'
|
||||
>Send reset email</ha-progress-button>
|
||||
<div class="card-actions">
|
||||
<ha-progress-button on-click="_handleEmailPasswordReset" progress="[[_requestInProgress]]">Send reset email</ha-progress-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</div>
|
||||
</hass-subpage>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaConfigCloudForgotPassword extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-config-cloud-forgot-password'; }
|
||||
|
||||
static get properties() {
|
||||
@ -131,4 +120,3 @@ class HaConfigCloudForgotPassword extends window.hassMixins.EventsMixin(Polymer.
|
||||
}
|
||||
|
||||
customElements.define(HaConfigCloudForgotPassword.is, HaConfigCloudForgotPassword);
|
||||
</script>
|
||||
@ -1,21 +1,23 @@
|
||||
<link rel="import" href='../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href='../../../bower_components/paper-card/paper-card.html'>
|
||||
<link rel="import" href='../../../bower_components/paper-button/paper-button.html'>
|
||||
<link rel="import" href='../../../bower_components/paper-icon-button/paper-icon-button.html'>
|
||||
<link rel="import" href='../../../bower_components/paper-input/paper-input.html'>
|
||||
<link rel="import" href='../../../bower_components/paper-ripple/paper-ripple.html'>
|
||||
<link rel="import" href='../../../bower_components/paper-item/paper-item.html'>
|
||||
<link rel="import" href='../../../bower_components/paper-item/paper-item-body.html'>
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import '@polymer/paper-item/paper-item-body.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-ripple/paper-ripple.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../../src/layouts/hass-subpage.html">
|
||||
<link rel="import" href="../../../src/util/hass-mixins.html">
|
||||
<link rel="import" href='../../../src/resources/ha-style.html'>
|
||||
<link rel="import" href='../../../src/components/buttons/ha-progress-button.html'>
|
||||
import '../../../src/components/buttons/ha-progress-button.js';
|
||||
import '../../../src/layouts/hass-subpage.js';
|
||||
import '../../../src/resources/ha-style.js';
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
import '../ha-config-section.js';
|
||||
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
|
||||
<dom-module id="ha-config-cloud-login">
|
||||
<template>
|
||||
class HaConfigCloudLogin extends
|
||||
window.hassMixins.NavigateMixin(window.hassMixins.EventsMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
padding-bottom: 24px;
|
||||
@ -57,80 +59,51 @@
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
</style>
|
||||
<hass-subpage header='Cloud Login'>
|
||||
<div class='content'>
|
||||
<ha-config-section
|
||||
is-wide='[[isWide]]'
|
||||
>
|
||||
<span slot='header'>Home Assistant Cloud</span>
|
||||
<span slot='introduction'>
|
||||
<hass-subpage header="Cloud Login">
|
||||
<div class="content">
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<span slot="header">Home Assistant Cloud</span>
|
||||
<span slot="introduction">
|
||||
The Home Assistant Cloud allows your local Home Assistant instance to connect with cloud-only services like Amazon Alexa.
|
||||
<p><a href='https://www.home-assistant.io/components/cloud/' target='_blank'>Learn more</a></p>
|
||||
<p><a href="https://www.home-assistant.io/components/cloud/" target="_blank">Learn more</a></p>
|
||||
</span>
|
||||
|
||||
<paper-card hidden$='[[!flashMessage]]'>
|
||||
<div class='card-content flash-msg'>
|
||||
<paper-card hidden\$="[[!flashMessage]]">
|
||||
<div class="card-content flash-msg">
|
||||
[[flashMessage]]
|
||||
<paper-icon-button
|
||||
icon='mdi:close'
|
||||
on-click='_dismissFlash'
|
||||
>Dismiss</paper-icon-button>
|
||||
<paper-ripple id='flashRipple' noink></paper-ripple>
|
||||
<paper-icon-button icon="mdi:close" on-click="_dismissFlash">Dismiss</paper-icon-button>
|
||||
<paper-ripple id="flashRipple" noink=""></paper-ripple>
|
||||
</div>
|
||||
</paper-card>
|
||||
|
||||
<paper-card>
|
||||
<div class='card-content'>
|
||||
<div class="card-content">
|
||||
<h1>Sign In</h1>
|
||||
<div class='error' hidden$='[[!_error]]'>[[_error]]</div>
|
||||
<paper-input
|
||||
label='Email'
|
||||
id='email'
|
||||
type='email'
|
||||
value='{{email}}'
|
||||
on-keydown='_keyDown'
|
||||
error-message='Invalid email'
|
||||
></paper-input>
|
||||
<paper-input
|
||||
id='password'
|
||||
label='Password'
|
||||
value='{{_password}}'
|
||||
type='password'
|
||||
on-keydown='_keyDown'
|
||||
error-message='Passwords are at least 8 characters'
|
||||
></paper-input>
|
||||
<div class="error" hidden\$="[[!_error]]">[[_error]]</div>
|
||||
<paper-input label="Email" id="email" type="email" value="{{email}}" on-keydown="_keyDown" error-message="Invalid email"></paper-input>
|
||||
<paper-input id="password" label="Password" value="{{_password}}" type="password" on-keydown="_keyDown" error-message="Passwords are at least 8 characters"></paper-input>
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<ha-progress-button
|
||||
on-click='_handleLogin'
|
||||
progress='[[_requestInProgress]]'
|
||||
>Sign in</ha-progress-button>
|
||||
<button
|
||||
class='link'
|
||||
hidden='[[_requestInProgress]]'
|
||||
on-click='_handleForgotPassword'
|
||||
>forgot password?</button>
|
||||
<div class="card-actions">
|
||||
<ha-progress-button on-click="_handleLogin" progress="[[_requestInProgress]]">Sign in</ha-progress-button>
|
||||
<button class="link" hidden="[[_requestInProgress]]" on-click="_handleForgotPassword">forgot password?</button>
|
||||
</div>
|
||||
</paper-card>
|
||||
|
||||
<paper-card>
|
||||
<paper-item on-click='_handleRegister'>
|
||||
<paper-item-body two-line>
|
||||
<paper-item on-click="_handleRegister">
|
||||
<paper-item-body two-line="">
|
||||
Create Account
|
||||
<div secondary>Get up and running quickly.</div>
|
||||
<div secondary="">Get up and running quickly.</div>
|
||||
</paper-item-body>
|
||||
<iron-icon icon='mdi:chevron-right'></iron-icon>
|
||||
<iron-icon icon="mdi:chevron-right"></iron-icon>
|
||||
</paper-item>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
</div>
|
||||
</hass-subpage>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaConfigCloudLogin extends
|
||||
window.hassMixins.NavigateMixin(window.hassMixins.EventsMixin(Polymer.Element)) {
|
||||
static get is() { return 'ha-config-cloud-login'; }
|
||||
|
||||
static get properties() {
|
||||
@ -260,4 +233,3 @@ class HaConfigCloudLogin extends
|
||||
}
|
||||
|
||||
customElements.define(HaConfigCloudLogin.is, HaConfigCloudLogin);
|
||||
</script>
|
||||
@ -1,16 +1,17 @@
|
||||
<link rel="import" href='../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href='../../../bower_components/paper-card/paper-card.html'>
|
||||
<link rel="import" href='../../../bower_components/paper-input/paper-input.html'>
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../../src/layouts/hass-subpage.html">
|
||||
<link rel="import" href="../../../src/util/hass-mixins.html">
|
||||
<link rel="import" href='../../../src/resources/ha-style.html'>
|
||||
<link rel="import" href='../../../src/components/buttons/ha-progress-button.html'>
|
||||
import '../../../src/components/buttons/ha-progress-button.js';
|
||||
import '../../../src/layouts/hass-subpage.js';
|
||||
import '../../../src/resources/ha-style.js';
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
import '../ha-config-section.js';
|
||||
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
|
||||
<dom-module id="ha-config-cloud-register">
|
||||
<template>
|
||||
class HaConfigCloudRegister extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
a {
|
||||
color: var(--primary-color);
|
||||
@ -41,67 +42,41 @@
|
||||
}
|
||||
</style>
|
||||
<hass-subpage header="Register Account">
|
||||
<div class='content'>
|
||||
<ha-config-section
|
||||
is-wide='[[isWide]]'
|
||||
>
|
||||
<span slot='header'>Register with the Home Assistant Cloud</span>
|
||||
<span slot='introduction'>
|
||||
<div class="content">
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<span slot="header">Register with the Home Assistant Cloud</span>
|
||||
<span slot="introduction">
|
||||
Register today to easily connect with the Home Assistant Cloud. This will allow you to unlock great new services and functionality, like Amazon Alexa integration.
|
||||
|
||||
<p>
|
||||
By registering an account you agree to the following terms and conditions.
|
||||
<ul>
|
||||
<li><a href='https://home-assistant.io/tos/' target='_blank'>Terms and Conditions</a></li>
|
||||
<li><a href='https://home-assistant.io/privacy/' target='_blank'>Privacy Policy</a></li>
|
||||
</p><ul>
|
||||
<li><a href="https://home-assistant.io/tos/" target="_blank">Terms and Conditions</a></li>
|
||||
<li><a href="https://home-assistant.io/privacy/" target="_blank">Privacy Policy</a></li>
|
||||
</ul>
|
||||
</p>
|
||||
<p></p>
|
||||
</span>
|
||||
|
||||
<paper-card>
|
||||
<div class='card-content'>
|
||||
<div class='header'>
|
||||
<div class="card-content">
|
||||
<div class="header">
|
||||
<h1>Register</h1>
|
||||
<div class='error' hidden$='[[!_error]]'>[[_error]]</div>
|
||||
<div class="error" hidden\$="[[!_error]]">[[_error]]</div>
|
||||
</div>
|
||||
<paper-input
|
||||
autofocus
|
||||
id='email'
|
||||
label='Email address'
|
||||
type='email'
|
||||
value='{{email}}'
|
||||
on-keydown='_keyDown'
|
||||
error-message='Invalid email'
|
||||
></paper-input>
|
||||
<paper-input
|
||||
id='password'
|
||||
label='Password'
|
||||
value='{{_password}}'
|
||||
type='password'
|
||||
on-keydown='_keyDown'
|
||||
error-message='Your password needs to be at least 8 characters'
|
||||
></paper-input>
|
||||
<paper-input autofocus="" id="email" label="Email address" type="email" value="{{email}}" on-keydown="_keyDown" error-message="Invalid email"></paper-input>
|
||||
<paper-input id="password" label="Password" value="{{_password}}" type="password" on-keydown="_keyDown" error-message="Your password needs to be at least 8 characters"></paper-input>
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<ha-progress-button
|
||||
on-click='_handleRegister'
|
||||
progress='[[_requestInProgress]]'
|
||||
>Create Account</ha-progress-button>
|
||||
<button
|
||||
class='link'
|
||||
hidden='[[_requestInProgress]]'
|
||||
on-click='_handleResendVerifyEmail'
|
||||
>Resend confirmation email</button>
|
||||
<div class="card-actions">
|
||||
<ha-progress-button on-click="_handleRegister" progress="[[_requestInProgress]]">Create Account</ha-progress-button>
|
||||
<button class="link" hidden="[[_requestInProgress]]" on-click="_handleResendVerifyEmail">Resend confirmation email</button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
</div>
|
||||
</hass-subpage>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaConfigCloudRegister extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-config-cloud-register'; }
|
||||
|
||||
static get properties() {
|
||||
@ -209,4 +184,3 @@ class HaConfigCloudRegister extends window.hassMixins.EventsMixin(Polymer.Elemen
|
||||
}
|
||||
|
||||
customElements.define(HaConfigCloudRegister.is, HaConfigCloudRegister);
|
||||
</script>
|
||||
@ -1,133 +0,0 @@
|
||||
<link rel="import" href='../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../../bower_components/app-route/app-route.html'>
|
||||
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
|
||||
<link rel="import" href="./ha-config-cloud-login.html">
|
||||
<link rel="import" href="./ha-config-cloud-register.html">
|
||||
<link rel="import" href="./ha-config-cloud-forgot-password.html">
|
||||
<link rel="import" href="./ha-config-cloud-account.html">
|
||||
|
||||
<dom-module id="ha-config-cloud">
|
||||
<template>
|
||||
<app-route
|
||||
route='[[route]]'
|
||||
pattern='/cloud/:page'
|
||||
data="{{_routeData}}"
|
||||
tail="{{_routeTail}}"
|
||||
></app-route>
|
||||
|
||||
<template is='dom-if' if='[[_equals(_routeData.page, "account")]]' restamp>
|
||||
<ha-config-cloud-account
|
||||
hass='[[hass]]'
|
||||
account='[[account]]'
|
||||
is-wide='[[isWide]]'
|
||||
></ha-config-cloud-account>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[_equals(_routeData.page, "login")]]' restamp>
|
||||
<ha-config-cloud-login
|
||||
page-name='login'
|
||||
hass='[[hass]]'
|
||||
is-wide='[[isWide]]'
|
||||
email='{{_loginEmail}}'
|
||||
flash-message='{{_flashMessage}}'
|
||||
></ha-config-cloud-login>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[_equals(_routeData.page, "register")]]' restamp>
|
||||
<ha-config-cloud-register
|
||||
page-name='register'
|
||||
hass='[[hass]]'
|
||||
is-wide='[[isWide]]'
|
||||
email='{{_loginEmail}}'
|
||||
></ha-config-cloud-register>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[_equals(_routeData.page, "forgot-password")]]' restamp>
|
||||
<ha-config-cloud-forgot-password
|
||||
page-name='forgot-password'
|
||||
hass='[[hass]]'
|
||||
email='{{_loginEmail}}'
|
||||
></ha-config-cloud-forgot-password>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
{
|
||||
const LOGGED_IN_URLS = [
|
||||
'/cloud/account',
|
||||
];
|
||||
const NOT_LOGGED_IN_URLS = [
|
||||
'/cloud/login',
|
||||
'/cloud/register',
|
||||
'/cloud/forgot-password',
|
||||
];
|
||||
|
||||
class HaConfigCloud extends window.hassMixins.NavigateMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-config-cloud'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
loadingAccount: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
account: {
|
||||
type: Object,
|
||||
},
|
||||
_flashMessage: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
|
||||
route: Object,
|
||||
|
||||
_routeData: Object,
|
||||
_routeTail: Object,
|
||||
_loginEmail: String,
|
||||
};
|
||||
}
|
||||
|
||||
static get observers() {
|
||||
return [
|
||||
'_checkRoute(route, account)'
|
||||
];
|
||||
}
|
||||
|
||||
ready() {
|
||||
super.ready();
|
||||
this.addEventListener('cloud-done', (ev) => {
|
||||
this._flashMessage = ev.detail.flashMessage;
|
||||
this.navigate('/config/cloud/login');
|
||||
});
|
||||
}
|
||||
|
||||
_checkRoute(route) {
|
||||
if (!route || route.path.substr(0, 6) !== '/cloud') return;
|
||||
|
||||
this._debouncer = Polymer.Debouncer.debounce(
|
||||
this._debouncer,
|
||||
Polymer.Async.timeOut.after(0),
|
||||
() => {
|
||||
if (!this.account && !NOT_LOGGED_IN_URLS.includes(route.path)) {
|
||||
this.navigate('/config/cloud/login', true);
|
||||
} else if (this.account && !LOGGED_IN_URLS.includes(route.path)) {
|
||||
this.navigate('/config/cloud/account', true);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
_equals(a, b) {
|
||||
return a === b;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaConfigCloud.is, HaConfigCloud);
|
||||
}
|
||||
</script>
|
||||
109
panels/config/cloud/ha-config-cloud.js
Normal file
109
panels/config/cloud/ha-config-cloud.js
Normal file
@ -0,0 +1,109 @@
|
||||
import '@polymer/app-route/app-route.js';
|
||||
import { timeOut } from '@polymer/polymer/lib/utils/async.js';
|
||||
import { Debouncer } from '@polymer/polymer/lib/utils/debounce.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
import '../ha-config-section.js';
|
||||
import './ha-config-cloud-account.js';
|
||||
import './ha-config-cloud-forgot-password.js';
|
||||
import './ha-config-cloud-login.js';
|
||||
import './ha-config-cloud-register.js';
|
||||
|
||||
{
|
||||
const LOGGED_IN_URLS = [
|
||||
'/cloud/account',
|
||||
];
|
||||
const NOT_LOGGED_IN_URLS = [
|
||||
'/cloud/login',
|
||||
'/cloud/register',
|
||||
'/cloud/forgot-password',
|
||||
];
|
||||
|
||||
class HaConfigCloud extends window.hassMixins.NavigateMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<app-route route="[[route]]" pattern="/cloud/:page" data="{{_routeData}}" tail="{{_routeTail}}"></app-route>
|
||||
|
||||
<template is="dom-if" if="[[_equals(_routeData.page, "account")]]" restamp="">
|
||||
<ha-config-cloud-account hass="[[hass]]" account="[[account]]" is-wide="[[isWide]]"></ha-config-cloud-account>
|
||||
</template>
|
||||
|
||||
<template is="dom-if" if="[[_equals(_routeData.page, "login")]]" restamp="">
|
||||
<ha-config-cloud-login page-name="login" hass="[[hass]]" is-wide="[[isWide]]" email="{{_loginEmail}}" flash-message="{{_flashMessage}}"></ha-config-cloud-login>
|
||||
</template>
|
||||
|
||||
<template is="dom-if" if="[[_equals(_routeData.page, "register")]]" restamp="">
|
||||
<ha-config-cloud-register page-name="register" hass="[[hass]]" is-wide="[[isWide]]" email="{{_loginEmail}}"></ha-config-cloud-register>
|
||||
</template>
|
||||
|
||||
<template is="dom-if" if="[[_equals(_routeData.page, "forgot-password")]]" restamp="">
|
||||
<ha-config-cloud-forgot-password page-name="forgot-password" hass="[[hass]]" email="{{_loginEmail}}"></ha-config-cloud-forgot-password>
|
||||
</template>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-config-cloud'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
loadingAccount: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
account: {
|
||||
type: Object,
|
||||
},
|
||||
_flashMessage: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
|
||||
route: Object,
|
||||
|
||||
_routeData: Object,
|
||||
_routeTail: Object,
|
||||
_loginEmail: String,
|
||||
};
|
||||
}
|
||||
|
||||
static get observers() {
|
||||
return [
|
||||
'_checkRoute(route, account)'
|
||||
];
|
||||
}
|
||||
|
||||
ready() {
|
||||
super.ready();
|
||||
this.addEventListener('cloud-done', (ev) => {
|
||||
this._flashMessage = ev.detail.flashMessage;
|
||||
this.navigate('/config/cloud/login');
|
||||
});
|
||||
}
|
||||
|
||||
_checkRoute(route) {
|
||||
if (!route || route.path.substr(0, 6) !== '/cloud') return;
|
||||
|
||||
this._debouncer = Debouncer.debounce(
|
||||
this._debouncer,
|
||||
timeOut.after(0),
|
||||
() => {
|
||||
if (!this.account && !NOT_LOGGED_IN_URLS.includes(route.path)) {
|
||||
this.navigate('/config/cloud/login', true);
|
||||
} else if (this.account && !LOGGED_IN_URLS.includes(route.path)) {
|
||||
this.navigate('/config/cloud/account', true);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
_equals(a, b) {
|
||||
return a === b;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaConfigCloud.is, HaConfigCloud);
|
||||
}
|
||||
@ -1,20 +1,26 @@
|
||||
<link rel="import" href='../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../../bower_components/paper-button/paper-button.html'>
|
||||
<link rel='import' href='../../../bower_components/paper-card/paper-card.html'>
|
||||
<link rel='import' href='../../../bower_components/paper-item/paper-item-body.html'>
|
||||
<link rel='import' href='../../../bower_components/iron-flex-layout/iron-flex-layout-classes.html'>
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-item/paper-item-body.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
<link rel='import' href='../../../src/resources/ha-style.html'>
|
||||
<link rel='import' href='../../../src/layouts/hass-subpage.html'>
|
||||
import '../../../src/layouts/hass-subpage.js';
|
||||
import '../../../src/resources/ha-style.js';
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
import '../ha-config-section.js';
|
||||
import './ha-config-flow.js';
|
||||
|
||||
<link rel='import' href='../ha-config-section.html'>
|
||||
|
||||
<link rel='import' href='./ha-config-flow.html'>
|
||||
|
||||
<dom-module id="ha-config-entries">
|
||||
<template>
|
||||
<style include='iron-flex ha-style'>
|
||||
{
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaConfigManager extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
paper-button {
|
||||
color: var(--primary-color);
|
||||
font-weight: 500;
|
||||
@ -30,79 +36,66 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<hass-subpage header='Integrations'>
|
||||
<template is='dom-if' if='[[_progress.length]]'>
|
||||
<ha-config-section is-wide='[[isWide]]'>
|
||||
<span slot='header'>In Progress</span>
|
||||
<hass-subpage header="Integrations">
|
||||
<template is="dom-if" if="[[_progress.length]]">
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<span slot="header">In Progress</span>
|
||||
<paper-card>
|
||||
<template is='dom-repeat' items='[[_progress]]'>
|
||||
<div class='config-entry-row'>
|
||||
<template is="dom-repeat" items="[[_progress]]">
|
||||
<div class="config-entry-row">
|
||||
<paper-item-body>
|
||||
[[_computeIntegrationTitle(localize, item.handler)]]
|
||||
</paper-item-body>
|
||||
<paper-button on-click='_continueFlow'>Configure</paper-button>
|
||||
<paper-button on-click="_continueFlow">Configure</paper-button>
|
||||
</div>
|
||||
</template>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
</template>
|
||||
|
||||
<ha-config-section is-wide='[[isWide]]'>
|
||||
<span slot='header'>Configured</span>
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<span slot="header">Configured</span>
|
||||
<paper-card>
|
||||
<template is='dom-if' if='[[!_entries.length]]'>
|
||||
<div class='config-entry-row'>
|
||||
<template is="dom-if" if="[[!_entries.length]]">
|
||||
<div class="config-entry-row">
|
||||
<paper-item-body>
|
||||
Nothing configured yet
|
||||
</paper-item-body>
|
||||
</div>
|
||||
</template>
|
||||
<template is='dom-repeat' items='[[_entries]]'>
|
||||
<div class='config-entry-row'>
|
||||
<paper-item-body three-line>
|
||||
<template is="dom-repeat" items="[[_entries]]">
|
||||
<div class="config-entry-row">
|
||||
<paper-item-body three-line="">
|
||||
[[item.title]]
|
||||
<div secondary>Integration: [[_computeIntegrationTitle(localize, item.domain)]]</div>
|
||||
<div secondary>Added by: [[item.source]]</div>
|
||||
<div secondary>State: [[item.state]]</div>
|
||||
<div secondary="">Integration: [[_computeIntegrationTitle(localize, item.domain)]]</div>
|
||||
<div secondary="">Added by: [[item.source]]</div>
|
||||
<div secondary="">State: [[item.state]]</div>
|
||||
</paper-item-body>
|
||||
<paper-button on-click='_removeEntry'>Remove</paper-button>
|
||||
<paper-button on-click="_removeEntry">Remove</paper-button>
|
||||
</div>
|
||||
</template>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
|
||||
<ha-config-section is-wide='[[isWide]]'>
|
||||
<span slot='header'>Available</span>
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<span slot="header">Available</span>
|
||||
<paper-card>
|
||||
<template is='dom-repeat' items='[[_handlers]]'>
|
||||
<div class='config-entry-row'>
|
||||
<template is="dom-repeat" items="[[_handlers]]">
|
||||
<div class="config-entry-row">
|
||||
<paper-item-body>
|
||||
[[_computeIntegrationTitle(localize, item)]]
|
||||
</paper-item-body>
|
||||
<paper-button on-click='_createFlow'>Configure</paper-button>
|
||||
<paper-button on-click="_createFlow">Configure</paper-button>
|
||||
</div>
|
||||
</template>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
</hass-subpage>
|
||||
|
||||
<ha-config-flow
|
||||
hass='[[hass]]'
|
||||
flow-id='[[_flowId]]'
|
||||
step='{{_flowStep}}'
|
||||
on-flow-closed='_flowClose'
|
||||
></ha-config-flow>
|
||||
</template>
|
||||
</dom-module>
|
||||
<ha-config-flow hass="[[hass]]" flow-id="[[_flowId]]" step="{{_flowStep}}" on-flow-closed="_flowClose"></ha-config-flow>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
{
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaConfigManager extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(Polymer.Element)) {
|
||||
static get is() { return 'ha-config-entries'; }
|
||||
|
||||
static get properties() {
|
||||
@ -209,4 +202,3 @@
|
||||
|
||||
customElements.define(HaConfigManager.is, HaConfigManager);
|
||||
}
|
||||
</script>
|
||||
@ -1,16 +1,23 @@
|
||||
<link rel="import" href='../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../../bower_components/paper-dialog/paper-dialog.html'>
|
||||
<link rel='import' href='../../../bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html'>
|
||||
<link rel="import" href='../../../bower_components/paper-button/paper-button.html'>
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-dialog-scrollable/paper-dialog-scrollable.js';
|
||||
import '@polymer/paper-dialog/paper-dialog.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
<link rel="import" href='../../../src/components/ha-markdown.html'>
|
||||
<link rel='import' href='../../../src/resources/ha-style.html'>
|
||||
<link rel="import" href='../../../src/components/ha-form.html'>
|
||||
import '../../../src/components/ha-form.js';
|
||||
import '../../../src/components/ha-markdown.js';
|
||||
import '../../../src/resources/ha-style.js';
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
|
||||
<dom-module id="ha-config-flow">
|
||||
<template>
|
||||
<style include='ha-style-dialog'>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaConfigFlow extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style-dialog">
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
@ -22,73 +29,55 @@
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
<paper-dialog
|
||||
id='dialog'
|
||||
with-backdrop
|
||||
opened='[[step]]'
|
||||
on-opened-changed='_openedChanged'
|
||||
>
|
||||
<paper-dialog id="dialog" with-backdrop="" opened="[[step]]" on-opened-changed="_openedChanged">
|
||||
<h2>
|
||||
<template is='dom-if' if='[[_equals(step.type, "abort")]]'>
|
||||
<template is="dom-if" if="[[_equals(step.type, "abort")]]">
|
||||
Aborted
|
||||
</template>
|
||||
<template is='dom-if' if='[[_equals(step.type, "create_entry")]]'>
|
||||
<template is="dom-if" if="[[_equals(step.type, "create_entry")]]">
|
||||
Success!
|
||||
</template>
|
||||
<template is='dom-if' if='[[_equals(step.type, "form")]]'>
|
||||
<template is="dom-if" if="[[_equals(step.type, "form")]]">
|
||||
[[_computeStepTitle(localize, step)]]
|
||||
</template>
|
||||
</h2>
|
||||
<paper-dialog-scrollable>
|
||||
<template is='dom-if' if='[[!step]]'>
|
||||
<template is="dom-if" if="[[!step]]">
|
||||
Loading flow.
|
||||
</template>
|
||||
<template is='dom-if' if='[[step]]'>
|
||||
<template is='dom-if' if='[[_equals(step.type, "abort")]]'>
|
||||
<template is="dom-if" if="[[step]]">
|
||||
<template is="dom-if" if="[[_equals(step.type, "abort")]]">
|
||||
<p>[[_computeStepAbortedReason(localize, step)]]</p>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[_equals(step.type, "create_entry")]]'>
|
||||
<template is="dom-if" if="[[_equals(step.type, "create_entry")]]">
|
||||
<p>Created config for [[step.title]]</p>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[_equals(step.type, "form")]]'>
|
||||
<template is='dom-if' if='[[_computeStepDescription(localize, step)]]'>
|
||||
<ha-markdown content='[[_computeStepDescription(localize, step)]]'></ha-markdown>
|
||||
<template is="dom-if" if="[[_equals(step.type, "form")]]">
|
||||
<template is="dom-if" if="[[_computeStepDescription(localize, step)]]">
|
||||
<ha-markdown content="[[_computeStepDescription(localize, step)]]"></ha-markdown>
|
||||
</template>
|
||||
|
||||
<ha-form
|
||||
data='{{stepData}}'
|
||||
schema='[[step.data_schema]]'
|
||||
error='[[step.errors]]'
|
||||
compute-label='[[_computeLabelCallback(localize, step)]]'
|
||||
compute-error='[[_computeErrorCallback(localize, step)]]'
|
||||
></ha-form>
|
||||
<ha-form data="{{stepData}}" schema="[[step.data_schema]]" error="[[step.errors]]" compute-label="[[_computeLabelCallback(localize, step)]]" compute-error="[[_computeErrorCallback(localize, step)]]"></ha-form>
|
||||
</template>
|
||||
</template>
|
||||
</paper-dialog-scrollable>
|
||||
<div class='buttons'>
|
||||
<template is='dom-if' if='[[_equals(step.type, "abort")]]'>
|
||||
<paper-button on-click='_flowDone'>Close</paper-button>
|
||||
<div class="buttons">
|
||||
<template is="dom-if" if="[[_equals(step.type, "abort")]]">
|
||||
<paper-button on-click="_flowDone">Close</paper-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[_equals(step.type, "create_entry")]]'>
|
||||
<paper-button on-click='_flowDone'>Close</paper-button>
|
||||
<template is="dom-if" if="[[_equals(step.type, "create_entry")]]">
|
||||
<paper-button on-click="_flowDone">Close</paper-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[_equals(step.type, "form")]]'>
|
||||
<paper-button on-click='_submitStep'>Submit</paper-button>
|
||||
<template is="dom-if" if="[[_equals(step.type, "form")]]">
|
||||
<paper-button on-click="_submitStep">Submit</paper-button>
|
||||
</template>
|
||||
</div>
|
||||
</paper-dialog>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaConfigFlow extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(Polymer.Element)) {
|
||||
static get is() { return 'ha-config-flow'; }
|
||||
|
||||
static get properties() {
|
||||
@ -204,4 +193,3 @@ class HaConfigFlow extends
|
||||
}
|
||||
|
||||
customElements.define(HaConfigFlow.is, HaConfigFlow);
|
||||
</script>
|
||||
@ -1,121 +0,0 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-header/app-header.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
<link rel="import" href="../../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
|
||||
<link rel="import" href="../../../src/resources/ha-style.html">
|
||||
<link rel='import' href='../../../src/layouts/ha-app-layout.html'>
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
|
||||
<link rel="import" href="./ha-config-section-core.html">
|
||||
<link rel="import" href="./ha-config-section-push-notifications.html">
|
||||
<link rel="import" href="./ha-config-section-translation.html">
|
||||
<link rel="import" href="./ha-config-section-themes.html">
|
||||
|
||||
<dom-module id="ha-config-core">
|
||||
<template>
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
|
||||
.border {
|
||||
margin: 32px auto 0;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||
max-width: 1040px;
|
||||
}
|
||||
|
||||
.narrow .border {
|
||||
max-width: 640px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<ha-app-layout has-scrolling-region>
|
||||
<app-header slot="header" fixed>
|
||||
<app-toolbar>
|
||||
<paper-icon-button
|
||||
icon='mdi:arrow-left'
|
||||
on-click='_backTapped'
|
||||
></paper-icon-button>
|
||||
<div main-title>[[localize('ui.panel.config.core.caption')]]</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<div class$='[[computeClasses(isWide)]]'>
|
||||
<ha-config-section-core
|
||||
is-wide='[[isWide]]'
|
||||
hass='[[hass]]'
|
||||
></ha-config-section-core>
|
||||
|
||||
<template is='dom-if' if='[[pushSupported]]'>
|
||||
<div class='border'></div>
|
||||
<ha-config-section-push-notifications
|
||||
is-wide='[[isWide]]'
|
||||
hass='[[hass]]'
|
||||
push-supported='{{pushSupported}}'
|
||||
></ha-config-section-push-notifications>
|
||||
</template>
|
||||
<template is='dom-if' if='[[computeIsTranslationLoaded(hass)]]'>
|
||||
<div class='border'></div>
|
||||
<ha-config-section-translation
|
||||
is-wide='[[isWide]]'
|
||||
hass='[[hass]]'
|
||||
></ha-config-section-translation>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[computeIsThemesLoaded(hass)]]'>
|
||||
<div class='border'></div>
|
||||
<ha-config-section-themes
|
||||
is-wide='[[isWide]]'
|
||||
hass='[[hass]]'
|
||||
></ha-config-section-themes>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
</ha-app-layout>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaConfigCore extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-config-core'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
pushSupported: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
computeClasses(isWide) {
|
||||
return isWide ? 'content' : 'content narrow';
|
||||
}
|
||||
|
||||
computeIsZwaveLoaded(hass) {
|
||||
return window.hassUtil.isComponentLoaded(hass, 'config.zwave');
|
||||
}
|
||||
|
||||
computeIsTranslationLoaded(hass) {
|
||||
return hass.translationMetadata &&
|
||||
Object.keys(hass.translationMetadata.translations).length;
|
||||
}
|
||||
|
||||
computeIsThemesLoaded(hass) {
|
||||
return hass.themes && hass.themes.themes &&
|
||||
Object.keys(hass.themes.themes).length;
|
||||
}
|
||||
|
||||
_backTapped() {
|
||||
history.back();
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaConfigCore.is, HaConfigCore);
|
||||
</script>
|
||||
103
panels/config/core/ha-config-core.js
Normal file
103
panels/config/core/ha-config-core.js
Normal file
@ -0,0 +1,103 @@
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../../../src/layouts/ha-app-layout.js';
|
||||
import '../../../src/resources/ha-style.js';
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
import './ha-config-section-core.js';
|
||||
import './ha-config-section-push-notifications.js';
|
||||
import './ha-config-section-themes.js';
|
||||
import './ha-config-section-translation.js';
|
||||
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaConfigCore extends window.hassMixins.LocalizeMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
|
||||
.border {
|
||||
margin: 32px auto 0;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||
max-width: 1040px;
|
||||
}
|
||||
|
||||
.narrow .border {
|
||||
max-width: 640px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<ha-app-layout has-scrolling-region="">
|
||||
<app-header slot="header" fixed="">
|
||||
<app-toolbar>
|
||||
<paper-icon-button icon="mdi:arrow-left" on-click="_backTapped"></paper-icon-button>
|
||||
<div main-title="">[[localize('ui.panel.config.core.caption')]]</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<div class\$="[[computeClasses(isWide)]]">
|
||||
<ha-config-section-core is-wide="[[isWide]]" hass="[[hass]]"></ha-config-section-core>
|
||||
|
||||
<template is="dom-if" if="[[pushSupported]]">
|
||||
<div class="border"></div>
|
||||
<ha-config-section-push-notifications is-wide="[[isWide]]" hass="[[hass]]" push-supported="{{pushSupported}}"></ha-config-section-push-notifications>
|
||||
</template>
|
||||
<template is="dom-if" if="[[computeIsTranslationLoaded(hass)]]">
|
||||
<div class="border"></div>
|
||||
<ha-config-section-translation is-wide="[[isWide]]" hass="[[hass]]"></ha-config-section-translation>
|
||||
</template>
|
||||
|
||||
<template is="dom-if" if="[[computeIsThemesLoaded(hass)]]">
|
||||
<div class="border"></div>
|
||||
<ha-config-section-themes is-wide="[[isWide]]" hass="[[hass]]"></ha-config-section-themes>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
</ha-app-layout>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-config-core'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
pushSupported: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
computeClasses(isWide) {
|
||||
return isWide ? 'content' : 'content narrow';
|
||||
}
|
||||
|
||||
computeIsZwaveLoaded(hass) {
|
||||
return window.hassUtil.isComponentLoaded(hass, 'config.zwave');
|
||||
}
|
||||
|
||||
computeIsTranslationLoaded(hass) {
|
||||
return hass.translationMetadata &&
|
||||
Object.keys(hass.translationMetadata.translations).length;
|
||||
}
|
||||
|
||||
computeIsThemesLoaded(hass) {
|
||||
return hass.themes && hass.themes.themes &&
|
||||
Object.keys(hass.themes.themes).length;
|
||||
}
|
||||
|
||||
_backTapped() {
|
||||
history.back();
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaConfigCore.is, HaConfigCore);
|
||||
@ -1,17 +1,20 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-input/paper-input.html">
|
||||
<link rel="import" href="../../../bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../../src/components/buttons/ha-call-service-button.html">
|
||||
<link rel="import" href="../../../src/resources/ha-style.html">
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
import '../../../src/components/buttons/ha-call-service-button.js';
|
||||
import '../../../src/resources/ha-style.js';
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
import '../ha-config-section.js';
|
||||
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
|
||||
<dom-module id="ha-config-section-core">
|
||||
<template>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaConfigSectionCore extends window.hassMixins.LocalizeMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.validate-container {
|
||||
@apply --layout-vertical;
|
||||
@ -42,112 +45,76 @@
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
</style>
|
||||
<ha-config-section
|
||||
is-wide='[[isWide]]'
|
||||
>
|
||||
<span slot='header'>[[localize('ui.panel.config.core.section.core.header')]]</span>
|
||||
<span slot='introduction'>[[localize('ui.panel.config.core.section.core.introduction')]]</span>
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<span slot="header">[[localize('ui.panel.config.core.section.core.header')]]</span>
|
||||
<span slot="introduction">[[localize('ui.panel.config.core.section.core.introduction')]]</span>
|
||||
|
||||
<paper-card heading="[[localize('ui.panel.config.core.section.core.validation.heading')]]">
|
||||
<div class='card-content'>
|
||||
<div class="card-content">
|
||||
[[localize('ui.panel.config.core.section.core.validation.introduction')]]
|
||||
<template is='dom-if' if='[[!validateLog]]'>
|
||||
<div class='validate-container'>
|
||||
<template is='dom-if' if='[[!validating]]'>
|
||||
<template is='dom-if' if='[[isValid]]'>
|
||||
<div class='validate-result' id='result'>
|
||||
<template is="dom-if" if="[[!validateLog]]">
|
||||
<div class="validate-container">
|
||||
<template is="dom-if" if="[[!validating]]">
|
||||
<template is="dom-if" if="[[isValid]]">
|
||||
<div class="validate-result" id="result">
|
||||
[[localize('ui.panel.config.core.section.core.validation.valid')]]
|
||||
</div>
|
||||
</template>
|
||||
<paper-button raised on-click='validateConfig'>
|
||||
<paper-button raised="" on-click="validateConfig">
|
||||
[[localize('ui.panel.config.core.section.core.validation.check_config')]]
|
||||
</paper-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[validating]]'>
|
||||
<paper-spinner active></paper-spinner>
|
||||
<template is="dom-if" if="[[validating]]">
|
||||
<paper-spinner active=""></paper-spinner>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<template is='dom-if' if='[[validateLog]]'>
|
||||
<div class='config-invalid'>
|
||||
<span class='text'>
|
||||
<template is="dom-if" if="[[validateLog]]">
|
||||
<div class="config-invalid">
|
||||
<span class="text">
|
||||
[[localize('ui.panel.config.core.section.core.validation.invalid')]]
|
||||
</span>
|
||||
<paper-button raised on-click='validateConfig'>
|
||||
<paper-button raised="" on-click="validateConfig">
|
||||
[[localize('ui.panel.config.core.section.core.validation.check_config')]]
|
||||
</paper-button>
|
||||
</div>
|
||||
<div id='configLog' class='validate-log'>[[validateLog]]</div>
|
||||
<div id="configLog" class="validate-log">[[validateLog]]</div>
|
||||
</template>
|
||||
</div>
|
||||
</paper-card>
|
||||
|
||||
<paper-card heading="[[localize('ui.panel.config.core.section.core.reloading.heading')]]">
|
||||
<div class='card-content'>
|
||||
<div class="card-content">
|
||||
[[localize('ui.panel.config.core.section.core.reloading.introduction')]]
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='homeassistant'
|
||||
service='reload_core_config'
|
||||
>[[localize('ui.panel.config.core.section.core.reloading.core')]]
|
||||
<div class="card-actions">
|
||||
<ha-call-service-button hass="[[hass]]" domain="homeassistant" service="reload_core_config">[[localize('ui.panel.config.core.section.core.reloading.core')]]
|
||||
</ha-call-service-button>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='group'
|
||||
service='reload'
|
||||
hidden$='[[!groupLoaded(hass)]]'
|
||||
>[[localize('ui.panel.config.core.section.core.reloading.group')]]
|
||||
<ha-call-service-button hass="[[hass]]" domain="group" service="reload" hidden\$="[[!groupLoaded(hass)]]">[[localize('ui.panel.config.core.section.core.reloading.group')]]
|
||||
</ha-call-service-button>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='automation'
|
||||
service='reload'
|
||||
hidden$='[[!automationLoaded(hass)]]'
|
||||
>[[localize('ui.panel.config.core.section.core.reloading.automation')]]
|
||||
<ha-call-service-button hass="[[hass]]" domain="automation" service="reload" hidden\$="[[!automationLoaded(hass)]]">[[localize('ui.panel.config.core.section.core.reloading.automation')]]
|
||||
</ha-call-service-button>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='script'
|
||||
service='reload'
|
||||
hidden$='[[!scriptLoaded(hass)]]'
|
||||
>[[localize('ui.panel.config.core.section.core.reloading.script')]]
|
||||
<ha-call-service-button hass="[[hass]]" domain="script" service="reload" hidden\$="[[!scriptLoaded(hass)]]">[[localize('ui.panel.config.core.section.core.reloading.script')]]
|
||||
</ha-call-service-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
|
||||
<paper-card heading="[[localize('ui.panel.config.core.section.core.server_management.heading')]]">
|
||||
<div class='card-content'>
|
||||
<div class="card-content">
|
||||
[[localize('ui.panel.config.core.section.core.server_management.introduction')]]
|
||||
</div>
|
||||
<div class='card-actions warning'>
|
||||
<ha-call-service-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
domain='homeassistant'
|
||||
service='restart'
|
||||
>[[localize('ui.panel.config.core.section.core.server_management.restart')]]
|
||||
<div class="card-actions warning">
|
||||
<ha-call-service-button class="warning" hass="[[hass]]" domain="homeassistant" service="restart">[[localize('ui.panel.config.core.section.core.server_management.restart')]]
|
||||
</ha-call-service-button>
|
||||
<ha-call-service-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
domain='homeassistant'
|
||||
service='stop'
|
||||
>[[localize('ui.panel.config.core.section.core.server_management.stop')]]
|
||||
<ha-call-service-button class="warning" hass="[[hass]]" domain="homeassistant" service="stop">[[localize('ui.panel.config.core.section.core.server_management.stop')]]
|
||||
</ha-call-service-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
|
||||
</ha-config-section>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaConfigSectionCore extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-config-section-core'; }
|
||||
|
||||
static get properties() {
|
||||
@ -207,4 +174,3 @@ class HaConfigSectionCore extends window.hassMixins.LocalizeMixin(Polymer.Elemen
|
||||
}
|
||||
|
||||
customElements.define(HaConfigSectionCore.is, HaConfigSectionCore);
|
||||
</script>
|
||||
@ -1,59 +0,0 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../bower_components/iron-label/iron-label.html">
|
||||
<link rel="import" href="../../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
<link rel='import' href='../../../src/components/ha-push-notifications-toggle.html'>
|
||||
|
||||
|
||||
<dom-module id="ha-config-section-push-notifications">
|
||||
<template>
|
||||
<style include="iron-flex iron-flex-alignment iron-positioning">
|
||||
ha-push-notifications-toggle {
|
||||
margin-left: 16px;
|
||||
}
|
||||
</style>
|
||||
<ha-config-section is-wide='[[isWide]]'>
|
||||
<span slot='header'>[[localize('ui.panel.config.core.section.push_notifications.header')]]</span>
|
||||
<span slot='introduction'>
|
||||
[[localize('ui.panel.config.core.section.push_notifications.introduction')]]
|
||||
</span>
|
||||
|
||||
<paper-card>
|
||||
<div class='card-content'>
|
||||
<iron-label class='horizontal layout'>
|
||||
[[localize('ui.panel.config.core.section.push_notifications.push_notifications')]]
|
||||
<ha-push-notifications-toggle
|
||||
hass='[[hass]]'
|
||||
push-supported='{{pushSupported}}'
|
||||
></ha-push-notifications-toggle>
|
||||
</iron-label>
|
||||
</div>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaConfigSectionPushNotifications extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-config-section-push-notifications'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
pushSupported: {
|
||||
type: Boolean,
|
||||
notify: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaConfigSectionPushNotifications.is, HaConfigSectionPushNotifications);
|
||||
</script>
|
||||
54
panels/config/core/ha-config-section-push-notifications.js
Normal file
54
panels/config/core/ha-config-section-push-notifications.js
Normal file
@ -0,0 +1,54 @@
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import '@polymer/iron-label/iron-label.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../../../src/components/ha-push-notifications-toggle.js';
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
import '../ha-config-section.js';
|
||||
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaConfigSectionPushNotifications extends window.hassMixins.LocalizeMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex iron-flex-alignment iron-positioning">
|
||||
ha-push-notifications-toggle {
|
||||
margin-left: 16px;
|
||||
}
|
||||
</style>
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<span slot="header">[[localize('ui.panel.config.core.section.push_notifications.header')]]</span>
|
||||
<span slot="introduction">
|
||||
[[localize('ui.panel.config.core.section.push_notifications.introduction')]]
|
||||
</span>
|
||||
|
||||
<paper-card>
|
||||
<div class="card-content">
|
||||
<iron-label class="horizontal layout">
|
||||
[[localize('ui.panel.config.core.section.push_notifications.push_notifications')]]
|
||||
<ha-push-notifications-toggle hass="[[hass]]" push-supported="{{pushSupported}}"></ha-push-notifications-toggle>
|
||||
</iron-label>
|
||||
</div>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-config-section-push-notifications'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
pushSupported: {
|
||||
type: Boolean,
|
||||
notify: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaConfigSectionPushNotifications.is, HaConfigSectionPushNotifications);
|
||||
@ -1,28 +1,32 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
|
||||
<link rel='import' href='../../../bower_components/paper-listbox/paper-listbox.html'>
|
||||
<link rel='import' href='../../../bower_components/paper-item/paper-item.html'>
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
import '../ha-config-section.js';
|
||||
|
||||
<dom-module id="ha-config-section-themes">
|
||||
<template>
|
||||
<ha-config-section is-wide='[[isWide]]'>
|
||||
<span slot='header'>[[localize('ui.panel.config.core.section.themes.header')]]</span>
|
||||
<span slot='introduction'>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaConfigSectionThemes extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<span slot="header">[[localize('ui.panel.config.core.section.themes.header')]]</span>
|
||||
<span slot="introduction">
|
||||
[[localize('ui.panel.config.core.section.themes.introduction')]]
|
||||
</span>
|
||||
|
||||
<paper-card>
|
||||
<div class='card-content'>
|
||||
<paper-dropdown-menu label="[[localize('ui.panel.config.core.section.themes.header')]]" dynamic-align>
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
selected='{{selectedTheme}}'
|
||||
>
|
||||
<template is='dom-repeat' items='[[themes]]' as='theme'>
|
||||
<div class="card-content">
|
||||
<paper-dropdown-menu label="[[localize('ui.panel.config.core.section.themes.header')]]" dynamic-align="">
|
||||
<paper-listbox slot="dropdown-content" selected="{{selectedTheme}}">
|
||||
<template is="dom-repeat" items="[[themes]]" as="theme">
|
||||
<paper-item>[[theme]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
@ -30,16 +34,9 @@
|
||||
</div>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaConfigSectionThemes extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(Polymer.Element)) {
|
||||
static get is() { return 'ha-config-section-themes'; }
|
||||
|
||||
static get properties() {
|
||||
@ -95,4 +92,3 @@ class HaConfigSectionThemes extends
|
||||
}
|
||||
|
||||
customElements.define(HaConfigSectionThemes.is, HaConfigSectionThemes);
|
||||
</script>
|
||||
@ -1,42 +1,42 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
|
||||
<link rel='import' href='../../../bower_components/paper-listbox/paper-listbox.html'>
|
||||
<link rel='import' href='../../../bower_components/paper-item/paper-item.html'>
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
import '../ha-config-section.js';
|
||||
|
||||
<dom-module id="ha-config-section-translation">
|
||||
<template>
|
||||
<ha-config-section is-wide='[[isWide]]'>
|
||||
<span slot='header'>[[localize('ui.panel.config.core.section.translation.header')]]</span>
|
||||
<span slot='introduction'>
|
||||
[[localize('ui.panel.config.core.section.translation.introduction')]]
|
||||
</span>
|
||||
|
||||
<paper-card>
|
||||
<div class='card-content'>
|
||||
<paper-dropdown-menu label="[[localize('ui.panel.config.core.section.translation.language')]]" dynamic-align>
|
||||
<paper-listbox slot="dropdown-content" attr-for-selected="language-tag" selected="{{languageSelection}}">
|
||||
<template is='dom-repeat' items='[[languages]]'>
|
||||
<paper-item language-tag$="[[item.tag]]">[[item.nativeName]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
></paper-dropdown-menu>
|
||||
</div>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaConfigSectionTranslation extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(Polymer.Element)) {
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<span slot="header">[[localize('ui.panel.config.core.section.translation.header')]]</span>
|
||||
<span slot="introduction">
|
||||
[[localize('ui.panel.config.core.section.translation.introduction')]]
|
||||
</span>
|
||||
|
||||
<paper-card>
|
||||
<div class="card-content">
|
||||
<paper-dropdown-menu label="[[localize('ui.panel.config.core.section.translation.language')]]" dynamic-align="">
|
||||
<paper-listbox slot="dropdown-content" attr-for-selected="language-tag" selected="{{languageSelection}}">
|
||||
<template is="dom-repeat" items="[[languages]]">
|
||||
<paper-item language-tag\$="[[item.tag]]">[[item.nativeName]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
></paper-dropdown-menu>
|
||||
</div>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-config-section-translation'; }
|
||||
|
||||
static get properties() {
|
||||
@ -84,4 +84,3 @@ class HaConfigSectionTranslation extends
|
||||
}
|
||||
|
||||
customElements.define(HaConfigSectionTranslation.is, HaConfigSectionTranslation);
|
||||
</script>
|
||||
@ -1,93 +0,0 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-header-layout/app-header-layout.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-header/app-header.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
<link rel="import" href="../../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
|
||||
<link rel="import" href="../../../src/util/hass-util.html">
|
||||
<link rel="import" href="../../../src/resources/ha-style.html">
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
|
||||
<link rel="import" href="./ha-form-customize.html">
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
<link rel="import" href="../ha-entity-config.html">
|
||||
|
||||
<dom-module id="ha-config-customize">
|
||||
<template>
|
||||
<style include="ha-style">
|
||||
</style>
|
||||
|
||||
<app-header-layout has-scrolling-region>
|
||||
<app-header slot="header" fixed>
|
||||
<app-toolbar>
|
||||
<paper-icon-button
|
||||
icon='mdi:arrow-left'
|
||||
on-click='_backTapped'
|
||||
></paper-icon-button>
|
||||
<div main-title>[[localize('ui.panel.config.customize.caption')]]</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<div class$='[[computeClasses(isWide)]]'>
|
||||
<ha-config-section is-wide='[[isWide]]'>
|
||||
<span slot='header'>Customization</span>
|
||||
<span slot='introduction'>
|
||||
Tweak per-entity attributes.<br>
|
||||
Added/edited customizations will take effect immediately. Removed customizations will take effect when the entity is updated.
|
||||
</span>
|
||||
<ha-entity-config
|
||||
hass='[[hass]]'
|
||||
label='Entity'
|
||||
entities='[[entities]]'
|
||||
config='[[entityConfig]]'>
|
||||
</ha-entity-config>
|
||||
</ha-config-section>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaConfigCustomize extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-config-customize'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
|
||||
entities: {
|
||||
type: Array,
|
||||
computed: 'computeEntities(hass)',
|
||||
},
|
||||
|
||||
entityConfig: {
|
||||
type: Object,
|
||||
value: {
|
||||
component: 'ha-form-customize',
|
||||
computeSelectCaption: stateObj =>
|
||||
window.hassUtil.computeStateName(stateObj) + ' (' + window.hassUtil.computeDomain(stateObj) + ')'
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
computeClasses(isWide) {
|
||||
return isWide ? 'content' : 'content narrow';
|
||||
}
|
||||
|
||||
_backTapped() {
|
||||
history.back();
|
||||
}
|
||||
|
||||
computeEntities(hass) {
|
||||
return Object.keys(hass.states)
|
||||
.map(key => hass.states[key])
|
||||
.sort(window.hassUtil.sortByName);
|
||||
}
|
||||
}
|
||||
customElements.define(HaConfigCustomize.is, HaConfigCustomize);
|
||||
</script>
|
||||
84
panels/config/customize/ha-config-customize.js
Normal file
84
panels/config/customize/ha-config-customize.js
Normal file
@ -0,0 +1,84 @@
|
||||
import '@polymer/app-layout/app-header-layout/app-header-layout.js';
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../../../src/resources/ha-style.js';
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
import '../../../src/util/hass-util.js';
|
||||
import '../ha-config-section.js';
|
||||
import '../ha-entity-config.js';
|
||||
import './ha-form-customize.js';
|
||||
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaConfigCustomize extends window.hassMixins.LocalizeMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style">
|
||||
</style>
|
||||
|
||||
<app-header-layout has-scrolling-region="">
|
||||
<app-header slot="header" fixed="">
|
||||
<app-toolbar>
|
||||
<paper-icon-button icon="mdi:arrow-left" on-click="_backTapped"></paper-icon-button>
|
||||
<div main-title="">[[localize('ui.panel.config.customize.caption')]]</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<div class\$="[[computeClasses(isWide)]]">
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<span slot="header">Customization</span>
|
||||
<span slot="introduction">
|
||||
Tweak per-entity attributes.<br>
|
||||
Added/edited customizations will take effect immediately. Removed customizations will take effect when the entity is updated.
|
||||
</span>
|
||||
<ha-entity-config hass="[[hass]]" label="Entity" entities="[[entities]]" config="[[entityConfig]]">
|
||||
</ha-entity-config>
|
||||
</ha-config-section>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-config-customize'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
|
||||
entities: {
|
||||
type: Array,
|
||||
computed: 'computeEntities(hass)',
|
||||
},
|
||||
|
||||
entityConfig: {
|
||||
type: Object,
|
||||
value: {
|
||||
component: 'ha-form-customize',
|
||||
computeSelectCaption: stateObj =>
|
||||
window.hassUtil.computeStateName(stateObj) + ' (' + window.hassUtil.computeDomain(stateObj) + ')'
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
computeClasses(isWide) {
|
||||
return isWide ? 'content' : 'content narrow';
|
||||
}
|
||||
|
||||
_backTapped() {
|
||||
history.back();
|
||||
}
|
||||
|
||||
computeEntities(hass) {
|
||||
return Object.keys(hass.states)
|
||||
.map(key => hass.states[key])
|
||||
.sort(window.hassUtil.sortByName);
|
||||
}
|
||||
}
|
||||
customElements.define(HaConfigCustomize.is, HaConfigCustomize);
|
||||
@ -1,17 +1,18 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel='import' href="../../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../../src/util/hass-attributes-util.html">
|
||||
import '../../../src/util/hass-attributes-util.js';
|
||||
import '../ha-form-style.js';
|
||||
import './types/ha-customize-array.js';
|
||||
import './types/ha-customize-boolean.js';
|
||||
import './types/ha-customize-icon.js';
|
||||
import './types/ha-customize-key-value.js';
|
||||
import './types/ha-customize-string.js';
|
||||
|
||||
<link rel="import" href="../ha-form-style.html">
|
||||
<link rel="import" href="./types/ha-customize-array.html">
|
||||
<link rel="import" href="./types/ha-customize-boolean.html">
|
||||
<link rel="import" href="./types/ha-customize-icon.html">
|
||||
<link rel="import" href="./types/ha-customize-key-value.html">
|
||||
<link rel="import" href="./types/ha-customize-string.html">
|
||||
|
||||
<dom-module id="ha-customize-attribute">
|
||||
<template>
|
||||
class HaCustomizeAttribute extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-form-style">
|
||||
:host {
|
||||
display: block;
|
||||
@ -26,13 +27,11 @@
|
||||
right: 0;
|
||||
}
|
||||
</style>
|
||||
<div id='wrapper' class='form-group'></div>
|
||||
<div id="wrapper" class="form-group"></div>
|
||||
<paper-icon-button class="button" icon="[[getIcon(item.secondary)]]" on-click="tapButton"></paper-icon-button>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaCustomizeAttribute extends Polymer.Element {
|
||||
static get is() { return 'ha-customize-attribute'; }
|
||||
|
||||
static get properties() {
|
||||
@ -82,4 +81,3 @@ class HaCustomizeAttribute extends Polymer.Element {
|
||||
}
|
||||
}
|
||||
customElements.define(HaCustomizeAttribute.is, HaCustomizeAttribute);
|
||||
</script>
|
||||
@ -1,36 +0,0 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/polymer/lib/mixins/mutable-data.html">
|
||||
|
||||
<link rel="import" href="./ha-customize-attribute.html">
|
||||
|
||||
<dom-module id="ha-form-customize-attributes">
|
||||
<template>
|
||||
<style>
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<template is='dom-repeat' items='{{attributes}}' mutable-data>
|
||||
<ha-customize-attribute
|
||||
item="{{item}}"
|
||||
hidden$="[[item.closed]]">
|
||||
</ha-customize-attribute>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaFormCustomizeAttributes extends Polymer.MutableData(Polymer.Element) {
|
||||
static get is() { return 'ha-form-customize-attributes'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
attributes: {
|
||||
type: Array,
|
||||
notify: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
customElements.define(HaFormCustomizeAttributes.is, HaFormCustomizeAttributes);
|
||||
</script>
|
||||
33
panels/config/customize/ha-form-customize-attributes.js
Normal file
33
panels/config/customize/ha-form-customize-attributes.js
Normal file
@ -0,0 +1,33 @@
|
||||
import { MutableData } from '@polymer/polymer/lib/mixins/mutable-data.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import './ha-customize-attribute.js';
|
||||
|
||||
class HaFormCustomizeAttributes extends MutableData(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<template is="dom-repeat" items="{{attributes}}" mutable-data="">
|
||||
<ha-customize-attribute item="{{item}}" hidden\$="[[item.closed]]">
|
||||
</ha-customize-attribute>
|
||||
</template>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-form-customize-attributes'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
attributes: {
|
||||
type: Array,
|
||||
notify: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
customElements.define(HaFormCustomizeAttributes.is, HaFormCustomizeAttributes);
|
||||
@ -1,15 +1,16 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
|
||||
<link rel='import' href='../../../bower_components/paper-listbox/paper-listbox.html'>
|
||||
<link rel='import' href='../../../bower_components/paper-item/paper-item.html'>
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../../src/util/hass-util.html">
|
||||
<link rel="import" href="../../../src/util/hass-attributes-util.html">
|
||||
import '../../../src/util/hass-attributes-util.js';
|
||||
import '../../../src/util/hass-util.js';
|
||||
import './ha-form-customize-attributes.js';
|
||||
|
||||
<link rel="import" href="./ha-form-customize-attributes.html">
|
||||
|
||||
<dom-module id="ha-form-customize">
|
||||
<template>
|
||||
class HaFormCustomize extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style ha-form-style">
|
||||
.warning {
|
||||
color: red;
|
||||
@ -19,59 +20,50 @@
|
||||
padding-left: 20px;
|
||||
}
|
||||
</style>
|
||||
<template is='dom-if' if='[[computeShowWarning(localConfig, globalConfig)]]'>
|
||||
<template is="dom-if" if="[[computeShowWarning(localConfig, globalConfig)]]">
|
||||
<div class="warning">
|
||||
It seems that your configuration.yaml doesn't properly include customize.yaml<br>
|
||||
Changes made here won't affect your configuration.
|
||||
</div>
|
||||
</template>
|
||||
<template is='dom-if' if='[[hasLocalAttributes]]'>
|
||||
<template is="dom-if" if="[[hasLocalAttributes]]">
|
||||
<h4 class="attributes-text">
|
||||
The following attributes are already set in customize.yaml<br>
|
||||
</h4>
|
||||
<ha-form-customize-attributes attributes="{{localAttributes}}"></ha-form-customize-attributes>
|
||||
</template>
|
||||
<template is='dom-if' if='[[hasGlobalAttributes]]'>
|
||||
<template is="dom-if" if="[[hasGlobalAttributes]]">
|
||||
<h4 class="attributes-text">
|
||||
The following attributes are customized from outside of customize.yaml<br>
|
||||
Possibly via a domain, a glob or a different include.
|
||||
</h4>
|
||||
<ha-form-customize-attributes attributes="{{globalAttributes}}"></ha-form-customize-attributes>
|
||||
</template>
|
||||
<template is='dom-if' if='[[hasExistingAttributes]]'>
|
||||
<template is="dom-if" if="[[hasExistingAttributes]]">
|
||||
<h4 class="attributes-text">
|
||||
The following attributes of the entity are set programatically.<br>
|
||||
You can override them if you like.
|
||||
</h4>
|
||||
<ha-form-customize-attributes attributes="{{existingAttributes}}"></ha-form-customize-attributes>
|
||||
</template>
|
||||
<template is='dom-if' if='[[hasNewAttributes]]'>
|
||||
<template is="dom-if" if="[[hasNewAttributes]]">
|
||||
<h4 class="attributes-text">
|
||||
The following attributes weren't set. Set them if you like.
|
||||
</h4>
|
||||
<ha-form-customize-attributes attributes="{{newAttributes}}"></ha-form-customize-attributes>
|
||||
</template>
|
||||
<div class='form-group'>
|
||||
<paper-dropdown-menu
|
||||
label='Pick an attribute to override'
|
||||
class='flex'
|
||||
dynamic-align
|
||||
>
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
selected='{{selectedNewAttribute}}'
|
||||
>
|
||||
<template is='dom-repeat' items='[[newAttributesOptions]]' as='option'>
|
||||
<div class="form-group">
|
||||
<paper-dropdown-menu label="Pick an attribute to override" class="flex" dynamic-align="">
|
||||
<paper-listbox slot="dropdown-content" selected="{{selectedNewAttribute}}">
|
||||
<template is="dom-repeat" items="[[newAttributesOptions]]" as="option">
|
||||
<paper-item>[[option]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaFormCustomize extends Polymer.Element {
|
||||
static get is() { return 'ha-form-customize'; }
|
||||
|
||||
static get properties() {
|
||||
@ -275,4 +267,3 @@ class HaFormCustomize extends Polymer.Element {
|
||||
}
|
||||
}
|
||||
customElements.define(HaFormCustomize.is, HaFormCustomize);
|
||||
</script>
|
||||
@ -1,36 +1,29 @@
|
||||
<link rel='import' href='../../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href="../../../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
|
||||
<link rel='import' href='../../../../bower_components/paper-listbox/paper-listbox.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-item/paper-item.html'>
|
||||
<link rel="import" href="../../../../src/util/hass-mixins.html">
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id='ha-customize-array'>
|
||||
<template>
|
||||
import '../../../../src/util/hass-mixins.js';
|
||||
|
||||
class HaCustomizeArray extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
paper-dropdown-menu {
|
||||
margin: -9px 0;
|
||||
}
|
||||
</style>
|
||||
<paper-dropdown-menu
|
||||
label='[[item.description]]'
|
||||
disabled='[[item.secondary]]'
|
||||
selected-item-label="{{item.value}}"
|
||||
dynamic-align
|
||||
>
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
selected='[[computeSelected(item)]]'
|
||||
>
|
||||
<template is='dom-repeat' items='[[getOptions(item)]]' as='option'>
|
||||
<paper-dropdown-menu label="[[item.description]]" disabled="[[item.secondary]]" selected-item-label="{{item.value}}" dynamic-align="">
|
||||
<paper-listbox slot="dropdown-content" selected="[[computeSelected(item)]]">
|
||||
<template is="dom-repeat" items="[[getOptions(item)]]" as="option">
|
||||
<paper-item>[[option]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaCustomizeArray extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-customize-array'; }
|
||||
|
||||
static get properties() {
|
||||
@ -59,4 +52,3 @@ class HaCustomizeArray extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
}
|
||||
customElements.define(HaCustomizeArray.is, HaCustomizeArray);
|
||||
</script>
|
||||
@ -1,29 +0,0 @@
|
||||
<link rel='import' href='../../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-checkbox/paper-checkbox.html'>
|
||||
|
||||
<dom-module id='ha-customize-boolean'>
|
||||
<template>
|
||||
<paper-checkbox
|
||||
disabled='[[item.secondary]]'
|
||||
checked="{{item.value}}"
|
||||
>
|
||||
[[item.description]]
|
||||
</paper-checkbox>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaCustomizeBoolean extends Polymer.Element {
|
||||
static get is() { return 'ha-customize-boolean'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
item: {
|
||||
type: Object,
|
||||
notifies: true,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
customElements.define(HaCustomizeBoolean.is, HaCustomizeBoolean);
|
||||
</script>
|
||||
25
panels/config/customize/types/ha-customize-boolean.js
Normal file
25
panels/config/customize/types/ha-customize-boolean.js
Normal file
@ -0,0 +1,25 @@
|
||||
import '@polymer/paper-checkbox/paper-checkbox.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
class HaCustomizeBoolean extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<paper-checkbox disabled="[[item.secondary]]" checked="{{item.value}}">
|
||||
[[item.description]]
|
||||
</paper-checkbox>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-customize-boolean'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
item: {
|
||||
type: Object,
|
||||
notifies: true,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
customElements.define(HaCustomizeBoolean.is, HaCustomizeBoolean);
|
||||
@ -1,42 +0,0 @@
|
||||
<link rel='import' href='../../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../../../bower_components/iron-icon/iron-icon.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-input/paper-input.html'>
|
||||
|
||||
<dom-module id='ha-customize-icon'>
|
||||
<template>
|
||||
<style>
|
||||
:host {
|
||||
@apply --layout-horizontal;
|
||||
}
|
||||
.icon-image {
|
||||
border: 1px solid grey;
|
||||
padding: 8px;
|
||||
margin-right: 20px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
<iron-icon class="icon-image" icon="[[item.value]]"></iron-icon>
|
||||
<paper-input
|
||||
auto-validate pattern="(mdi:.*)?" error-message="Must start with 'mdi:'"
|
||||
disabled='[[item.secondary]]'
|
||||
label='icon'
|
||||
value='{{item.value}}'>
|
||||
</paper-input>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaCustomizeIcon extends Polymer.Element {
|
||||
static get is() { return 'ha-customize-icon'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
item: {
|
||||
type: Object,
|
||||
notifies: true,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
customElements.define(HaCustomizeIcon.is, HaCustomizeIcon);
|
||||
</script>
|
||||
37
panels/config/customize/types/ha-customize-icon.js
Normal file
37
panels/config/customize/types/ha-customize-icon.js
Normal file
@ -0,0 +1,37 @@
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
class HaCustomizeIcon extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
@apply --layout-horizontal;
|
||||
}
|
||||
.icon-image {
|
||||
border: 1px solid grey;
|
||||
padding: 8px;
|
||||
margin-right: 20px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
<iron-icon class="icon-image" icon="[[item.value]]"></iron-icon>
|
||||
<paper-input auto-validate="" pattern="(mdi:.*)?" error-message="Must start with 'mdi:'" disabled="[[item.secondary]]" label="icon" value="{{item.value}}">
|
||||
</paper-input>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-customize-icon'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
item: {
|
||||
type: Object,
|
||||
notifies: true,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
customElements.define(HaCustomizeIcon.is, HaCustomizeIcon);
|
||||
@ -1,45 +0,0 @@
|
||||
<link rel='import' href='../../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-input/paper-input.html'>
|
||||
|
||||
<dom-module id='ha-customize-key-value'>
|
||||
<template>
|
||||
<style>
|
||||
:host {
|
||||
@apply --layout-horizontal;
|
||||
}
|
||||
paper-input {
|
||||
@apply --layout-flex;
|
||||
}
|
||||
.key {
|
||||
padding-right: 20px;
|
||||
}
|
||||
</style>
|
||||
<paper-input
|
||||
disabled='[[item.secondary]]'
|
||||
class='key'
|
||||
label='Attribute name'
|
||||
value='{{item.attribute}}'>
|
||||
</paper-input>
|
||||
<paper-input
|
||||
disabled='[[item.secondary]]'
|
||||
label='Attribute value'
|
||||
value='{{item.value}}'>
|
||||
</paper-input>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaCustomizeKeyValue extends Polymer.Element {
|
||||
static get is() { return 'ha-customize-key-value'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
item: {
|
||||
type: Object,
|
||||
notifies: true,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
customElements.define(HaCustomizeKeyValue.is, HaCustomizeKeyValue);
|
||||
</script>
|
||||
37
panels/config/customize/types/ha-customize-key-value.js
Normal file
37
panels/config/customize/types/ha-customize-key-value.js
Normal file
@ -0,0 +1,37 @@
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
class HaCustomizeKeyValue extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
@apply --layout-horizontal;
|
||||
}
|
||||
paper-input {
|
||||
@apply --layout-flex;
|
||||
}
|
||||
.key {
|
||||
padding-right: 20px;
|
||||
}
|
||||
</style>
|
||||
<paper-input disabled="[[item.secondary]]" class="key" label="Attribute name" value="{{item.attribute}}">
|
||||
</paper-input>
|
||||
<paper-input disabled="[[item.secondary]]" label="Attribute value" value="{{item.value}}">
|
||||
</paper-input>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-customize-key-value'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
item: {
|
||||
type: Object,
|
||||
notifies: true,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
customElements.define(HaCustomizeKeyValue.is, HaCustomizeKeyValue);
|
||||
@ -1,32 +0,0 @@
|
||||
<link rel='import' href='../../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-input/paper-input.html'>
|
||||
|
||||
<dom-module id='ha-customize-string'>
|
||||
<template>
|
||||
<paper-input
|
||||
disabled='[[item.secondary]]'
|
||||
label='[[getLabel(item)]]'
|
||||
value='{{item.value}}'>
|
||||
</paper-input>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaCustomizeString extends Polymer.Element {
|
||||
static get is() { return 'ha-customize-string'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
item: {
|
||||
type: Object,
|
||||
notifies: true,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
getLabel(item) {
|
||||
return item.description + (item.type === 'json' ? ' (JSON formatted)' : '');
|
||||
}
|
||||
}
|
||||
customElements.define(HaCustomizeString.is, HaCustomizeString);
|
||||
</script>
|
||||
28
panels/config/customize/types/ha-customize-string.js
Normal file
28
panels/config/customize/types/ha-customize-string.js
Normal file
@ -0,0 +1,28 @@
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
class HaCustomizeString extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<paper-input disabled="[[item.secondary]]" label="[[getLabel(item)]]" value="{{item.value}}">
|
||||
</paper-input>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-customize-string'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
item: {
|
||||
type: Object,
|
||||
notifies: true,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
getLabel(item) {
|
||||
return item.description + (item.type === 'json' ? ' (JSON formatted)' : '');
|
||||
}
|
||||
}
|
||||
customElements.define(HaCustomizeString.is, HaCustomizeString);
|
||||
@ -1,54 +0,0 @@
|
||||
<link rel="import" href='../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item.html">
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item-body.html">
|
||||
<link rel="import" href="../../../bower_components/iron-icon/iron-icon.html">
|
||||
|
||||
<link rel="import" href="../../../src/util/hass-mixins.html">
|
||||
|
||||
<dom-module id="ha-config-cloud-menu">
|
||||
<template>
|
||||
<style include="iron-flex">
|
||||
paper-card {
|
||||
display: block;
|
||||
}
|
||||
paper-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
<paper-card>
|
||||
<paper-item on-click='_navigate'>
|
||||
<paper-item-body two-line>
|
||||
Home Assistant Cloud
|
||||
<template is='dom-if' if='[[account]]'>
|
||||
<div secondary>Logged in as [[account.email]]</div>
|
||||
</template>
|
||||
<template is='dom-if' if='[[!account]]'>
|
||||
<div secondary>Not logged in</div>
|
||||
</template>
|
||||
</paper-item-body>
|
||||
<iron-icon icon='mdi:chevron-right'></iron-icon>
|
||||
</paper-item>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaConfigCloudMenu extends window.hassMixins.NavigateMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-config-cloud-menu'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
account: Object,
|
||||
};
|
||||
}
|
||||
|
||||
_navigate() {
|
||||
this.navigate('/config/cloud');
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaConfigCloudMenu.is, HaConfigCloudMenu);
|
||||
</script>
|
||||
53
panels/config/dashboard/ha-config-cloud-menu.js
Normal file
53
panels/config/dashboard/ha-config-cloud-menu.js
Normal file
@ -0,0 +1,53 @@
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-item/paper-item-body.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
|
||||
class HaConfigCloudMenu extends window.hassMixins.NavigateMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex">
|
||||
paper-card {
|
||||
display: block;
|
||||
}
|
||||
paper-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
<paper-card>
|
||||
<paper-item on-click="_navigate">
|
||||
<paper-item-body two-line="">
|
||||
Home Assistant Cloud
|
||||
<template is="dom-if" if="[[account]]">
|
||||
<div secondary="">Logged in as [[account.email]]</div>
|
||||
</template>
|
||||
<template is="dom-if" if="[[!account]]">
|
||||
<div secondary="">Not logged in</div>
|
||||
</template>
|
||||
</paper-item-body>
|
||||
<iron-icon icon="mdi:chevron-right"></iron-icon>
|
||||
</paper-item>
|
||||
</paper-card>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-config-cloud-menu'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
account: Object,
|
||||
};
|
||||
}
|
||||
|
||||
_navigate() {
|
||||
this.navigate('/config/cloud');
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaConfigCloudMenu.is, HaConfigCloudMenu);
|
||||
@ -1,83 +0,0 @@
|
||||
<link rel="import" href='../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-header-layout/app-header-layout.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-header/app-header.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
|
||||
<link rel="import" href="../../../src/components/ha-menu-button.html">
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
|
||||
<link rel="import" href="./ha-config-navigation.html">
|
||||
<link rel="import" href="./ha-config-cloud-menu.html">
|
||||
<link rel="import" href="./ha-config-entries-menu.html">
|
||||
|
||||
|
||||
<dom-module id="ha-config-dashboard">
|
||||
<template>
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<app-header-layout has-scrolling-region>
|
||||
<app-header slot="header" fixed>
|
||||
<app-toolbar>
|
||||
<ha-menu-button narrow='[[narrow]]' show-menu='[[showMenu]]'></ha-menu-button>
|
||||
<div main-title>[[localize('panel.configuration')]]</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<div class='content'>
|
||||
<ha-config-section
|
||||
is-wide='[[isWide]]'
|
||||
>
|
||||
<span slot='header'>[[localize('ui.panel.config.header')]]</span>
|
||||
<span slot='introduction'>[[localize('ui.panel.config.introduction')]]</span>
|
||||
|
||||
<template is='dom-if' if='[[computeIsLoaded(hass, "cloud")]]'>
|
||||
<ha-config-cloud-menu
|
||||
hass='[[hass]]'
|
||||
account='[[account]]'
|
||||
></ha-config-cloud-menu>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[computeIsLoaded(hass, "config.config_entries")]]'>
|
||||
<ha-config-entries-menu
|
||||
hass='[[hass]]'
|
||||
></ha-config-entries-menu>
|
||||
</template>
|
||||
|
||||
<ha-config-navigation
|
||||
hass='[[hass]]'
|
||||
></ha-config-navigation>
|
||||
</ha-config-section>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaConfigDashboard extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-config-dashboard'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
account: Object,
|
||||
narrow: Boolean,
|
||||
showMenu: Boolean,
|
||||
};
|
||||
}
|
||||
|
||||
computeIsLoaded(hass, component) {
|
||||
return window.hassUtil.isComponentLoaded(hass, component);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaConfigDashboard.is, HaConfigDashboard);
|
||||
</script>
|
||||
71
panels/config/dashboard/ha-config-dashboard.js
Normal file
71
panels/config/dashboard/ha-config-dashboard.js
Normal file
@ -0,0 +1,71 @@
|
||||
import '@polymer/app-layout/app-header-layout/app-header-layout.js';
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../../../src/components/ha-menu-button.js';
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
import '../ha-config-section.js';
|
||||
import './ha-config-cloud-menu.js';
|
||||
import './ha-config-entries-menu.js';
|
||||
import './ha-config-navigation.js';
|
||||
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaConfigDashboard extends window.hassMixins.LocalizeMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<app-header-layout has-scrolling-region="">
|
||||
<app-header slot="header" fixed="">
|
||||
<app-toolbar>
|
||||
<ha-menu-button narrow="[[narrow]]" show-menu="[[showMenu]]"></ha-menu-button>
|
||||
<div main-title="">[[localize('panel.configuration')]]</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<div class="content">
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<span slot="header">[[localize('ui.panel.config.header')]]</span>
|
||||
<span slot="introduction">[[localize('ui.panel.config.introduction')]]</span>
|
||||
|
||||
<template is="dom-if" if="[[computeIsLoaded(hass, "cloud")]]">
|
||||
<ha-config-cloud-menu hass="[[hass]]" account="[[account]]"></ha-config-cloud-menu>
|
||||
</template>
|
||||
|
||||
<template is="dom-if" if="[[computeIsLoaded(hass, "config.config_entries")]]">
|
||||
<ha-config-entries-menu hass="[[hass]]"></ha-config-entries-menu>
|
||||
</template>
|
||||
|
||||
<ha-config-navigation hass="[[hass]]"></ha-config-navigation>
|
||||
</ha-config-section>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-config-dashboard'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
account: Object,
|
||||
narrow: Boolean,
|
||||
showMenu: Boolean,
|
||||
};
|
||||
}
|
||||
|
||||
computeIsLoaded(hass, component) {
|
||||
return window.hassUtil.isComponentLoaded(hass, component);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaConfigDashboard.is, HaConfigDashboard);
|
||||
@ -1,49 +0,0 @@
|
||||
<link rel="import" href='../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item.html">
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item-body.html">
|
||||
<link rel="import" href="../../../bower_components/iron-icon/iron-icon.html">
|
||||
|
||||
<link rel="import" href="../../../src/util/hass-mixins.html">
|
||||
|
||||
<dom-module id="ha-config-entries-menu">
|
||||
<template>
|
||||
<style include="iron-flex">
|
||||
paper-card {
|
||||
display: block;
|
||||
}
|
||||
paper-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
<paper-card>
|
||||
<paper-item on-click='_navigate'>
|
||||
<paper-item-body two-line>
|
||||
Integrations
|
||||
<div secondary>EXPERIMENTAL – Manage connected devices and services</div>
|
||||
</paper-item-body>
|
||||
<iron-icon icon='mdi:chevron-right'></iron-icon>
|
||||
</paper-item>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaConfigEntriesMenu extends window.hassMixins.NavigateMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-config-entries-menu'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
account: Object,
|
||||
};
|
||||
}
|
||||
|
||||
_navigate() {
|
||||
this.navigate('/config/integrations');
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaConfigEntriesMenu.is, HaConfigEntriesMenu);
|
||||
</script>
|
||||
48
panels/config/dashboard/ha-config-entries-menu.js
Normal file
48
panels/config/dashboard/ha-config-entries-menu.js
Normal file
@ -0,0 +1,48 @@
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-item/paper-item-body.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
|
||||
class HaConfigEntriesMenu extends window.hassMixins.NavigateMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex">
|
||||
paper-card {
|
||||
display: block;
|
||||
}
|
||||
paper-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
<paper-card>
|
||||
<paper-item on-click="_navigate">
|
||||
<paper-item-body two-line="">
|
||||
Integrations
|
||||
<div secondary="">EXPERIMENTAL – Manage connected devices and services</div>
|
||||
</paper-item-body>
|
||||
<iron-icon icon="mdi:chevron-right"></iron-icon>
|
||||
</paper-item>
|
||||
</paper-card>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-config-entries-menu'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
account: Object,
|
||||
};
|
||||
}
|
||||
|
||||
_navigate() {
|
||||
this.navigate('/config/integrations');
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaConfigEntriesMenu.is, HaConfigEntriesMenu);
|
||||
@ -1,38 +1,12 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item.html">
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item-body.html">
|
||||
<link rel="import" href="../../../bower_components/iron-icon/iron-icon.html">
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-item/paper-item-body.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
|
||||
<dom-module id="ha-config-navigation">
|
||||
<template>
|
||||
<style include="iron-flex">
|
||||
paper-card {
|
||||
display: block;
|
||||
}
|
||||
paper-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
<paper-card>
|
||||
<template is='dom-repeat' items='[[pages]]'>
|
||||
<template is='dom-if' if='[[_computeLoaded(hass, item)]]'>
|
||||
<paper-item on-click='_navigate'>
|
||||
<paper-item-body two-line>
|
||||
[[_computeCaption(item, localize)]]
|
||||
<div secondary>[[_computeDescription(item, localize)]]</div>
|
||||
</paper-item-body>
|
||||
<iron-icon icon='mdi:chevron-right'></iron-icon>
|
||||
</paper-item>
|
||||
</template>
|
||||
</template>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
{
|
||||
const CORE_PAGES = [
|
||||
'core',
|
||||
@ -43,7 +17,33 @@
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaConfigNavigation extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.NavigateMixin(Polymer.Element)) {
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.NavigateMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex">
|
||||
paper-card {
|
||||
display: block;
|
||||
}
|
||||
paper-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
<paper-card>
|
||||
<template is="dom-repeat" items="[[pages]]">
|
||||
<template is="dom-if" if="[[_computeLoaded(hass, item)]]">
|
||||
<paper-item on-click="_navigate">
|
||||
<paper-item-body two-line="">
|
||||
[[_computeCaption(item, localize)]]
|
||||
<div secondary="">[[_computeDescription(item, localize)]]</div>
|
||||
</paper-item-body>
|
||||
<iron-icon icon="mdi:chevron-right"></iron-icon>
|
||||
</paper-item>
|
||||
</template>
|
||||
</template>
|
||||
</paper-card>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-config-navigation'; }
|
||||
|
||||
static get properties() {
|
||||
@ -84,4 +84,3 @@
|
||||
|
||||
customElements.define(HaConfigNavigation.is, HaConfigNavigation);
|
||||
}
|
||||
</script>
|
||||
@ -1 +0,0 @@
|
||||
<script src='../../build-temp/panel-config.js'></script>
|
||||
1
panels/config/ha-config-js.js
Normal file
1
panels/config/ha-config-js.js
Normal file
@ -0,0 +1 @@
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../src/resources/ha-style.html">
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id="ha-config-section">
|
||||
<template>
|
||||
import '../../src/resources/ha-style.js';
|
||||
|
||||
class HaConfigSection extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
padding: 28px 20px 0;
|
||||
@ -52,22 +55,20 @@
|
||||
max-width: 500px;
|
||||
}
|
||||
</style>
|
||||
<div class$='[[computeContentClasses(isWide)]]'>
|
||||
<div class='header'><slot name="header"></slot></div>
|
||||
<div class$='[[computeClasses(isWide)]]'>
|
||||
<div class='intro'>
|
||||
<div class\$="[[computeContentClasses(isWide)]]">
|
||||
<div class="header"><slot name="header"></slot></div>
|
||||
<div class\$="[[computeClasses(isWide)]]">
|
||||
<div class="intro">
|
||||
<slot name="introduction"></slot>
|
||||
</div>
|
||||
<div class='panel flex-auto'>
|
||||
<div class="panel flex-auto">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaConfigSection extends Polymer.Element {
|
||||
static get is() { return 'ha-config-section'; }
|
||||
|
||||
static get properties() {
|
||||
@ -106,4 +107,3 @@ class HaConfigSection extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HaConfigSection.is, HaConfigSection);
|
||||
</script>
|
||||
@ -1,13 +1,15 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="../../bower_components/paper-spinner/paper-spinner.html">
|
||||
<link rel="import" href="../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
|
||||
<link rel="import" href="../../bower_components/paper-listbox/paper-listbox.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../bower_components/paper-item/paper-item.html">
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import '@polymer/paper-spinner/paper-spinner.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id="ha-entity-config">
|
||||
<template>
|
||||
class HaEntityConfig extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
paper-card {
|
||||
display: block;
|
||||
@ -34,61 +36,44 @@
|
||||
}
|
||||
</style>
|
||||
<paper-card>
|
||||
<div class='card-content'>
|
||||
<div class='device-picker'>
|
||||
<paper-dropdown-menu
|
||||
label='[[label]]'
|
||||
class='flex'
|
||||
disabled='[[!entities.length]]'
|
||||
>
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
selected='{{selectedEntity}}'
|
||||
>
|
||||
<template is='dom-repeat' items='[[entities]]' as='state'>
|
||||
<div class="card-content">
|
||||
<div class="device-picker">
|
||||
<paper-dropdown-menu label="[[label]]" class="flex" disabled="[[!entities.length]]">
|
||||
<paper-listbox slot="dropdown-content" selected="{{selectedEntity}}">
|
||||
<template is="dom-repeat" items="[[entities]]" as="state">
|
||||
<paper-item>[[computeSelectCaption(state)]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</div>
|
||||
|
||||
<div class='form-container'>
|
||||
<template is='dom-if' if='[[computeShowPlaceholder(formState)]]'>
|
||||
<div class='form-placeholder'>
|
||||
<template is='dom-if' if='[[computeShowNoDevices(formState)]]'>
|
||||
<div class="form-container">
|
||||
<template is="dom-if" if="[[computeShowPlaceholder(formState)]]">
|
||||
<div class="form-placeholder">
|
||||
<template is="dom-if" if="[[computeShowNoDevices(formState)]]">
|
||||
No entities found! :-(
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[computeShowSpinner(formState)]]'>
|
||||
<paper-spinner active alt='[[formState]]'></paper-spinner>
|
||||
<template is="dom-if" if="[[computeShowSpinner(formState)]]">
|
||||
<paper-spinner active="" alt="[[formState]]"></paper-spinner>
|
||||
[[formState]]
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div hidden$='[[!computeShowForm(formState)]]' id='form'></div>
|
||||
<div hidden\$="[[!computeShowForm(formState)]]" id="form"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<paper-button
|
||||
on-click='saveEntity'
|
||||
disabled='[[computeShowPlaceholder(formState)]]'
|
||||
>SAVE</paper-button>
|
||||
<template is='dom-if' if='[[allowDelete]]'>
|
||||
<paper-button
|
||||
class='warning'
|
||||
on-click='deleteEntity'
|
||||
disabled='[[computeShowPlaceholder(formState)]]'
|
||||
>DELETE</paper-button>
|
||||
<div class="card-actions">
|
||||
<paper-button on-click="saveEntity" disabled="[[computeShowPlaceholder(formState)]]">SAVE</paper-button>
|
||||
<template is="dom-if" if="[[allowDelete]]">
|
||||
<paper-button class="warning" on-click="deleteEntity" disabled="[[computeShowPlaceholder(formState)]]">DELETE</paper-button>
|
||||
</template>
|
||||
</div>
|
||||
</paper-card>
|
||||
`;
|
||||
}
|
||||
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaEntityConfig extends Polymer.Element {
|
||||
static get is() { return 'ha-entity-config'; }
|
||||
|
||||
static get properties() {
|
||||
@ -214,4 +199,3 @@ class HaEntityConfig extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HaEntityConfig.is, HaEntityConfig);
|
||||
</script>
|
||||
@ -1,4 +1,7 @@
|
||||
<dom-module id='ha-form-style'>
|
||||
const documentContainer = document.createElement('template');
|
||||
documentContainer.setAttribute('style', 'display: none;');
|
||||
|
||||
documentContainer.innerHTML = `<dom-module id="ha-form-style">
|
||||
<template>
|
||||
<style>
|
||||
.form-group {
|
||||
@ -25,4 +28,6 @@
|
||||
}
|
||||
</style>
|
||||
</template>
|
||||
</dom-module>
|
||||
</dom-module>`;
|
||||
|
||||
document.head.appendChild(documentContainer.content);
|
||||
@ -1,21 +1,24 @@
|
||||
<link rel="import" href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../bower_components/iron-media-query/iron-media-query.html'>
|
||||
<link rel='import' href='../../bower_components/app-route/app-route.html'>
|
||||
import '@polymer/app-route/app-route.js';
|
||||
import '@polymer/iron-media-query/iron-media-query.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../src/layouts/hass-error-screen.html">
|
||||
<link rel="import" href="../../src/util/hass-mixins.html">
|
||||
import '../../build-temp/panel-config.js';
|
||||
import '../../src/layouts/hass-error-screen.js';
|
||||
import '../../src/util/hass-mixins.js';
|
||||
import './automation/ha-config-automation.js';
|
||||
import './cloud/ha-config-cloud.js';
|
||||
import './config-entries/ha-config-entries.js';
|
||||
import './core/ha-config-core.js';
|
||||
import './customize/ha-config-customize.js';
|
||||
import './dashboard/ha-config-dashboard.js';
|
||||
import './script/ha-config-script.js';
|
||||
import './zwave/ha-config-zwave.js';
|
||||
|
||||
<link rel="import" href="./dashboard/ha-config-dashboard.html">
|
||||
<link rel="import" href="./core/ha-config-core.html">
|
||||
<link rel="import" href="./cloud/ha-config-cloud.html">
|
||||
<link rel="import" href="./automation/ha-config-automation.html">
|
||||
<link rel="import" href="./script/ha-config-script.html">
|
||||
<link rel="import" href="./zwave/ha-config-zwave.html">
|
||||
<link rel="import" href="./customize/ha-config-customize.html">
|
||||
<link rel="import" href="./config-entries/ha-config-entries.html">
|
||||
|
||||
<dom-module id="ha-panel-config">
|
||||
<template>
|
||||
class HaPanelConfig extends window.hassMixins.NavigateMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<app-route
|
||||
route='[[route]]'
|
||||
pattern='/:page'
|
||||
@ -97,11 +100,9 @@
|
||||
is-wide='[[isWide]]'
|
||||
></ha-config-entries>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaPanelConfig extends window.hassMixins.NavigateMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-panel-config'; }
|
||||
|
||||
static get properties() {
|
||||
@ -154,4 +155,3 @@ class HaPanelConfig extends window.hassMixins.NavigateMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HaPanelConfig.is, HaPanelConfig);
|
||||
</script>
|
||||
@ -1,52 +1,32 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel='import' href='../../../bower_components/app-route/app-route.html'>
|
||||
import '@polymer/app-route/app-route.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="./ha-script-picker.html">
|
||||
<link rel="import" href="./ha-script-editor.html">
|
||||
import './ha-script-editor.js';
|
||||
import './ha-script-picker.js';
|
||||
|
||||
<dom-module id="ha-config-script">
|
||||
<template>
|
||||
class HaConfigScript extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
ha-script-picker,
|
||||
ha-script-editor {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
<app-route
|
||||
route='[[route]]'
|
||||
pattern='/script/edit/:script'
|
||||
data="{{_routeData}}"
|
||||
active="{{_edittingScript}}"
|
||||
></app-route>
|
||||
<app-route
|
||||
route='[[route]]'
|
||||
pattern='/script/new'
|
||||
active="{{_creatingNew}}"
|
||||
></app-route>
|
||||
<app-route route="[[route]]" pattern="/script/edit/:script" data="{{_routeData}}" active="{{_edittingScript}}"></app-route>
|
||||
<app-route route="[[route]]" pattern="/script/new" active="{{_creatingNew}}"></app-route>
|
||||
|
||||
<template is='dom-if' if='[[!showEditor]]'>
|
||||
<ha-script-picker
|
||||
hass='[[hass]]'
|
||||
narrow='[[narrow]]'
|
||||
show-menu='[[showMenu]]'
|
||||
scripts='[[scripts]]'
|
||||
is-wide='[[isWide]]'
|
||||
></ha-script-picker>
|
||||
<template is="dom-if" if="[[!showEditor]]">
|
||||
<ha-script-picker hass="[[hass]]" narrow="[[narrow]]" show-menu="[[showMenu]]" scripts="[[scripts]]" is-wide="[[isWide]]"></ha-script-picker>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[showEditor]]' restamp>
|
||||
<ha-script-editor
|
||||
hass='[[hass]]'
|
||||
script='[[script]]'
|
||||
is-wide='[[isWide]]'
|
||||
creating-new='[[_creatingNew]]'
|
||||
></ha-script-editor>
|
||||
<template is="dom-if" if="[[showEditor]]" restamp="">
|
||||
<ha-script-editor hass="[[hass]]" script="[[script]]" is-wide="[[isWide]]" creating-new="[[_creatingNew]]"></ha-script-editor>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaConfigScript extends Polymer.Element {
|
||||
static get is() { return 'ha-config-script'; }
|
||||
|
||||
static get properties() {
|
||||
@ -121,4 +101,3 @@ class HaConfigScript extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HaConfigScript.is, HaConfigScript);
|
||||
</script>
|
||||
@ -1,31 +1,34 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-header/app-header.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item.html">
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item-body.html">
|
||||
<link rel="import" href="../../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-input/paper-input.html">
|
||||
<link rel="import" href="../../../bower_components/paper-input/paper-textarea.html">
|
||||
<link rel="import" href="../../../bower_components/paper-radio-button/paper-radio-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-radio-group/paper-radio-group.html">
|
||||
<link rel="import" href="../../../bower_components/paper-dropdown-menu/paper-dropdown-menu-light.html">
|
||||
<link rel="import" href="../../../bower_components/paper-listbox/paper-listbox.html">
|
||||
<link rel="import" href="../../../bower_components/paper-menu-button/paper-menu-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-fab/paper-fab.html">
|
||||
<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/iron-autogrow-textarea/iron-autogrow-textarea.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu-light.js';
|
||||
import '@polymer/paper-fab/paper-fab.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import '@polymer/paper-input/paper-textarea.js';
|
||||
import '@polymer/paper-item/paper-item-body.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import '@polymer/paper-menu-button/paper-menu-button.js';
|
||||
import '@polymer/paper-radio-button/paper-radio-button.js';
|
||||
import '@polymer/paper-radio-group/paper-radio-group.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../../src/components/entity/ha-entity-picker.html'>
|
||||
<link rel='import' href='../../../src/components/ha-combo-box.html'>
|
||||
<link rel='import' href='../../../src/layouts/ha-app-layout.html'>
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
import '../../../src/components/entity/ha-entity-picker.js';
|
||||
import '../../../src/components/ha-combo-box.js';
|
||||
import '../../../src/layouts/ha-app-layout.js';
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
import '../ha-config-js.js';
|
||||
import '../ha-config-section.js';
|
||||
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
|
||||
<link rel="import" href="../ha-config-js.html">
|
||||
|
||||
<dom-module id="ha-script-editor">
|
||||
<template>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaScriptEditor extends window.hassMixins.LocalizeMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style">
|
||||
.errors {
|
||||
padding: 20px;
|
||||
@ -81,39 +84,24 @@
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
<ha-app-layout has-scrolling-region>
|
||||
<app-header slot="header" fixed>
|
||||
<ha-app-layout has-scrolling-region="">
|
||||
<app-header slot="header" fixed="">
|
||||
<app-toolbar>
|
||||
<paper-icon-button
|
||||
icon='mdi:arrow-left'
|
||||
on-click='backTapped'
|
||||
></paper-icon-button>
|
||||
<div main-title>Script [[name]]</div>
|
||||
<paper-icon-button icon="mdi:arrow-left" on-click="backTapped"></paper-icon-button>
|
||||
<div main-title="">Script [[name]]</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
<div class='content'>
|
||||
<template is='dom-if' if='[[errors]]'>
|
||||
<div class='errors'>[[errors]]</div>
|
||||
<div class="content">
|
||||
<template is="dom-if" if="[[errors]]">
|
||||
<div class="errors">[[errors]]</div>
|
||||
</template>
|
||||
<div id='root'></div>
|
||||
<div id="root"></div>
|
||||
</div>
|
||||
<paper-fab slot="fab"
|
||||
is-wide$='[[isWide]]'
|
||||
dirty$='[[dirty]]'
|
||||
icon='mdi:content-save'
|
||||
title='Save'
|
||||
on-click='saveScript'
|
||||
></paper-fab>
|
||||
<paper-fab slot="fab" is-wide\$="[[isWide]]" dirty\$="[[dirty]]" icon="mdi:content-save" title="Save" on-click="saveScript"></paper-fab>
|
||||
</ha-app-layout>
|
||||
`;
|
||||
}
|
||||
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaScriptEditor extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-script-editor'; }
|
||||
|
||||
static get properties() {
|
||||
@ -286,4 +274,3 @@ class HaScriptEditor extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HaScriptEditor.is, HaScriptEditor);
|
||||
</script>
|
||||
@ -1,150 +0,0 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-header/app-header.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item.html">
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item-body.html">
|
||||
<link rel="import" href="../../../bower_components/paper-fab/paper-fab.html">
|
||||
<link rel="import" href="../../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
|
||||
<link rel='import' href='../../../src/layouts/ha-app-layout.html'>
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
|
||||
<dom-module id="ha-script-picker">
|
||||
<template>
|
||||
<style include="ha-style">
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
|
||||
paper-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
paper-fab {
|
||||
position: fixed;
|
||||
bottom: 16px;
|
||||
right: 16px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
paper-fab[is-wide] {
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
</style>
|
||||
|
||||
<ha-app-layout has-scrolling-region>
|
||||
<app-header slot="header" fixed>
|
||||
<app-toolbar>
|
||||
<paper-icon-button
|
||||
icon='mdi:arrow-left'
|
||||
on-click='_backTapped'
|
||||
></paper-icon-button>
|
||||
<div main-title>[[localize('ui.panel.config.script.caption')]]</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<ha-config-section
|
||||
is-wide='[[isWide]]'
|
||||
>
|
||||
<div slot='header'>Script Editor</div>
|
||||
<div slot='introduction'>
|
||||
The script editor allows you to create and edit scripts.
|
||||
Please read <a href='https://home-assistant.io/docs/scripts/editor/' target='_blank'>the instructions</a> to make sure that you have configured Home Assistant correctly.
|
||||
</div>
|
||||
|
||||
<paper-card heading='Pick script to edit'>
|
||||
<template is='dom-if' if='[[!scripts.length]]'>
|
||||
<div class='card-content'>
|
||||
<p>We couldn't find any editable scripts.</p>
|
||||
</div>
|
||||
</template>
|
||||
<template is='dom-repeat' items='[[scripts]]' as='script'>
|
||||
<paper-item>
|
||||
<paper-item-body two-line on-click='scriptTapped'>
|
||||
<div>[[computeName(script)]]</div>
|
||||
<div secondary>[[computeDescription(script)]]</div>
|
||||
</paper-item-body>
|
||||
<iron-icon icon='mdi:chevron-right'></iron-icon>
|
||||
</paper-item>
|
||||
</template>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
|
||||
<paper-fab slot="fab"
|
||||
is-wide$='[[isWide]]'
|
||||
icon='mdi:plus'
|
||||
title='Add Script'
|
||||
on-click='addScript'
|
||||
></paper-fab>
|
||||
</ha-app-layout>
|
||||
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaScriptPicker extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.NavigateMixin(Polymer.Element)) {
|
||||
static get is() { return 'ha-script-picker'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
narrow: {
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
showMenu: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
scripts: {
|
||||
type: Array,
|
||||
},
|
||||
|
||||
isWide: {
|
||||
type: Boolean,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
scriptTapped(ev) {
|
||||
this.navigate('/config/script/edit/' + this.scripts[ev.model.index].entity_id);
|
||||
}
|
||||
|
||||
addScript() {
|
||||
this.navigate('/config/script/new');
|
||||
}
|
||||
|
||||
computeName(script) {
|
||||
return window.hassUtil.computeStateName(script);
|
||||
}
|
||||
|
||||
// Still thinking of something to add here.
|
||||
// eslint-disable-next-line
|
||||
computeDescription(script) {
|
||||
return '';
|
||||
}
|
||||
|
||||
_backTapped() {
|
||||
history.back();
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaScriptPicker.is, HaScriptPicker);
|
||||
</script>
|
||||
137
panels/config/script/ha-script-picker.js
Normal file
137
panels/config/script/ha-script-picker.js
Normal file
@ -0,0 +1,137 @@
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-fab/paper-fab.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-item/paper-item-body.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../../../src/layouts/ha-app-layout.js';
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
import '../ha-config-section.js';
|
||||
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaScriptPicker extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.NavigateMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style">
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
|
||||
paper-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
paper-fab {
|
||||
position: fixed;
|
||||
bottom: 16px;
|
||||
right: 16px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
paper-fab[is-wide] {
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
</style>
|
||||
|
||||
<ha-app-layout has-scrolling-region="">
|
||||
<app-header slot="header" fixed="">
|
||||
<app-toolbar>
|
||||
<paper-icon-button icon="mdi:arrow-left" on-click="_backTapped"></paper-icon-button>
|
||||
<div main-title="">[[localize('ui.panel.config.script.caption')]]</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<div slot="header">Script Editor</div>
|
||||
<div slot="introduction">
|
||||
The script editor allows you to create and edit scripts.
|
||||
Please read <a href="https://home-assistant.io/docs/scripts/editor/" target="_blank">the instructions</a> to make sure that you have configured Home Assistant correctly.
|
||||
</div>
|
||||
|
||||
<paper-card heading="Pick script to edit">
|
||||
<template is="dom-if" if="[[!scripts.length]]">
|
||||
<div class="card-content">
|
||||
<p>We couldn't find any editable scripts.</p>
|
||||
</div>
|
||||
</template>
|
||||
<template is="dom-repeat" items="[[scripts]]" as="script">
|
||||
<paper-item>
|
||||
<paper-item-body two-line="" on-click="scriptTapped">
|
||||
<div>[[computeName(script)]]</div>
|
||||
<div secondary="">[[computeDescription(script)]]</div>
|
||||
</paper-item-body>
|
||||
<iron-icon icon="mdi:chevron-right"></iron-icon>
|
||||
</paper-item>
|
||||
</template>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
|
||||
<paper-fab slot="fab" is-wide\$="[[isWide]]" icon="mdi:plus" title="Add Script" on-click="addScript"></paper-fab>
|
||||
</ha-app-layout>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-script-picker'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
narrow: {
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
showMenu: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
scripts: {
|
||||
type: Array,
|
||||
},
|
||||
|
||||
isWide: {
|
||||
type: Boolean,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
scriptTapped(ev) {
|
||||
this.navigate('/config/script/edit/' + this.scripts[ev.model.index].entity_id);
|
||||
}
|
||||
|
||||
addScript() {
|
||||
this.navigate('/config/script/new');
|
||||
}
|
||||
|
||||
computeName(script) {
|
||||
return window.hassUtil.computeStateName(script);
|
||||
}
|
||||
|
||||
// Still thinking of something to add here.
|
||||
// eslint-disable-next-line
|
||||
computeDescription(script) {
|
||||
return '';
|
||||
}
|
||||
|
||||
_backTapped() {
|
||||
history.back();
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaScriptPicker.is, HaScriptPicker);
|
||||
@ -1,618 +0,0 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../src/components/ha-menu-button.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-header/app-header.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
<link rel="import" href="../../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
|
||||
<link rel='import' href='../../../bower_components/paper-item/paper-item.html'>
|
||||
<link rel='import' href="../../../bower_components/paper-listbox/paper-listbox.html">
|
||||
<link rel='import' href="../../../bower_components/paper-input/paper-input.html">
|
||||
|
||||
<link rel="import" href="../../../src/components/buttons/ha-call-service-button.html">
|
||||
<link rel="import" href="../../../src/components/ha-service-description.html">
|
||||
<link rel='import' href='../../../src/layouts/ha-app-layout.html'>
|
||||
<link rel="import" href="../../../src/resources/ha-style.html">
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
<link rel="import" href="../ha-form-style.html">
|
||||
|
||||
<link rel="import" href="./zwave-log.html">
|
||||
<link rel="import" href="./zwave-network.html">
|
||||
<link rel="import" href="./zwave-node-information.html">
|
||||
<link rel="import" href="./zwave-values.html">
|
||||
<link rel="import" href="./zwave-groups.html">
|
||||
<link rel="import" href="./zwave-node-config.html">
|
||||
<link rel="import" href="./zwave-usercodes.html">
|
||||
|
||||
<dom-module id="ha-config-zwave">
|
||||
<template>
|
||||
<style include="iron-flex ha-style ha-form-style">
|
||||
.content {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.node-info {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.help-text {
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
paper-card {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.device-picker {
|
||||
@apply --layout-horizontal;
|
||||
@apply --layout-center-center;
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
|
||||
ha-service-description {
|
||||
display: block;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.toggle-help-icon {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
right: 0;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
</style>
|
||||
<ha-app-layout has-scrolling-region>
|
||||
<app-header slot="header" fixed>
|
||||
<app-toolbar>
|
||||
<paper-icon-button
|
||||
icon='mdi:arrow-left'
|
||||
on-click='_backTapped'
|
||||
></paper-icon-button>
|
||||
<div main-title>[[localize('ui.panel.config.zwave.caption')]]</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<zwave-network
|
||||
id='zwave-network'
|
||||
is-wide='[[isWide]]'
|
||||
hass='[[hass]]'
|
||||
></zwave-network>
|
||||
|
||||
<!--Node card-->
|
||||
<ha-config-section is-wide='[[isWide]]'>
|
||||
<div style="position: relative" slot='header'>
|
||||
<span>Z-Wave Node Management</span>
|
||||
<paper-icon-button
|
||||
class="toggle-help-icon"
|
||||
on-click='toggleHelp'
|
||||
icon='mdi:help-circle'
|
||||
></paper-icon-button>
|
||||
|
||||
</div>
|
||||
<span slot='introduction'>
|
||||
Run Z-Wave commands that affect a single node. Pick a node to see a list of available commands.
|
||||
</span>
|
||||
|
||||
<paper-card class="content">
|
||||
<div class='device-picker'>
|
||||
<paper-dropdown-menu dynamic-align label="Nodes" class="flex">
|
||||
<paper-listbox slot="dropdown-content" selected='{{selectedNode}}'>
|
||||
<template is='dom-repeat' items='[[nodes]]' as='state'>
|
||||
<paper-item>[[computeSelectCaption(state)]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</div>
|
||||
<template is='dom-if' if='[[!computeIsNodeSelected(selectedNode)]]'>
|
||||
<template is='dom-if' if='[[showHelp]]'>
|
||||
<div style='color: grey; padding: 12px'>Select node to view per-node options</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[computeIsNodeSelected(selectedNode)]]'>
|
||||
<div class='card-actions'>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='refresh_node'
|
||||
service-data=[[computeNodeServiceData(selectedNode)]]
|
||||
>Refresh Node</ha-call-service-button>
|
||||
<ha-service-description
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='refresh_node'
|
||||
hidden$='[[!showHelp]]'
|
||||
></ha-service-description>
|
||||
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='remove_failed_node'
|
||||
service-data=[[computeNodeServiceData(selectedNode)]]
|
||||
>Remove Failed Node</ha-call-service-button>
|
||||
<ha-service-description
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='remove_failed_node'
|
||||
hidden$='[[!showHelp]]'
|
||||
></ha-service-description>
|
||||
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='replace_failed_node'
|
||||
service-data=[[computeNodeServiceData(selectedNode)]]
|
||||
>Replace Failed Node</ha-call-service-button>
|
||||
<ha-service-description
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='replace_failed_node'
|
||||
hidden$='[[!showHelp]]'
|
||||
></ha-service-description>
|
||||
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='print_node'
|
||||
service-data=[[computeNodeServiceData(selectedNode)]]
|
||||
>Print Node</ha-call-service-button>
|
||||
<ha-service-description
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='print_node'
|
||||
hidden$='[[!showHelp]]'
|
||||
></ha-service-description>
|
||||
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='heal_node'
|
||||
service-data=[[computeHealNodeServiceData(selectedNode)]]
|
||||
>Heal Node</ha-call-service-button>
|
||||
<ha-service-description
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='heal_node'
|
||||
hidden$='[[!showHelp]]'
|
||||
></ha-service-description>
|
||||
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='test_node'
|
||||
service-data=[[computeNodeServiceData(selectedNode)]]
|
||||
>Test Node</ha-call-service-button>
|
||||
<ha-service-description
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='test_node'
|
||||
hidden$='[[!showHelp]]'
|
||||
></ha-service-description>
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<paper-input
|
||||
float-label="New node name"
|
||||
type=text
|
||||
value={{newNodeNameInput}}
|
||||
placeholder=[[computeGetNodeName(selectedNode)]]>
|
||||
</paper-input>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='rename_node'
|
||||
service-data=[[computeNodeNameServiceData(newNodeNameInput)]]
|
||||
>Rename Node</ha-call-service-button>
|
||||
<ha-service-description
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='rename_node'
|
||||
hidden$='[[!showHelp]]'
|
||||
></ha-service-description>
|
||||
</div>
|
||||
|
||||
<div class='device-picker'>
|
||||
<paper-dropdown-menu label="Entities of this node" dynamic-align class="flex">
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
selected='{{selectedEntity}}'>
|
||||
<template is='dom-repeat' items='[[entities]]' as='state'>
|
||||
<paper-item>[[computeSelectCaptionEnt(state)]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</div>
|
||||
<template is='dom-if' if='[[!computeIsEntitySelected(selectedEntity)]]'>
|
||||
<div class='card-actions'>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='refresh_entity'
|
||||
service-data=[[computeRefreshEntityServiceData(selectedEntity)]]
|
||||
>Refresh Entity</ha-call-service-button>
|
||||
<ha-service-description
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='refresh_entity'
|
||||
hidden$='[[!showHelp]]'
|
||||
></ha-service-description>
|
||||
</div>
|
||||
<div class='form-group'>
|
||||
<paper-checkbox
|
||||
checked='{{entityIgnored}}'
|
||||
class='form-control'
|
||||
>
|
||||
Exclude this entity from Home Assistant
|
||||
</paper-checkbox>
|
||||
<paper-input
|
||||
disabled='{{entityIgnored}}'
|
||||
label="Polling intensity"
|
||||
type=number
|
||||
min=0
|
||||
value={{entityPollingIntensity}}>
|
||||
</paper-input>
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='set_poll_intensity'
|
||||
service-data=[[computePollIntensityServiceData(entityPollingIntensity)]]
|
||||
>Save</ha-call-service-button>
|
||||
</div>
|
||||
<div class='content'>
|
||||
<div class='card-actions'>
|
||||
<paper-button toggles raised noink active={{entityInfoActive}}>Entity Attributes</paper-button>
|
||||
</div>
|
||||
<template is='dom-if' if={{entityInfoActive}}>
|
||||
<template is='dom-repeat' items='[[selectedEntityAttrs]]' as='state'>
|
||||
<div class='node-info'>
|
||||
<span>[[state]]</span>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
</template>
|
||||
</paper-card>
|
||||
|
||||
<template is='dom-if' if='[[computeIsNodeSelected(selectedNode)]]'>
|
||||
<!--Node info card-->
|
||||
<zwave-node-information
|
||||
id='zwave-node-information'
|
||||
nodes='[[nodes]]'
|
||||
selected-node='[[selectedNode]]'
|
||||
></zwave-node-information>
|
||||
|
||||
<!--Value card-->
|
||||
<zwave-values
|
||||
hass='[[hass]]'
|
||||
nodes='[[nodes]]'
|
||||
selected-node='[[selectedNode]]'
|
||||
values='[[values]]'
|
||||
></zwave-values>
|
||||
|
||||
<!--Group card-->
|
||||
<zwave-groups
|
||||
hass='[[hass]]'
|
||||
nodes='[[nodes]]'
|
||||
selected-node='[[selectedNode]]'
|
||||
groups='[[groups]]'
|
||||
></zwave-groups>
|
||||
|
||||
<!--Config card-->
|
||||
<zwave-node-config
|
||||
hass='[[hass]]'
|
||||
nodes='[[nodes]]'
|
||||
selected-node='[[selectedNode]]'
|
||||
config='[[config]]'
|
||||
></zwave-node-config>
|
||||
</template>
|
||||
|
||||
<!--User Codes-->
|
||||
<template is='dom-if' if='{{hasNodeUserCodes}}'>
|
||||
<zwave-usercodes
|
||||
id='zwave-usercodes'
|
||||
hass='[[hass]]'
|
||||
nodes='[[nodes]]'
|
||||
user-codes='[[userCodes]]'
|
||||
selected-node='[[selectedNode]]'
|
||||
></zwave-usercodes>
|
||||
</template>
|
||||
</ha-config-section>
|
||||
|
||||
|
||||
|
||||
<!--Ozw log-->
|
||||
<ozw-log
|
||||
is-wide='[[isWide]]'
|
||||
hass='[[hass]]'
|
||||
></ozw-log>
|
||||
|
||||
</ha-app-layout>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaConfigZwave extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-config-zwave'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
|
||||
nodes: {
|
||||
type: Array,
|
||||
computed: 'computeNodes(hass)'
|
||||
},
|
||||
|
||||
selectedNode: {
|
||||
type: Number,
|
||||
value: -1,
|
||||
observer: 'selectedNodeChanged'
|
||||
},
|
||||
|
||||
config: {
|
||||
type: Array,
|
||||
value: function () {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
|
||||
entities: {
|
||||
type: Array,
|
||||
computed: 'computeEntities(selectedNode)',
|
||||
},
|
||||
|
||||
entityInfoActive: {
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
selectedEntity: {
|
||||
type: Number,
|
||||
value: -1,
|
||||
observer: 'selectedEntityChanged',
|
||||
},
|
||||
|
||||
selectedEntityAttrs: {
|
||||
type: Array,
|
||||
computed: 'computeSelectedEntityAttrs(selectedEntity)'
|
||||
},
|
||||
|
||||
values: {
|
||||
type: Array,
|
||||
},
|
||||
|
||||
groups: {
|
||||
type: Array,
|
||||
},
|
||||
|
||||
newNodeNameInput: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
userCodes: {
|
||||
type: Array,
|
||||
value: function () {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
|
||||
hasNodeUserCodes: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
showHelp: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
entityIgnored: {
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
entityPollingIntensity: {
|
||||
type: Number,
|
||||
value: 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
ready() {
|
||||
super.ready();
|
||||
this.addEventListener('hass-service-called', ev => this.serviceCalled(ev));
|
||||
}
|
||||
|
||||
serviceCalled(ev) {
|
||||
var el = this;
|
||||
if ((ev.detail.success) && (ev.detail.service === 'set_poll_intensity')) {
|
||||
el.saveEntity();
|
||||
}
|
||||
}
|
||||
|
||||
computeNodes(hass) {
|
||||
return Object.keys(hass.states)
|
||||
.map(function (key) { return hass.states[key]; })
|
||||
.filter(function (ent) {
|
||||
return ((ent.entity_id).match('zwave[.]'));
|
||||
})
|
||||
.sort(window.hassUtil.sortByName);
|
||||
}
|
||||
|
||||
computeEntities(selectedNode) {
|
||||
if (!this.nodes || selectedNode === -1) return -1;
|
||||
var hass = this.hass;
|
||||
var nodeid = this.nodes[this.selectedNode].attributes.node_id;
|
||||
return Object.keys(hass.states)
|
||||
.map(function (key) { return hass.states[key]; })
|
||||
.filter(function (ent) {
|
||||
if (ent.attributes.node_id === undefined) {
|
||||
return false;
|
||||
}
|
||||
return (!ent.attributes.hidden &&
|
||||
'node_id' in ent.attributes &&
|
||||
ent.attributes.node_id === nodeid &&
|
||||
(!(ent.entity_id).match('zwave[.]')));
|
||||
})
|
||||
.sort(window.hassUtil.sortByName);
|
||||
}
|
||||
|
||||
selectedNodeChanged(selectedNode) {
|
||||
this.newNodeNameInput = '';
|
||||
|
||||
if (selectedNode === -1) return;
|
||||
this.selectedConfigParameter = -1;
|
||||
this.selectedConfigParameterValue = -1;
|
||||
this.selectedGroup = -1;
|
||||
|
||||
this.hass.callApi('GET', 'zwave/config/' + this.nodes[selectedNode].attributes.node_id).then((configs) => {
|
||||
this.config = this._objToArray(configs);
|
||||
});
|
||||
|
||||
this.hass.callApi('GET', 'zwave/values/' + this.nodes[selectedNode].attributes.node_id).then((values) => {
|
||||
this.values = this._objToArray(values);
|
||||
});
|
||||
|
||||
this.hass.callApi('GET', 'zwave/groups/' + this.nodes[selectedNode].attributes.node_id).then((groups) => {
|
||||
this.groups = this._objToArray(groups);
|
||||
});
|
||||
|
||||
this.hasNodeUserCodes = false;
|
||||
this.notifyPath('hasNodeUserCodes');
|
||||
this.hass.callApi('GET', 'zwave/usercodes/' + this.nodes[selectedNode].attributes.node_id).then((usercodes) => {
|
||||
this.userCodes = this._objToArray(usercodes);
|
||||
this.hasNodeUserCodes = this.userCodes.length > 0;
|
||||
this.notifyPath('hasNodeUserCodes');
|
||||
});
|
||||
}
|
||||
|
||||
selectedEntityChanged(selectedEntity) {
|
||||
if (selectedEntity === -1) return;
|
||||
var el = this;
|
||||
el.hass.callApi('GET', 'zwave/values/' + el.nodes[el.selectedNode].attributes.node_id).then((values) => {
|
||||
el.values = el._objToArray(values);
|
||||
});
|
||||
|
||||
var valueId = el.entities[selectedEntity].attributes.value_id;
|
||||
var valueData = el.values.find(function (obj) { return obj.key === valueId; });
|
||||
var valueIndex = el.values.indexOf(valueData);
|
||||
el.hass.callApi('GET', 'config/zwave/device_config/' + valueId)
|
||||
.then(function (data) {
|
||||
el.entityIgnored = data.ignored || false;
|
||||
el.entityPollingIntensity = el.values[valueIndex].value.poll_intensity;
|
||||
});
|
||||
}
|
||||
|
||||
computeSelectedEntityAttrs(selectedEntity) {
|
||||
if (selectedEntity === -1) return 'No entity selected';
|
||||
var entityAttrs = this.entities[selectedEntity].attributes;
|
||||
var att = [];
|
||||
Object.keys(entityAttrs).forEach(function (key) {
|
||||
att.push(key + ': ' + entityAttrs[key]);
|
||||
});
|
||||
return att.sort();
|
||||
}
|
||||
|
||||
computeSelectCaption(stateObj) {
|
||||
return window.hassUtil.computeStateName(stateObj) + ' (Node:' +
|
||||
stateObj.attributes.node_id + ' ' +
|
||||
stateObj.attributes.query_stage + ')';
|
||||
}
|
||||
|
||||
computeSelectCaptionEnt(stateObj) {
|
||||
return (window.hassUtil.computeDomain(stateObj) + '.'
|
||||
+ window.hassUtil.computeStateName(stateObj));
|
||||
}
|
||||
|
||||
computeIsNodeSelected() {
|
||||
return (this.nodes && this.selectedNode !== -1);
|
||||
}
|
||||
|
||||
computeIsEntitySelected(selectedEntity) {
|
||||
return (selectedEntity === -1);
|
||||
}
|
||||
|
||||
computeNodeServiceData(selectedNode) {
|
||||
return { node_id: this.nodes[selectedNode].attributes.node_id };
|
||||
}
|
||||
|
||||
computeHealNodeServiceData(selectedNode) {
|
||||
return {
|
||||
node_id: this.nodes[selectedNode].attributes.node_id,
|
||||
return_routes: true
|
||||
};
|
||||
}
|
||||
|
||||
computeGetNodeName(selectedNode) {
|
||||
if (this.selectedNode === -1 ||
|
||||
!this.nodes[selectedNode].entity_id) return -1;
|
||||
return this.nodes[selectedNode].attributes.node_name;
|
||||
}
|
||||
|
||||
computeNodeNameServiceData(newNodeNameInput) {
|
||||
return {
|
||||
node_id: this.nodes[this.selectedNode].attributes.node_id,
|
||||
name: newNodeNameInput
|
||||
};
|
||||
}
|
||||
|
||||
computeRefreshEntityServiceData(selectedEntity) {
|
||||
if (selectedEntity === -1) return -1;
|
||||
return { entity_id: this.entities[selectedEntity].entity_id };
|
||||
}
|
||||
|
||||
computePollIntensityServiceData(entityPollingIntensity) {
|
||||
if (!this.selectedNode === -1 || this.selectedEntity === -1) return -1;
|
||||
return {
|
||||
node_id: this.nodes[this.selectedNode].attributes.node_id,
|
||||
value_id: this.entities[this.selectedEntity].attributes.value_id,
|
||||
poll_intensity: parseInt(entityPollingIntensity),
|
||||
};
|
||||
}
|
||||
|
||||
saveEntity() {
|
||||
var data = {
|
||||
ignored: this.entityIgnored,
|
||||
polling_intensity: parseInt(this.entityPollingIntensity),
|
||||
};
|
||||
return this.hass.callApi('POST', 'config/zwave/device_config/' + this.entities[this.selectedEntity].entity_id, data);
|
||||
}
|
||||
|
||||
toggleHelp() {
|
||||
this.showHelp = !this.showHelp;
|
||||
}
|
||||
|
||||
_objToArray(obj) {
|
||||
var array = [];
|
||||
Object.keys(obj).forEach(function (key) {
|
||||
array.push({
|
||||
key: key,
|
||||
value: obj[key],
|
||||
});
|
||||
});
|
||||
return array;
|
||||
}
|
||||
|
||||
_backTapped() {
|
||||
history.back();
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaConfigZwave.is, HaConfigZwave);
|
||||
</script>
|
||||
477
panels/config/zwave/ha-config-zwave.js
Normal file
477
panels/config/zwave/ha-config-zwave.js
Normal file
@ -0,0 +1,477 @@
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../../../src/components/buttons/ha-call-service-button.js';
|
||||
import '../../../src/components/ha-menu-button.js';
|
||||
import '../../../src/components/ha-service-description.js';
|
||||
import '../../../src/layouts/ha-app-layout.js';
|
||||
import '../../../src/resources/ha-style.js';
|
||||
import '../../../src/util/hass-mixins.js';
|
||||
import '../ha-config-section.js';
|
||||
import '../ha-form-style.js';
|
||||
import './zwave-groups.js';
|
||||
import './zwave-log.js';
|
||||
import './zwave-network.js';
|
||||
import './zwave-node-config.js';
|
||||
import './zwave-node-information.js';
|
||||
import './zwave-usercodes.js';
|
||||
import './zwave-values.js';
|
||||
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaConfigZwave extends window.hassMixins.LocalizeMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style ha-form-style">
|
||||
.content {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.node-info {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.help-text {
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
paper-card {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.device-picker {
|
||||
@apply --layout-horizontal;
|
||||
@apply --layout-center-center;
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
|
||||
ha-service-description {
|
||||
display: block;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.toggle-help-icon {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
right: 0;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
</style>
|
||||
<ha-app-layout has-scrolling-region="">
|
||||
<app-header slot="header" fixed="">
|
||||
<app-toolbar>
|
||||
<paper-icon-button icon="mdi:arrow-left" on-click="_backTapped"></paper-icon-button>
|
||||
<div main-title="">[[localize('ui.panel.config.zwave.caption')]]</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<zwave-network id="zwave-network" is-wide="[[isWide]]" hass="[[hass]]"></zwave-network>
|
||||
|
||||
<!--Node card-->
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<div style="position: relative" slot="header">
|
||||
<span>Z-Wave Node Management</span>
|
||||
<paper-icon-button class="toggle-help-icon" on-click="toggleHelp" icon="mdi:help-circle"></paper-icon-button>
|
||||
|
||||
</div>
|
||||
<span slot="introduction">
|
||||
Run Z-Wave commands that affect a single node. Pick a node to see a list of available commands.
|
||||
</span>
|
||||
|
||||
<paper-card class="content">
|
||||
<div class="device-picker">
|
||||
<paper-dropdown-menu dynamic-align="" label="Nodes" class="flex">
|
||||
<paper-listbox slot="dropdown-content" selected="{{selectedNode}}">
|
||||
<template is="dom-repeat" items="[[nodes]]" as="state">
|
||||
<paper-item>[[computeSelectCaption(state)]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</div>
|
||||
<template is="dom-if" if="[[!computeIsNodeSelected(selectedNode)]]">
|
||||
<template is="dom-if" if="[[showHelp]]">
|
||||
<div style="color: grey; padding: 12px">Select node to view per-node options</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template is="dom-if" if="[[computeIsNodeSelected(selectedNode)]]">
|
||||
<div class="card-actions">
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="refresh_node" service-data="[[computeNodeServiceData(selectedNode)]]">Refresh Node</ha-call-service-button>
|
||||
<ha-service-description hass="[[hass]]" domain="zwave" service="refresh_node" hidden\$="[[!showHelp]]"></ha-service-description>
|
||||
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="remove_failed_node" service-data="[[computeNodeServiceData(selectedNode)]]">Remove Failed Node</ha-call-service-button>
|
||||
<ha-service-description hass="[[hass]]" domain="zwave" service="remove_failed_node" hidden\$="[[!showHelp]]"></ha-service-description>
|
||||
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="replace_failed_node" service-data="[[computeNodeServiceData(selectedNode)]]">Replace Failed Node</ha-call-service-button>
|
||||
<ha-service-description hass="[[hass]]" domain="zwave" service="replace_failed_node" hidden\$="[[!showHelp]]"></ha-service-description>
|
||||
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="print_node" service-data="[[computeNodeServiceData(selectedNode)]]">Print Node</ha-call-service-button>
|
||||
<ha-service-description hass="[[hass]]" domain="zwave" service="print_node" hidden\$="[[!showHelp]]"></ha-service-description>
|
||||
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="heal_node" service-data="[[computeHealNodeServiceData(selectedNode)]]">Heal Node</ha-call-service-button>
|
||||
<ha-service-description hass="[[hass]]" domain="zwave" service="heal_node" hidden\$="[[!showHelp]]"></ha-service-description>
|
||||
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="test_node" service-data="[[computeNodeServiceData(selectedNode)]]">Test Node</ha-call-service-button>
|
||||
<ha-service-description hass="[[hass]]" domain="zwave" service="test_node" hidden\$="[[!showHelp]]"></ha-service-description>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<paper-input float-label="New node name" type="text" value="{{newNodeNameInput}}" placeholder="[[computeGetNodeName(selectedNode)]]">
|
||||
</paper-input>
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="rename_node" service-data="[[computeNodeNameServiceData(newNodeNameInput)]]">Rename Node</ha-call-service-button>
|
||||
<ha-service-description hass="[[hass]]" domain="zwave" service="rename_node" hidden\$="[[!showHelp]]"></ha-service-description>
|
||||
</div>
|
||||
|
||||
<div class="device-picker">
|
||||
<paper-dropdown-menu label="Entities of this node" dynamic-align="" class="flex">
|
||||
<paper-listbox slot="dropdown-content" selected="{{selectedEntity}}">
|
||||
<template is="dom-repeat" items="[[entities]]" as="state">
|
||||
<paper-item>[[computeSelectCaptionEnt(state)]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</div>
|
||||
<template is="dom-if" if="[[!computeIsEntitySelected(selectedEntity)]]">
|
||||
<div class="card-actions">
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="refresh_entity" service-data="[[computeRefreshEntityServiceData(selectedEntity)]]">Refresh Entity</ha-call-service-button>
|
||||
<ha-service-description hass="[[hass]]" domain="zwave" service="refresh_entity" hidden\$="[[!showHelp]]"></ha-service-description>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<paper-checkbox checked="{{entityIgnored}}" class="form-control">
|
||||
Exclude this entity from Home Assistant
|
||||
</paper-checkbox>
|
||||
<paper-input disabled="{{entityIgnored}}" label="Polling intensity" type="number" min="0" value="{{entityPollingIntensity}}">
|
||||
</paper-input>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="set_poll_intensity" service-data="[[computePollIntensityServiceData(entityPollingIntensity)]]">Save</ha-call-service-button>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="card-actions">
|
||||
<paper-button toggles="" raised="" noink="" active="{{entityInfoActive}}">Entity Attributes</paper-button>
|
||||
</div>
|
||||
<template is="dom-if" if="{{entityInfoActive}}">
|
||||
<template is="dom-repeat" items="[[selectedEntityAttrs]]" as="state">
|
||||
<div class="node-info">
|
||||
<span>[[state]]</span>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
</template>
|
||||
</paper-card>
|
||||
|
||||
<template is="dom-if" if="[[computeIsNodeSelected(selectedNode)]]">
|
||||
<!--Node info card-->
|
||||
<zwave-node-information id="zwave-node-information" nodes="[[nodes]]" selected-node="[[selectedNode]]"></zwave-node-information>
|
||||
|
||||
<!--Value card-->
|
||||
<zwave-values hass="[[hass]]" nodes="[[nodes]]" selected-node="[[selectedNode]]" values="[[values]]"></zwave-values>
|
||||
|
||||
<!--Group card-->
|
||||
<zwave-groups hass="[[hass]]" nodes="[[nodes]]" selected-node="[[selectedNode]]" groups="[[groups]]"></zwave-groups>
|
||||
|
||||
<!--Config card-->
|
||||
<zwave-node-config hass="[[hass]]" nodes="[[nodes]]" selected-node="[[selectedNode]]" config="[[config]]"></zwave-node-config>
|
||||
</template>
|
||||
|
||||
<!--User Codes-->
|
||||
<template is="dom-if" if="{{hasNodeUserCodes}}">
|
||||
<zwave-usercodes id="zwave-usercodes" hass="[[hass]]" nodes="[[nodes]]" user-codes="[[userCodes]]" selected-node="[[selectedNode]]"></zwave-usercodes>
|
||||
</template>
|
||||
</ha-config-section>
|
||||
|
||||
|
||||
|
||||
<!--Ozw log-->
|
||||
<ozw-log is-wide="[[isWide]]" hass="[[hass]]"></ozw-log>
|
||||
|
||||
</ha-app-layout>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-config-zwave'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
|
||||
nodes: {
|
||||
type: Array,
|
||||
computed: 'computeNodes(hass)'
|
||||
},
|
||||
|
||||
selectedNode: {
|
||||
type: Number,
|
||||
value: -1,
|
||||
observer: 'selectedNodeChanged'
|
||||
},
|
||||
|
||||
config: {
|
||||
type: Array,
|
||||
value: function () {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
|
||||
entities: {
|
||||
type: Array,
|
||||
computed: 'computeEntities(selectedNode)',
|
||||
},
|
||||
|
||||
entityInfoActive: {
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
selectedEntity: {
|
||||
type: Number,
|
||||
value: -1,
|
||||
observer: 'selectedEntityChanged',
|
||||
},
|
||||
|
||||
selectedEntityAttrs: {
|
||||
type: Array,
|
||||
computed: 'computeSelectedEntityAttrs(selectedEntity)'
|
||||
},
|
||||
|
||||
values: {
|
||||
type: Array,
|
||||
},
|
||||
|
||||
groups: {
|
||||
type: Array,
|
||||
},
|
||||
|
||||
newNodeNameInput: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
userCodes: {
|
||||
type: Array,
|
||||
value: function () {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
|
||||
hasNodeUserCodes: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
showHelp: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
entityIgnored: {
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
entityPollingIntensity: {
|
||||
type: Number,
|
||||
value: 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
ready() {
|
||||
super.ready();
|
||||
this.addEventListener('hass-service-called', ev => this.serviceCalled(ev));
|
||||
}
|
||||
|
||||
serviceCalled(ev) {
|
||||
var el = this;
|
||||
if ((ev.detail.success) && (ev.detail.service === 'set_poll_intensity')) {
|
||||
el.saveEntity();
|
||||
}
|
||||
}
|
||||
|
||||
computeNodes(hass) {
|
||||
return Object.keys(hass.states)
|
||||
.map(function (key) { return hass.states[key]; })
|
||||
.filter(function (ent) {
|
||||
return ((ent.entity_id).match('zwave[.]'));
|
||||
})
|
||||
.sort(window.hassUtil.sortByName);
|
||||
}
|
||||
|
||||
computeEntities(selectedNode) {
|
||||
if (!this.nodes || selectedNode === -1) return -1;
|
||||
var hass = this.hass;
|
||||
var nodeid = this.nodes[this.selectedNode].attributes.node_id;
|
||||
return Object.keys(hass.states)
|
||||
.map(function (key) { return hass.states[key]; })
|
||||
.filter(function (ent) {
|
||||
if (ent.attributes.node_id === undefined) {
|
||||
return false;
|
||||
}
|
||||
return (!ent.attributes.hidden &&
|
||||
'node_id' in ent.attributes &&
|
||||
ent.attributes.node_id === nodeid &&
|
||||
(!(ent.entity_id).match('zwave[.]')));
|
||||
})
|
||||
.sort(window.hassUtil.sortByName);
|
||||
}
|
||||
|
||||
selectedNodeChanged(selectedNode) {
|
||||
this.newNodeNameInput = '';
|
||||
|
||||
if (selectedNode === -1) return;
|
||||
this.selectedConfigParameter = -1;
|
||||
this.selectedConfigParameterValue = -1;
|
||||
this.selectedGroup = -1;
|
||||
|
||||
this.hass.callApi('GET', 'zwave/config/' + this.nodes[selectedNode].attributes.node_id).then((configs) => {
|
||||
this.config = this._objToArray(configs);
|
||||
});
|
||||
|
||||
this.hass.callApi('GET', 'zwave/values/' + this.nodes[selectedNode].attributes.node_id).then((values) => {
|
||||
this.values = this._objToArray(values);
|
||||
});
|
||||
|
||||
this.hass.callApi('GET', 'zwave/groups/' + this.nodes[selectedNode].attributes.node_id).then((groups) => {
|
||||
this.groups = this._objToArray(groups);
|
||||
});
|
||||
|
||||
this.hasNodeUserCodes = false;
|
||||
this.notifyPath('hasNodeUserCodes');
|
||||
this.hass.callApi('GET', 'zwave/usercodes/' + this.nodes[selectedNode].attributes.node_id).then((usercodes) => {
|
||||
this.userCodes = this._objToArray(usercodes);
|
||||
this.hasNodeUserCodes = this.userCodes.length > 0;
|
||||
this.notifyPath('hasNodeUserCodes');
|
||||
});
|
||||
}
|
||||
|
||||
selectedEntityChanged(selectedEntity) {
|
||||
if (selectedEntity === -1) return;
|
||||
var el = this;
|
||||
el.hass.callApi('GET', 'zwave/values/' + el.nodes[el.selectedNode].attributes.node_id).then((values) => {
|
||||
el.values = el._objToArray(values);
|
||||
});
|
||||
|
||||
var valueId = el.entities[selectedEntity].attributes.value_id;
|
||||
var valueData = el.values.find(function (obj) { return obj.key === valueId; });
|
||||
var valueIndex = el.values.indexOf(valueData);
|
||||
el.hass.callApi('GET', 'config/zwave/device_config/' + valueId)
|
||||
.then(function (data) {
|
||||
el.entityIgnored = data.ignored || false;
|
||||
el.entityPollingIntensity = el.values[valueIndex].value.poll_intensity;
|
||||
});
|
||||
}
|
||||
|
||||
computeSelectedEntityAttrs(selectedEntity) {
|
||||
if (selectedEntity === -1) return 'No entity selected';
|
||||
var entityAttrs = this.entities[selectedEntity].attributes;
|
||||
var att = [];
|
||||
Object.keys(entityAttrs).forEach(function (key) {
|
||||
att.push(key + ': ' + entityAttrs[key]);
|
||||
});
|
||||
return att.sort();
|
||||
}
|
||||
|
||||
computeSelectCaption(stateObj) {
|
||||
return window.hassUtil.computeStateName(stateObj) + ' (Node:' +
|
||||
stateObj.attributes.node_id + ' ' +
|
||||
stateObj.attributes.query_stage + ')';
|
||||
}
|
||||
|
||||
computeSelectCaptionEnt(stateObj) {
|
||||
return (window.hassUtil.computeDomain(stateObj) + '.'
|
||||
+ window.hassUtil.computeStateName(stateObj));
|
||||
}
|
||||
|
||||
computeIsNodeSelected() {
|
||||
return (this.nodes && this.selectedNode !== -1);
|
||||
}
|
||||
|
||||
computeIsEntitySelected(selectedEntity) {
|
||||
return (selectedEntity === -1);
|
||||
}
|
||||
|
||||
computeNodeServiceData(selectedNode) {
|
||||
return { node_id: this.nodes[selectedNode].attributes.node_id };
|
||||
}
|
||||
|
||||
computeHealNodeServiceData(selectedNode) {
|
||||
return {
|
||||
node_id: this.nodes[selectedNode].attributes.node_id,
|
||||
return_routes: true
|
||||
};
|
||||
}
|
||||
|
||||
computeGetNodeName(selectedNode) {
|
||||
if (this.selectedNode === -1 ||
|
||||
!this.nodes[selectedNode].entity_id) return -1;
|
||||
return this.nodes[selectedNode].attributes.node_name;
|
||||
}
|
||||
|
||||
computeNodeNameServiceData(newNodeNameInput) {
|
||||
return {
|
||||
node_id: this.nodes[this.selectedNode].attributes.node_id,
|
||||
name: newNodeNameInput
|
||||
};
|
||||
}
|
||||
|
||||
computeRefreshEntityServiceData(selectedEntity) {
|
||||
if (selectedEntity === -1) return -1;
|
||||
return { entity_id: this.entities[selectedEntity].entity_id };
|
||||
}
|
||||
|
||||
computePollIntensityServiceData(entityPollingIntensity) {
|
||||
if (!this.selectedNode === -1 || this.selectedEntity === -1) return -1;
|
||||
return {
|
||||
node_id: this.nodes[this.selectedNode].attributes.node_id,
|
||||
value_id: this.entities[this.selectedEntity].attributes.value_id,
|
||||
poll_intensity: parseInt(entityPollingIntensity),
|
||||
};
|
||||
}
|
||||
|
||||
saveEntity() {
|
||||
var data = {
|
||||
ignored: this.entityIgnored,
|
||||
polling_intensity: parseInt(this.entityPollingIntensity),
|
||||
};
|
||||
return this.hass.callApi('POST', 'config/zwave/device_config/' + this.entities[this.selectedEntity].entity_id, data);
|
||||
}
|
||||
|
||||
toggleHelp() {
|
||||
this.showHelp = !this.showHelp;
|
||||
}
|
||||
|
||||
_objToArray(obj) {
|
||||
var array = [];
|
||||
Object.keys(obj).forEach(function (key) {
|
||||
array.push({
|
||||
key: key,
|
||||
value: obj[key],
|
||||
});
|
||||
});
|
||||
return array;
|
||||
}
|
||||
|
||||
_backTapped() {
|
||||
history.back();
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaConfigZwave.is, HaConfigZwave);
|
||||
@ -1,13 +1,15 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
|
||||
<link rel='import' href='../../../bower_components/paper-item/paper-item.html'>
|
||||
<link rel='import' href="../../../bower_components/paper-listbox/paper-listbox.html">
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../../src/components/buttons/ha-call-service-button.html">
|
||||
import '../../../src/components/buttons/ha-call-service-button.js';
|
||||
|
||||
<dom-module id='zwave-groups'>
|
||||
<template>
|
||||
class ZwaveGroups extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
margin-top: 24px;
|
||||
@ -33,70 +35,54 @@
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
</style>
|
||||
<paper-card class="content" heading='Node group associations'>
|
||||
<paper-card class="content" heading="Node group associations">
|
||||
<!--TODO make api for getting groups and members-->
|
||||
<div class='device-picker'>
|
||||
<paper-dropdown-menu label="Group" dynamic-align class='flex'>
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
selected='{{selectedGroup}}'>
|
||||
<template is='dom-repeat' items='[[groups]]' as='state'>
|
||||
<div class="device-picker">
|
||||
<paper-dropdown-menu label="Group" dynamic-align="" class="flex">
|
||||
<paper-listbox slot="dropdown-content" selected="{{selectedGroup}}">
|
||||
<template is="dom-repeat" items="[[groups]]" as="state">
|
||||
<paper-item>[[computeSelectCaptionGroup(state)]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</div>
|
||||
<template is='dom-if' if='[[computeIsGroupSelected(selectedGroup)]]'>
|
||||
<div class='device-picker'>
|
||||
<paper-dropdown-menu label="Node to control" dynamic-align class='flex'>
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
selected='{{selectedTargetNode}}'>
|
||||
<template is='dom-repeat' items='[[nodes]]' as='state'>
|
||||
<template is="dom-if" if="[[computeIsGroupSelected(selectedGroup)]]">
|
||||
<div class="device-picker">
|
||||
<paper-dropdown-menu label="Node to control" dynamic-align="" class="flex">
|
||||
<paper-listbox slot="dropdown-content" selected="{{selectedTargetNode}}">
|
||||
<template is="dom-repeat" items="[[nodes]]" as="state">
|
||||
<paper-item>[[computeSelectCaption(state)]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</div>
|
||||
|
||||
<div class='help-text'>
|
||||
<div class="help-text">
|
||||
<span>Other Nodes in this group:</span>
|
||||
<template is='dom-repeat' items='[[otherGroupNodes]]' as='state'>
|
||||
<template is="dom-repeat" items="[[otherGroupNodes]]" as="state">
|
||||
<div>[[state]]</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class='help-text'>
|
||||
<div class="help-text">
|
||||
<span>Max Associations:</span>
|
||||
<span>[[maxAssociations]]</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[computeIsTargetNodeSelected(selectedTargetNode)]]'>
|
||||
<div class='card-actions'>
|
||||
<template is='dom-if' if='[[!noAssociationsLeft]]'>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='change_association'
|
||||
service-data='[[computeAssocServiceData(selectedGroup, "add")]]'
|
||||
>Add To Group</ha-call-service-button>
|
||||
<template is="dom-if" if="[[computeIsTargetNodeSelected(selectedTargetNode)]]">
|
||||
<div class="card-actions">
|
||||
<template is="dom-if" if="[[!noAssociationsLeft]]">
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="change_association" service-data="[[computeAssocServiceData(selectedGroup, "add")]]">Add To Group</ha-call-service-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[computeTargetInGroup(selectedGroup, selectedTargetNode)]]'>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='change_association'
|
||||
service-data='[[computeAssocServiceData(selectedGroup, "remove")]]'
|
||||
>Remove From Group</ha-call-service-button>
|
||||
<template is="dom-if" if="[[computeTargetInGroup(selectedGroup, selectedTargetNode)]]">
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="change_association" service-data="[[computeAssocServiceData(selectedGroup, "remove")]]">Remove From Group</ha-call-service-button>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class ZwaveGroups extends Polymer.Element {
|
||||
static get is() { return 'zwave-groups'; }
|
||||
|
||||
static get properties() {
|
||||
@ -253,4 +239,3 @@ class ZwaveGroups extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(ZwaveGroups.is, ZwaveGroups);
|
||||
</script>
|
||||
@ -1,13 +1,15 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-checkbox/paper-checkbox.html">
|
||||
<link rel="import" href="../../../bower_components/paper-input/paper-input.html">
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-checkbox/paper-checkbox.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
import '../ha-config-section.js';
|
||||
|
||||
<dom-module id='ozw-log'>
|
||||
<template>
|
||||
class OzwLog extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
margin-top: 24px;
|
||||
@ -25,32 +27,24 @@
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
</style>
|
||||
<ha-config-section is-wide='[[isWide]]'>
|
||||
<span slot='header'>OZW Log</span>
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<span slot="header">OZW Log</span>
|
||||
<paper-card>
|
||||
<div class='device-picker'>
|
||||
<paper-input
|
||||
label="Number of last log lines."
|
||||
type=number
|
||||
min=0
|
||||
max=1000
|
||||
step=10
|
||||
value={{numLogLines}}>
|
||||
<div class="device-picker">
|
||||
<paper-input label="Number of last log lines." type="number" min="0" max="1000" step="10" value="{{numLogLines}}">
|
||||
</paper-input>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<paper-button raised on-click='refreshLog'>Refresh</paper-button>
|
||||
<paper-button raised="" on-click="refreshLog">Refresh</paper-button>
|
||||
</div>
|
||||
<div class='help-text'>
|
||||
<div class="help-text">
|
||||
<pre>[[ozwLogs]]</pre>
|
||||
</div>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
</template>
|
||||
</dom-module>
|
||||
<script>
|
||||
`;
|
||||
}
|
||||
|
||||
class OzwLog extends Polymer.Element {
|
||||
static get is() { return 'ozw-log'; }
|
||||
|
||||
static get properties() {
|
||||
@ -86,4 +80,3 @@ class OzwLog extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(OzwLog.is, OzwLog);
|
||||
</script>
|
||||
@ -1,204 +0,0 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
<link rel="import" href="../../../src/components/buttons/ha-call-service-button.html">
|
||||
<link rel="import" href="../../../src/components/buttons/ha-call-api-button.html">
|
||||
<link rel="import" href="../../../src/components/ha-service-description.html">
|
||||
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
|
||||
<dom-module id='zwave-network'>
|
||||
<template>
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
paper-card {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.card-actions.warning ha-call-service-button {
|
||||
color: var(--google-red-500);
|
||||
}
|
||||
|
||||
.toggle-help-icon {
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
right: 0;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
ha-service-description {
|
||||
display: block;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<ha-config-section is-wide='[[isWide]]'>
|
||||
<div style="position: relative" slot='header'>
|
||||
<span>Z-Wave Network Management</span>
|
||||
<paper-icon-button
|
||||
class="toggle-help-icon"
|
||||
on-click='helpTap'
|
||||
icon='mdi:help-circle'
|
||||
></paper-icon-button>
|
||||
|
||||
</div>
|
||||
<span slot='introduction'>
|
||||
Run commands that affect the Z-Wave network. You won't get feedback on whether the command succeeded, but you can look in the OZW Log to try to figure out.
|
||||
</span>
|
||||
|
||||
|
||||
<paper-card class="content">
|
||||
<div class='card-actions'>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='add_node_secure'
|
||||
>Add Node Secure</ha-call-service-button>
|
||||
<ha-service-description
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='add_node_secure'
|
||||
hidden$='[[!showDescription]]'
|
||||
></ha-service-description>
|
||||
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='add_node'
|
||||
>Add Node</ha-call-service-button>
|
||||
<ha-service-description
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='add_node'
|
||||
hidden$='[[!showDescription]]'
|
||||
></ha-service-description>
|
||||
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='remove_node'
|
||||
>Remove Node</ha-call-service-button>
|
||||
<ha-service-description
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='remove_node'
|
||||
hidden$='[[!showDescription]]'
|
||||
></ha-service-description>
|
||||
|
||||
</div>
|
||||
<div class='card-actions warning'>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='cancel_command'
|
||||
>Cancel Command</ha-call-service-button>
|
||||
<ha-service-description
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='cancel_command'
|
||||
hidden$='[[!showDescription]]'
|
||||
></ha-service-description>
|
||||
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='heal_network'
|
||||
>Heal Network</ha-call-service-button>
|
||||
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='start_network'
|
||||
>Start Network</ha-call-service-button>
|
||||
<ha-service-description
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='start_network'
|
||||
hidden$='[[!showDescription]]'
|
||||
></ha-service-description>
|
||||
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='stop_network'
|
||||
>Stop Network</ha-call-service-button>
|
||||
<ha-service-description
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='stop_network'
|
||||
hidden$='[[!showDescription]]'
|
||||
></ha-service-description>
|
||||
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='soft_reset'
|
||||
>Soft Reset</ha-call-service-button>
|
||||
<ha-service-description
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='soft_reset'
|
||||
hidden$='[[!showDescription]]'
|
||||
></ha-service-description>
|
||||
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='test_network'
|
||||
>Test Network</ha-call-service-button>
|
||||
<ha-service-description
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='test_network'
|
||||
hidden$='[[!showDescription]]'
|
||||
></ha-service-description>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path="zwave/saveconfig"
|
||||
>Save Config</ha-call-api-button>
|
||||
|
||||
</div>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
</template>
|
||||
</dom-module>
|
||||
<script>
|
||||
|
||||
class ZwaveNetwork extends Polymer.Element {
|
||||
static get is() { return 'zwave-network'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
isWide: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
showDescription: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
helpTap() {
|
||||
this.showDescription = !this.showDescription;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(ZwaveNetwork.is, ZwaveNetwork);
|
||||
</script>
|
||||
120
panels/config/zwave/zwave-network.js
Normal file
120
panels/config/zwave/zwave-network.js
Normal file
@ -0,0 +1,120 @@
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../../../src/components/buttons/ha-call-api-button.js';
|
||||
import '../../../src/components/buttons/ha-call-service-button.js';
|
||||
import '../../../src/components/ha-service-description.js';
|
||||
import '../ha-config-section.js';
|
||||
|
||||
class ZwaveNetwork extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
paper-card {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.card-actions.warning ha-call-service-button {
|
||||
color: var(--google-red-500);
|
||||
}
|
||||
|
||||
.toggle-help-icon {
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
right: 0;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
ha-service-description {
|
||||
display: block;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<div style="position: relative" slot="header">
|
||||
<span>Z-Wave Network Management</span>
|
||||
<paper-icon-button class="toggle-help-icon" on-click="helpTap" icon="mdi:help-circle"></paper-icon-button>
|
||||
|
||||
</div>
|
||||
<span slot="introduction">
|
||||
Run commands that affect the Z-Wave network. You won't get feedback on whether the command succeeded, but you can look in the OZW Log to try to figure out.
|
||||
</span>
|
||||
|
||||
|
||||
<paper-card class="content">
|
||||
<div class="card-actions">
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="add_node_secure">Add Node Secure</ha-call-service-button>
|
||||
<ha-service-description hass="[[hass]]" domain="zwave" service="add_node_secure" hidden\$="[[!showDescription]]"></ha-service-description>
|
||||
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="add_node">Add Node</ha-call-service-button>
|
||||
<ha-service-description hass="[[hass]]" domain="zwave" service="add_node" hidden\$="[[!showDescription]]"></ha-service-description>
|
||||
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="remove_node">Remove Node</ha-call-service-button>
|
||||
<ha-service-description hass="[[hass]]" domain="zwave" service="remove_node" hidden\$="[[!showDescription]]"></ha-service-description>
|
||||
|
||||
</div>
|
||||
<div class="card-actions warning">
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="cancel_command">Cancel Command</ha-call-service-button>
|
||||
<ha-service-description hass="[[hass]]" domain="zwave" service="cancel_command" hidden\$="[[!showDescription]]"></ha-service-description>
|
||||
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="heal_network">Heal Network</ha-call-service-button>
|
||||
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="start_network">Start Network</ha-call-service-button>
|
||||
<ha-service-description hass="[[hass]]" domain="zwave" service="start_network" hidden\$="[[!showDescription]]"></ha-service-description>
|
||||
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="stop_network">Stop Network</ha-call-service-button>
|
||||
<ha-service-description hass="[[hass]]" domain="zwave" service="stop_network" hidden\$="[[!showDescription]]"></ha-service-description>
|
||||
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="soft_reset">Soft Reset</ha-call-service-button>
|
||||
<ha-service-description hass="[[hass]]" domain="zwave" service="soft_reset" hidden\$="[[!showDescription]]"></ha-service-description>
|
||||
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="test_network">Test Network</ha-call-service-button>
|
||||
<ha-service-description hass="[[hass]]" domain="zwave" service="test_network" hidden\$="[[!showDescription]]"></ha-service-description>
|
||||
<ha-call-api-button hass="[[hass]]" path="zwave/saveconfig">Save Config</ha-call-api-button>
|
||||
|
||||
</div>
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'zwave-network'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
isWide: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
showDescription: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
helpTap() {
|
||||
this.showDescription = !this.showDescription;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(ZwaveNetwork.is, ZwaveNetwork);
|
||||
@ -1,14 +1,16 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
|
||||
<link rel='import' href='../../../bower_components/paper-item/paper-item.html'>
|
||||
<link rel='import' href="../../../bower_components/paper-listbox/paper-listbox.html">
|
||||
<link rel='import' href="../../../bower_components/paper-input/paper-input.html">
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../../src/components/buttons/ha-call-service-button.html">
|
||||
import '../../../src/components/buttons/ha-call-service-button.js';
|
||||
|
||||
<dom-module id='zwave-node-config'>
|
||||
<template>
|
||||
class ZwaveNodeConfig extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
margin-top: 24px;
|
||||
@ -33,43 +35,30 @@
|
||||
padding-right: 24px;
|
||||
}
|
||||
</style>
|
||||
<div class='content'>
|
||||
<paper-card heading='Node config options'>
|
||||
<template is='dom-if' if='[[wakeupNode]]'>
|
||||
<div class='card-actions'>
|
||||
<paper-input
|
||||
float-label="Wakeup Interval"
|
||||
type=number
|
||||
value={{wakeupInput}}
|
||||
placeholder=[[computeGetWakeupValue(selectedNode)]]>
|
||||
<div suffix>seconds</div>
|
||||
<div class="content">
|
||||
<paper-card heading="Node config options">
|
||||
<template is="dom-if" if="[[wakeupNode]]">
|
||||
<div class="card-actions">
|
||||
<paper-input float-label="Wakeup Interval" type="number" value="{{wakeupInput}}" placeholder="[[computeGetWakeupValue(selectedNode)]]">
|
||||
<div suffix="">seconds</div>
|
||||
</paper-input>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='set_wakeup'
|
||||
service-data='[[computeWakeupServiceData(wakeupInput)]]'
|
||||
>Set Wakeup</ha-call-service-button>
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="set_wakeup" service-data="[[computeWakeupServiceData(wakeupInput)]]">Set Wakeup</ha-call-service-button>
|
||||
</div>
|
||||
</template>
|
||||
<div class='device-picker'>
|
||||
<paper-dropdown-menu label="Config parameter" dynamic-align class='flex'>
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
selected='{{selectedConfigParameter}}'>
|
||||
<template is='dom-repeat' items='[[config]]' as='state'>
|
||||
<div class="device-picker">
|
||||
<paper-dropdown-menu label="Config parameter" dynamic-align="" class="flex">
|
||||
<paper-listbox slot="dropdown-content" selected="{{selectedConfigParameter}}">
|
||||
<template is="dom-repeat" items="[[config]]" as="state">
|
||||
<paper-item>[[computeSelectCaptionConfigParameter(state)]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</div>
|
||||
<template is='dom-if' if="[[isConfigParameterSelected(selectedConfigParameter, 'List')]]">
|
||||
<div class='device-picker'>
|
||||
<paper-dropdown-menu label="Config value" dynamic-align class='flex' placeholder='{{loadedConfigValue}}'>
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
selected='{{selectedConfigValue}}'>
|
||||
<template is='dom-repeat' items='[[selectedConfigParameterValues]]' as='state'>
|
||||
<template is="dom-if" if="[[isConfigParameterSelected(selectedConfigParameter, 'List')]]">
|
||||
<div class="device-picker">
|
||||
<paper-dropdown-menu label="Config value" dynamic-align="" class="flex" placeholder="{{loadedConfigValue}}">
|
||||
<paper-listbox slot="dropdown-content" selected="{{selectedConfigValue}}">
|
||||
<template is="dom-repeat" items="[[selectedConfigParameterValues]]" as="state">
|
||||
<paper-item>[[state]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
@ -77,50 +66,36 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if="[[isConfigParameterSelected(selectedConfigParameter, 'Byte Short Int')]]">
|
||||
<div class='card-actions'>
|
||||
<paper-input
|
||||
label='{{selectedConfigParameterNumValues}}'
|
||||
type=number
|
||||
value='{{selectedConfigValue}}'
|
||||
max='{{configParameterMax}}'
|
||||
min='{{configParameterMin}}'>
|
||||
<template is="dom-if" if="[[isConfigParameterSelected(selectedConfigParameter, 'Byte Short Int')]]">
|
||||
<div class="card-actions">
|
||||
<paper-input label="{{selectedConfigParameterNumValues}}" type="number" value="{{selectedConfigValue}}" max="{{configParameterMax}}" min="{{configParameterMin}}">
|
||||
</paper-input>
|
||||
</div>
|
||||
</template>
|
||||
<template is='dom-if' if="[[isConfigParameterSelected(selectedConfigParameter, 'Bool Button')]]">
|
||||
<div class='device-picker'>
|
||||
<paper-dropdown-menu label="Config value" class='flex' dynamic-align placeholder='{{loadedConfigValue}}'>
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
selected='{{selectedConfigValue}}'>
|
||||
<template is='dom-repeat' items='[[selectedConfigParameterValues]]' as='state'>
|
||||
<template is="dom-if" if="[[isConfigParameterSelected(selectedConfigParameter, 'Bool Button')]]">
|
||||
<div class="device-picker">
|
||||
<paper-dropdown-menu label="Config value" class="flex" dynamic-align="" placeholder="{{loadedConfigValue}}">
|
||||
<paper-listbox slot="dropdown-content" selected="{{selectedConfigValue}}">
|
||||
<template is="dom-repeat" items="[[selectedConfigParameterValues]]" as="state">
|
||||
<paper-item>[[state]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</div>
|
||||
</template>
|
||||
<div class='help-text'>
|
||||
<div class="help-text">
|
||||
<span>[[configValueHelpText]]</span>
|
||||
</div>
|
||||
<template is='dom-if' if="[[isConfigParameterSelected(selectedConfigParameter, 'Bool Button Byte Short Int List')]]">
|
||||
<div class='card-actions'>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='set_config_parameter'
|
||||
service-data=[[computeSetConfigParameterServiceData(selectedConfigValue)]]
|
||||
>Set Config Parameter</ha-call-service-button>
|
||||
<template is="dom-if" if="[[isConfigParameterSelected(selectedConfigParameter, 'Bool Button Byte Short Int List')]]">
|
||||
<div class="card-actions">
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="set_config_parameter" service-data="[[computeSetConfigParameterServiceData(selectedConfigValue)]]">Set Config Parameter</ha-call-service-button>
|
||||
</div>
|
||||
</template>
|
||||
</paper-card>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class ZwaveNodeConfig extends Polymer.Element {
|
||||
static get is() { return 'zwave-node-config'; }
|
||||
|
||||
static get properties() {
|
||||
@ -321,4 +296,3 @@ class ZwaveNodeConfig extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(ZwaveNodeConfig.is, ZwaveNodeConfig);
|
||||
</script>
|
||||
@ -1,9 +1,11 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../bower_components/paper-button/paper-button.html">
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id='zwave-node-information'>
|
||||
<template>
|
||||
class ZwaveNodeInformation extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
margin-top: 24px;
|
||||
@ -25,26 +27,23 @@
|
||||
|
||||
</style>
|
||||
|
||||
<div class='content'>
|
||||
<paper-card heading='Node Information'>
|
||||
<div class='card-actions'>
|
||||
<paper-button toggles raised noink active={{nodeInfoActive}}>Show</paper-button>
|
||||
<div class="content">
|
||||
<paper-card heading="Node Information">
|
||||
<div class="card-actions">
|
||||
<paper-button toggles="" raised="" noink="" active="{{nodeInfoActive}}">Show</paper-button>
|
||||
</div>
|
||||
<template is='dom-if' if={{nodeInfoActive}}>
|
||||
<template is='dom-repeat' items='[[selectedNodeAttrs]]' as='state'>
|
||||
<div class='node-info'>
|
||||
<template is="dom-if" if="{{nodeInfoActive}}">
|
||||
<template is="dom-repeat" items="[[selectedNodeAttrs]]" as="state">
|
||||
<div class="node-info">
|
||||
<span>[[state]]</span>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</paper-card>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
</template>
|
||||
</dom-module>
|
||||
<script>
|
||||
|
||||
class ZwaveNodeInformation extends Polymer.Element {
|
||||
static get is() { return 'zwave-node-information'; }
|
||||
|
||||
static get properties() {
|
||||
@ -82,4 +81,3 @@ class ZwaveNodeInformation extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(ZwaveNodeInformation.is, ZwaveNodeInformation);
|
||||
</script>
|
||||
@ -1,14 +1,16 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
|
||||
<link rel='import' href='../../../bower_components/paper-item/paper-item.html'>
|
||||
<link rel='import' href="../../../bower_components/paper-listbox/paper-listbox.html">
|
||||
<link rel='import' href="../../../bower_components/paper-input/paper-input.html">
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../../src/components/buttons/ha-call-service-button.html">
|
||||
import '../../../src/components/buttons/ha-call-service-button.js';
|
||||
|
||||
<dom-module id='zwave-usercodes'>
|
||||
<template>
|
||||
class ZwaveUsercodes extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
margin-top: 24px;
|
||||
@ -28,54 +30,34 @@
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
</style>
|
||||
<div class='content'>
|
||||
<paper-card heading='Node user codes'>
|
||||
<div class='device-picker'>
|
||||
<paper-dropdown-menu label="Code slot" dynamic-align class='flex'>
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
selected='{{selectedUserCode}}'>
|
||||
<template is='dom-repeat' items='[[userCodes]]' as='state'>
|
||||
<div class="content">
|
||||
<paper-card heading="Node user codes">
|
||||
<div class="device-picker">
|
||||
<paper-dropdown-menu label="Code slot" dynamic-align="" class="flex">
|
||||
<paper-listbox slot="dropdown-content" selected="{{selectedUserCode}}">
|
||||
<template is="dom-repeat" items="[[userCodes]]" as="state">
|
||||
<paper-item>[[computeSelectCaptionUserCodes(state)]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</div>
|
||||
|
||||
<template is='dom-if' if="[[isUserCodeSelected(selectedUserCode)]]">
|
||||
<div class='card-actions'>
|
||||
<paper-input
|
||||
label='User code'
|
||||
type='text'
|
||||
allowed-pattern='[0-9,a-f,x,\\]'
|
||||
maxlength='{{userCodeMaxLen}}'
|
||||
minlength='16'
|
||||
value='{{selectedUserCodeValue}}'>
|
||||
<template is="dom-if" if="[[isUserCodeSelected(selectedUserCode)]]">
|
||||
<div class="card-actions">
|
||||
<paper-input label="User code" type="text" allowed-pattern="[0-9,a-f,x,\\\\]" maxlength="{{userCodeMaxLen}}" minlength="16" value="{{selectedUserCodeValue}}">
|
||||
</paper-input>
|
||||
<pre>Ascii: [[computedCodeOutput]]</pre>
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='lock'
|
||||
service='set_usercode'
|
||||
service-data='[[computeUserCodeServiceData(selectedUserCodeValue, "Add")]]'
|
||||
>Set Usercode</ha-call-service-button>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='lock'
|
||||
service='clear_usercode'
|
||||
service-data='[[computeUserCodeServiceData(selectedUserCode, "Delete")]]'
|
||||
>Delete Usercode</ha-call-service-button>
|
||||
<div class="card-actions">
|
||||
<ha-call-service-button hass="[[hass]]" domain="lock" service="set_usercode" service-data="[[computeUserCodeServiceData(selectedUserCodeValue, "Add")]]">Set Usercode</ha-call-service-button>
|
||||
<ha-call-service-button hass="[[hass]]" domain="lock" service="clear_usercode" service-data="[[computeUserCodeServiceData(selectedUserCode, "Delete")]]">Delete Usercode</ha-call-service-button>
|
||||
</div>
|
||||
</template>
|
||||
</paper-card>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
<script>
|
||||
`;
|
||||
}
|
||||
|
||||
class ZwaveUsercodes extends Polymer.Element {
|
||||
static get is() { return 'zwave-usercodes'; }
|
||||
|
||||
static get properties() {
|
||||
@ -213,4 +195,3 @@ class ZwaveUsercodes extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(ZwaveUsercodes.is, ZwaveUsercodes);
|
||||
</script>
|
||||
@ -1,13 +1,15 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
|
||||
<link rel='import' href='../../../bower_components/paper-item/paper-item.html'>
|
||||
<link rel='import' href="../../../bower_components/paper-listbox/paper-listbox.html">
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../../src/components/buttons/ha-call-service-button.html">
|
||||
import '../../../src/components/buttons/ha-call-service-button.js';
|
||||
|
||||
<dom-module id='zwave-values'>
|
||||
<template>
|
||||
class ZwaveValues extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
margin-top: 24px;
|
||||
@ -32,43 +34,30 @@
|
||||
padding-right: 24px;
|
||||
}
|
||||
</style>
|
||||
<div class='content'>
|
||||
<paper-card heading='Node Values'>
|
||||
<div class='device-picker'>
|
||||
<paper-dropdown-menu label="Value" dynamic-align class='flex'>
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
selected='{{selectedValue}}'>
|
||||
<template is='dom-repeat' items='[[values]]' as='item'>
|
||||
<div class="content">
|
||||
<paper-card heading="Node Values">
|
||||
<div class="device-picker">
|
||||
<paper-dropdown-menu label="Value" dynamic-align="" class="flex">
|
||||
<paper-listbox slot="dropdown-content" selected="{{selectedValue}}">
|
||||
<template is="dom-repeat" items="[[values]]" as="item">
|
||||
<paper-item>[[computeSelectCaption(item)]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</div>
|
||||
<template is='dom-if' if='[[!computeIsValueSelected(selectedValue)]]'>
|
||||
<div class='card-actions'>
|
||||
<paper-input
|
||||
float-label="Value Name"
|
||||
type=text
|
||||
value={{newValueNameInput}}
|
||||
placeholder=[[computeGetValueName(selectedValue)]]>
|
||||
<template is="dom-if" if="[[!computeIsValueSelected(selectedValue)]]">
|
||||
<div class="card-actions">
|
||||
<paper-input float-label="Value Name" type="text" value="{{newValueNameInput}}" placeholder="[[computeGetValueName(selectedValue)]]">
|
||||
</paper-input>
|
||||
<ha-call-service-button
|
||||
hass='[[hass]]'
|
||||
domain='zwave'
|
||||
service='rename_value'
|
||||
service-data=[[computeValueNameServiceData(newValueNameInput)]]
|
||||
>Rename Value</ha-call-service-button>
|
||||
<ha-call-service-button hass="[[hass]]" domain="zwave" service="rename_value" service-data="[[computeValueNameServiceData(newValueNameInput)]]">Rename Value</ha-call-service-button>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
</paper-card>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class ZwaveValues extends Polymer.Element {
|
||||
static get is() { return 'zwave-values'; }
|
||||
|
||||
static get properties() {
|
||||
@ -158,4 +147,3 @@ class ZwaveValues extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(ZwaveValues.is, ZwaveValues);
|
||||
</script>
|
||||
@ -1,9 +1,11 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
import '../../src/util/hass-mixins.js';
|
||||
|
||||
<dom-module id="events-list">
|
||||
<template>
|
||||
class EventsList extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
ul {
|
||||
margin: 0;
|
||||
@ -21,18 +23,16 @@
|
||||
</style>
|
||||
|
||||
<ul>
|
||||
<template is='dom-repeat' items='[[events]]' as='event'>
|
||||
<template is="dom-repeat" items="[[events]]" as="event">
|
||||
<li>
|
||||
<a href='#' on-click='eventSelected'>{{event.event}}</a>
|
||||
<a href="#" on-click="eventSelected">{{event.event}}</a>
|
||||
<span> (</span><span>{{event.listener_count}}</span><span> listeners)</span>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class EventsList extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'events-list'; }
|
||||
|
||||
static get properties() {
|
||||
@ -61,4 +61,3 @@ class EventsList extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(EventsList.is, EventsList);
|
||||
</script>
|
||||
@ -1,23 +1,21 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import '@polymer/app-layout/app-header-layout/app-header-layout.js';
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import '@polymer/paper-input/paper-textarea.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
import '../../src/components/ha-menu-button.js';
|
||||
import '../../src/resources/ha-style.js';
|
||||
import '../../src/util/hass-mixins.js';
|
||||
import './events-list.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="../../bower_components/paper-input/paper-input.html">
|
||||
<link rel="import" href="../../bower_components/paper-input/paper-textarea.html">
|
||||
|
||||
<link rel="import" href="../../bower_components/app-layout/app-header-layout/app-header-layout.html">
|
||||
<link rel="import" href="../../bower_components/app-layout/app-header/app-header.html">
|
||||
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
|
||||
<link rel="import" href="../../src/components/ha-menu-button.html">
|
||||
<link rel="import" href="../../src/resources/ha-style.html">
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
|
||||
<link rel="import" href="./events-list.html">
|
||||
|
||||
<dom-module id="ha-panel-dev-event">
|
||||
<template>
|
||||
class HaPanelDevEvent extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style is="custom-style" include="ha-style iron-flex iron-positioning"></style>
|
||||
<style>
|
||||
:host {
|
||||
@ -63,16 +61,13 @@
|
||||
|
||||
<div>
|
||||
<div class='header'>Available Events</div>
|
||||
<events-list on-event-selected='eventSelected' hass='[[hass]]'></event-list>
|
||||
<events-list on-event-selected='eventSelected' hass='[[hass]]'></events-list>
|
||||
</div>
|
||||
</div>
|
||||
</events-list>
|
||||
</app-header-layout>
|
||||
`;
|
||||
}
|
||||
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaPanelDevEvent extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-panel-dev-event'; }
|
||||
|
||||
static get properties() {
|
||||
@ -134,4 +129,3 @@ class HaPanelDevEvent extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HaPanelDevEvent.is, HaPanelDevEvent);
|
||||
</script>
|
||||
@ -1,22 +1,22 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import '@polymer/app-layout/app-header-layout/app-header-layout.js';
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-dialog-scrollable/paper-dialog-scrollable.js';
|
||||
import '@polymer/paper-dialog/paper-dialog.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-item/paper-item-body.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
<link rel="import" href="../../bower_components/paper-dialog/paper-dialog.html">
|
||||
<link rel="import" href="../../bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html">
|
||||
<link rel="import" href="../../bower_components/paper-item/paper-item.html">
|
||||
<link rel="import" href="../../bower_components/paper-item/paper-item-body.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
import '../../src/components/buttons/ha-call-service-button.js';
|
||||
import '../../src/components/ha-menu-button.js';
|
||||
import '../../src/resources/ha-style.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/app-layout/app-header-layout/app-header-layout.html">
|
||||
<link rel="import" href="../../bower_components/app-layout/app-header/app-header.html">
|
||||
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
|
||||
<link rel="import" href="../../src/components/buttons/ha-call-service-button.html">
|
||||
<link rel="import" href="../../src/components/ha-menu-button.html">
|
||||
<link rel="import" href="../../src/resources/ha-style.html">
|
||||
|
||||
<dom-module id="ha-panel-dev-info">
|
||||
<template>
|
||||
class HaPanelDevInfo extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-positioning ha-style">
|
||||
:host {
|
||||
-ms-user-select: initial;
|
||||
@ -204,7 +204,7 @@
|
||||
<paper-dialog with-backdrop id="showlog">
|
||||
<h2>Log Details ([[selectedItem.level]])</h2>
|
||||
<paper-dialog-scrollable id="scrollable">
|
||||
<p>[[fullTimeStamp(selectedItem.timestamp)]]</p>
|
||||
<p>[[fullTimeStamp(selectedItem.timestamp)]]</p>
|
||||
<template is='dom-if' if='[[selectedItem.message]]'>
|
||||
<pre>[[selectedItem.message]]</pre>
|
||||
</template>
|
||||
@ -213,11 +213,8 @@
|
||||
</template>
|
||||
</paper-dialog-scrollable>
|
||||
</paper-dialog>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaPanelDevInfo extends Polymer.Element {
|
||||
`;
|
||||
}
|
||||
static get is() { return 'ha-panel-dev-info'; }
|
||||
|
||||
static get properties() {
|
||||
@ -334,4 +331,3 @@ class HaPanelDevInfo extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HaPanelDevInfo.is, HaPanelDevInfo);
|
||||
</script>
|
||||
@ -1,20 +1,20 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
import '@polymer/app-layout/app-header-layout/app-header-layout.js';
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import '@polymer/paper-input/paper-textarea.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../bower_components/app-layout/app-header-layout/app-header-layout.html'>
|
||||
<link rel='import' href='../../bower_components/app-layout/app-header/app-header.html'>
|
||||
<link rel='import' href='../../bower_components/app-layout/app-toolbar/app-toolbar.html'>
|
||||
<link rel="import" href="../../bower_components/app-storage/app-localstorage/app-localstorage-document.html">
|
||||
import '../../src/components/ha-menu-button.js';
|
||||
import '../../src/resources/ha-style.js';
|
||||
import '../../src/util/app-localstorage-document.js';
|
||||
|
||||
<link rel='import' href='../../bower_components/paper-card/paper-card.html'>
|
||||
<link rel='import' href='../../bower_components/paper-input/paper-input.html'>
|
||||
<link rel='import' href='../../bower_components/paper-button/paper-button.html'>
|
||||
<link rel='import' href='../../bower_components/paper-input/paper-textarea.html'>
|
||||
|
||||
<link rel='import' href='../../src/components/ha-menu-button.html'>
|
||||
<link rel='import' href='../../src/resources/ha-style.html'>
|
||||
|
||||
<dom-module id='ha-panel-dev-mqtt'>
|
||||
<template>
|
||||
class HaPanelDevMqtt extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include='ha-style'>
|
||||
:host {
|
||||
-ms-user-select: initial;
|
||||
@ -75,11 +75,9 @@
|
||||
</div>
|
||||
|
||||
</app-header-layout>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaPanelDevMqtt extends Polymer.Element {
|
||||
static get is() { return 'ha-panel-dev-mqtt'; }
|
||||
|
||||
static get properties() {
|
||||
@ -101,4 +99,3 @@ class HaPanelDevMqtt extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HaPanelDevMqtt.is, HaPanelDevMqtt);
|
||||
</script>
|
||||
@ -1,20 +1,22 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
import '@polymer/app-layout/app-header-layout/app-header-layout.js';
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-input/paper-textarea.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../bower_components/paper-button/paper-button.html'>
|
||||
<link rel='import' href='../../bower_components/paper-input/paper-textarea.html'>
|
||||
import '../../src/components/entity/ha-entity-picker.js';
|
||||
import '../../src/components/ha-menu-button.js';
|
||||
import '../../src/components/ha-service-picker.js';
|
||||
import '../../src/resources/ha-style.js';
|
||||
import '../../src/util/app-localstorage-document.js';
|
||||
|
||||
<link rel='import' href='../../bower_components/app-layout/app-header-layout/app-header-layout.html'>
|
||||
<link rel='import' href='../../bower_components/app-layout/app-header/app-header.html'>
|
||||
<link rel='import' href='../../bower_components/app-layout/app-toolbar/app-toolbar.html'>
|
||||
<link rel="import" href="../../bower_components/app-storage/app-localstorage/app-localstorage-document.html">
|
||||
|
||||
<link rel='import' href='../../src/components/ha-menu-button.html'>
|
||||
<link rel='import' href='../../src/components/entity/ha-entity-picker.html'>
|
||||
<link rel='import' href='../../src/components/ha-service-picker.html'>
|
||||
<link rel='import' href='../../src/resources/ha-style.html'>
|
||||
|
||||
<dom-module id='ha-panel-dev-service'>
|
||||
<template>
|
||||
{
|
||||
const ERROR_SENTINEL = {};
|
||||
class HaPanelDevService extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include='ha-style'>
|
||||
:host {
|
||||
-ms-user-select: initial;
|
||||
@ -163,13 +165,8 @@
|
||||
</div>
|
||||
|
||||
</app-header-layout>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
{
|
||||
const ERROR_SENTINEL = {};
|
||||
class HaPanelDevService extends Polymer.Element {
|
||||
`;
|
||||
}
|
||||
static get is() { return 'ha-panel-dev-service'; }
|
||||
|
||||
static get properties() {
|
||||
@ -306,4 +303,3 @@
|
||||
|
||||
customElements.define(HaPanelDevService.is, HaPanelDevService);
|
||||
}
|
||||
</script>
|
||||
@ -1,22 +1,21 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import '@polymer/app-layout/app-header-layout/app-header-layout.js';
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-checkbox/paper-checkbox.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import '@polymer/paper-input/paper-textarea.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="../../bower_components/paper-input/paper-input.html">
|
||||
<link rel="import" href="../../bower_components/paper-input/paper-textarea.html">
|
||||
<link rel="import" href="../../bower_components/paper-checkbox/paper-checkbox.html">
|
||||
import '../../src/components/entity/ha-entity-picker.js';
|
||||
import '../../src/components/ha-menu-button.js';
|
||||
import '../../src/resources/ha-style.js';
|
||||
import '../../src/util/hass-mixins.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/app-layout/app-header-layout/app-header-layout.html">
|
||||
<link rel="import" href="../../bower_components/app-layout/app-header/app-header.html">
|
||||
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
|
||||
<link rel="import" href="../../src/components/ha-menu-button.html">
|
||||
<link rel="import" href="../../src/components/entity/ha-entity-picker.html">
|
||||
<link rel="import" href="../../src/resources/ha-style.html">
|
||||
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
|
||||
<dom-module id="ha-panel-dev-state">
|
||||
<template>
|
||||
class HaPanelDevState extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style">
|
||||
:host {
|
||||
-ms-user-select: initial;
|
||||
@ -134,11 +133,8 @@
|
||||
</table>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaPanelDevState extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
`;
|
||||
}
|
||||
static get is() { return 'ha-panel-dev-state'; }
|
||||
|
||||
static get properties() {
|
||||
@ -321,4 +317,3 @@ class HaPanelDevState extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HaPanelDevState.is, HaPanelDevState);
|
||||
</script>
|
||||
@ -1,18 +1,19 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/polymer/lib/utils/debounce.html">
|
||||
import '@polymer/app-layout/app-header-layout/app-header-layout.js';
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/paper-input/paper-textarea.js';
|
||||
import '@polymer/paper-spinner/paper-spinner.js';
|
||||
import { timeOut } from '@polymer/polymer/lib/utils/async.js';
|
||||
import { Debouncer } from '@polymer/polymer/lib/utils/debounce.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/paper-input/paper-textarea.html">
|
||||
<link rel="import" href="../../bower_components/paper-spinner/paper-spinner.html">
|
||||
import '../../src/components/ha-menu-button.js';
|
||||
import '../../src/resources/ha-style.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/app-layout/app-header-layout/app-header-layout.html">
|
||||
<link rel="import" href="../../bower_components/app-layout/app-header/app-header.html">
|
||||
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
|
||||
<link rel="import" href="../../src/components/ha-menu-button.html">
|
||||
<link rel="import" href="../../src/resources/ha-style.html">
|
||||
|
||||
<dom-module id="ha-panel-dev-template">
|
||||
<template>
|
||||
class HaPanelDevTemplate extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style is="custom-style" include="ha-style iron-flex iron-positioning"></style>
|
||||
<style>
|
||||
:host {
|
||||
@ -95,11 +96,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaPanelDevTemplate extends Polymer.Element {
|
||||
`;
|
||||
}
|
||||
static get is() { return 'ha-panel-dev-template'; }
|
||||
|
||||
static get properties() {
|
||||
@ -176,9 +174,9 @@ For loop example:
|
||||
if (this.error) {
|
||||
this.error = false;
|
||||
}
|
||||
this._debouncer = Polymer.Debouncer.debounce(
|
||||
this._debouncer = Debouncer.debounce(
|
||||
this._debouncer,
|
||||
Polymer.Async.timeOut.after(500),
|
||||
timeOut.after(500),
|
||||
() => { this.renderTemplate(); }
|
||||
);
|
||||
}
|
||||
@ -199,4 +197,3 @@ For loop example:
|
||||
}
|
||||
|
||||
customElements.define(HaPanelDevTemplate.is, HaPanelDevTemplate);
|
||||
</script>
|
||||
@ -1,8 +1,12 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id="ha-panel-hassio">
|
||||
<template>
|
||||
import '../../src/util/hass-mixins.js';
|
||||
|
||||
class HaPanelHassio extends
|
||||
window.hassMixins.NavigateMixin(window.hassMixins.EventsMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
iframe {
|
||||
border: 0;
|
||||
@ -15,12 +19,8 @@
|
||||
id='iframe'
|
||||
src="[[iframeUrl]]"
|
||||
></iframe>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaPanelHassio extends
|
||||
window.hassMixins.NavigateMixin(window.hassMixins.EventsMixin(Polymer.Element)) {
|
||||
`;
|
||||
}
|
||||
static get is() { return 'ha-panel-hassio'; }
|
||||
|
||||
static get properties() {
|
||||
@ -78,4 +78,3 @@ class HaPanelHassio extends
|
||||
}
|
||||
|
||||
customElements.define(HaPanelHassio.is, HaPanelHassio);
|
||||
</script>
|
||||
@ -1,25 +1,29 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
<link rel="import" href="../../bower_components/paper-input/paper-input.html">
|
||||
<link rel="import" href="../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
|
||||
<link rel="import" href="../../bower_components/paper-listbox/paper-listbox.html">
|
||||
<link rel="import" href="../../bower_components/paper-item/paper-item.html">
|
||||
<link rel="import" href="../../bower_components/app-layout/app-header-layout/app-header-layout.html">
|
||||
<link rel="import" href="../../bower_components/app-layout/app-header/app-header.html">
|
||||
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
import '@polymer/app-layout/app-header-layout/app-header-layout.js';
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
import '@vaadin/vaadin-date-picker/vaadin-date-picker.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/vaadin-date-picker/vaadin-date-picker.html">
|
||||
import '../../src/components/ha-menu-button.js';
|
||||
import '../../src/components/state-history-charts.js';
|
||||
import '../../src/data/ha-state-history-data.js';
|
||||
import '../../src/resources/ha-date-picker-style.js';
|
||||
import '../../src/resources/ha-style.js';
|
||||
import '../../src/util/hass-mixins.js';
|
||||
|
||||
<link rel="import" href="../../src/components/state-history-charts.html">
|
||||
<link rel="import" href="../../src/components/ha-menu-button.html">
|
||||
<link rel="import" href="../../src/data/ha-state-history-data.html">
|
||||
<link rel="import" href="../../src/resources/ha-style.html">
|
||||
<link rel="import" href="../../src/resources/ha-date-picker-style.html">
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
|
||||
<dom-module id="ha-panel-history">
|
||||
<template>
|
||||
<style include="iron-flex ha-style">
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaPanelHistory extends window.hassMixins.LocalizeMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
padding: 0 16px 16px;
|
||||
}
|
||||
@ -88,14 +92,8 @@
|
||||
</state-history-charts>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaPanelHistory extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
`;
|
||||
}
|
||||
static get is() { return 'ha-panel-history'; }
|
||||
|
||||
static get properties() {
|
||||
@ -157,14 +155,9 @@ class HaPanelHistory extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
// We are unable to parse date because we use intl api to render date
|
||||
// So we just return last known date.
|
||||
var lastFormatDate = new Date();
|
||||
this.$.picker.set('i18n.parseDate', function () {
|
||||
return lastFormatDate;
|
||||
});
|
||||
this.$.picker.set('i18n.parseDate', null);
|
||||
this.$.picker.set('i18n.formatDate', function (date) {
|
||||
lastFormatDate = date;
|
||||
return window.hassUtil.formatDate(date);
|
||||
return window.hassUtil.formatDate(new Date(date.year, date.month, date.day));
|
||||
});
|
||||
}
|
||||
|
||||
@ -194,4 +187,3 @@ class HaPanelHistory extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HaPanelHistory.is, HaPanelHistory);
|
||||
</script>
|
||||
@ -1,12 +1,13 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
import '../../src/components/ha-menu-button.js';
|
||||
import '../../src/resources/ha-style.js';
|
||||
|
||||
<link rel="import" href="../../src/components/ha-menu-button.html">
|
||||
<link rel="import" href="../../src/resources/ha-style.html">
|
||||
|
||||
<dom-module id='ha-panel-iframe'>
|
||||
<template>
|
||||
class HaPanelIframe extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include='ha-style'>
|
||||
iframe {
|
||||
border: 0;
|
||||
@ -24,11 +25,8 @@
|
||||
sandbox="allow-forms allow-popups allow-pointer-lock allow-same-origin allow-scripts"
|
||||
allowfullscreen="true" webkitallowfullscreen="true" mozallowfullscreen="true"
|
||||
></iframe>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaPanelIframe extends Polymer.Element {
|
||||
`;
|
||||
}
|
||||
static get is() { return 'ha-panel-iframe'; }
|
||||
|
||||
static get properties() {
|
||||
@ -49,4 +47,3 @@ class HaPanelIframe extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HaPanelIframe.is, HaPanelIframe);
|
||||
</script>
|
||||
@ -1,30 +0,0 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
|
||||
<link rel='import' href='../../src/layouts/partial-cards.html'>
|
||||
|
||||
<dom-module id="ha-panel-kiosk">
|
||||
<template>
|
||||
<partial-cards
|
||||
id='kiosk-states'
|
||||
hass='[[hass]]'
|
||||
show-menu
|
||||
route='[[route]]'
|
||||
panel-visible
|
||||
></partial-cards>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaPanelKiosk extends Polymer.Element {
|
||||
static get is() { return 'ha-panel-kiosk'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
route: Object,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaPanelKiosk.is, HaPanelKiosk);
|
||||
</script>
|
||||
28
panels/kiosk/ha-panel-kiosk.js
Normal file
28
panels/kiosk/ha-panel-kiosk.js
Normal file
@ -0,0 +1,28 @@
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../../src/layouts/partial-cards.js';
|
||||
|
||||
class HaPanelKiosk extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<partial-cards
|
||||
id='kiosk-states'
|
||||
hass='[[hass]]'
|
||||
show-menu
|
||||
route='[[route]]'
|
||||
panel-visible
|
||||
></partial-cards>
|
||||
`;
|
||||
}
|
||||
static get is() { return 'ha-panel-kiosk'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
route: Object,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaPanelKiosk.is, HaPanelKiosk);
|
||||
@ -1,10 +1,9 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<script>
|
||||
{
|
||||
var DATE_CACHE = {};
|
||||
|
||||
class HaLogbookData extends Polymer.Element {
|
||||
class HaLogbookData extends PolymerElement {
|
||||
static get is() { return 'ha-logbook-data'; }
|
||||
|
||||
static get properties() {
|
||||
@ -77,4 +76,3 @@
|
||||
|
||||
customElements.define(HaLogbookData.is, HaLogbookData);
|
||||
}
|
||||
</script>
|
||||
@ -1,12 +1,13 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../src/components/domain-icon.html">
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
import '../../src/components/domain-icon.js';
|
||||
import '../../src/util/hass-mixins.js';
|
||||
|
||||
|
||||
<dom-module id="ha-logbook">
|
||||
<template>
|
||||
class HaLogbook extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style is="custom-style" include="iron-flex"></style>
|
||||
<style>
|
||||
:host {
|
||||
@ -38,31 +39,29 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<template is='dom-if' if='[[!entries.length]]'>
|
||||
<template is="dom-if" if="[[!entries.length]]">
|
||||
No logbook entries found.
|
||||
</template>
|
||||
|
||||
<template is='dom-repeat' items="[[entries]]">
|
||||
<div class='horizontal layout entry'>
|
||||
<div class='time'>[[formatTime(item.when)]]</div>
|
||||
<domain-icon domain="[[item.domain]]" class='icon'></domain-icon>
|
||||
<div class='message' flex>
|
||||
<template is='dom-if' if="[[!item.entity_id]]">
|
||||
<span class='name'>[[item.name]]</span>
|
||||
<template is="dom-repeat" items="[[entries]]">
|
||||
<div class="horizontal layout entry">
|
||||
<div class="time">[[formatTime(item.when)]]</div>
|
||||
<domain-icon domain="[[item.domain]]" class="icon"></domain-icon>
|
||||
<div class="message" flex="">
|
||||
<template is="dom-if" if="[[!item.entity_id]]">
|
||||
<span class="name">[[item.name]]</span>
|
||||
</template>
|
||||
<template is='dom-if' if="[[item.entity_id]]">
|
||||
<a href='#' on-click="entityClicked" class='name'>[[item.name]]</a>
|
||||
<template is="dom-if" if="[[item.entity_id]]">
|
||||
<a href="#" on-click="entityClicked" class="name">[[item.name]]</a>
|
||||
</template>
|
||||
<span> </span>
|
||||
<span>[[item.message]]</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaLogbook extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-logbook'; }
|
||||
|
||||
static get properties() {
|
||||
@ -89,4 +88,3 @@ class HaLogbook extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HaLogbook.is, HaLogbook);
|
||||
</script>
|
||||
@ -1,25 +1,26 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import '@polymer/app-layout/app-header-layout/app-header-layout.js';
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import '@polymer/paper-spinner/paper-spinner.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
import '@vaadin/vaadin-date-picker/vaadin-date-picker.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
<link rel="import" href="../../bower_components/paper-spinner/paper-spinner.html">
|
||||
<link rel="import" href="../../bower_components/paper-input/paper-input.html">
|
||||
import '../../src/components/ha-menu-button.js';
|
||||
import '../../src/resources/ha-date-picker-style.js';
|
||||
import '../../src/resources/ha-style.js';
|
||||
import '../../src/util/hass-mixins.js';
|
||||
import './ha-logbook-data.js';
|
||||
import './ha-logbook.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/app-layout/app-header-layout/app-header-layout.html">
|
||||
<link rel="import" href="../../bower_components/app-layout/app-header/app-header.html">
|
||||
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
|
||||
<link rel="import" href="../../bower_components/vaadin-date-picker/vaadin-date-picker.html">
|
||||
|
||||
<link rel="import" href="../../src/components/ha-menu-button.html">
|
||||
<link rel="import" href="../../src/resources/ha-style.html">
|
||||
<link rel="import" href="../../src/resources/ha-date-picker-style.html">
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
|
||||
<link rel="import" href="./ha-logbook.html">
|
||||
<link rel="import" href="./ha-logbook-data.html">
|
||||
|
||||
<dom-module id="ha-panel-logbook">
|
||||
<template>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaPanelLogbook extends window.hassMixins.LocalizeMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style">
|
||||
.content {
|
||||
padding: 0 16px 16px;
|
||||
@ -83,14 +84,8 @@
|
||||
<ha-logbook hass='[[hass]]' entries="[[entries]]" hidden$='[[isLoading]]'></ha-logbook>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaPanelLogbook extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
`;
|
||||
}
|
||||
static get is() { return 'ha-panel-logbook'; }
|
||||
|
||||
static get properties() {
|
||||
@ -136,14 +131,9 @@ class HaPanelLogbook extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
// We are unable to parse date because we use intl api to render date
|
||||
// So we just return last known date.
|
||||
var lastFormatDate = new Date();
|
||||
this.$.picker.set('i18n.parseDate', function () {
|
||||
return lastFormatDate;
|
||||
});
|
||||
this.$.picker.set('i18n.parseDate', null);
|
||||
this.$.picker.set('i18n.formatDate', function (date) {
|
||||
lastFormatDate = date;
|
||||
return window.hassUtil.formatDate(date);
|
||||
return window.hassUtil.formatDate(new Date(date.year, date.month, date.day));
|
||||
});
|
||||
}
|
||||
|
||||
@ -160,4 +150,3 @@ class HaPanelLogbook extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HaPanelLogbook.is, HaPanelLogbook);
|
||||
</script>
|
||||
@ -1,24 +1,25 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
import '@polymer/app-layout/app-header-layout/app-header-layout.js';
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-dialog/paper-dialog.js';
|
||||
import '@polymer/paper-input/paper-textarea.js';
|
||||
import '@polymer/paper-item/paper-item-body.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../bower_components/paper-button/paper-button.html'>
|
||||
<link rel='import' href='../../bower_components/paper-dialog/paper-dialog.html'>
|
||||
<link rel='import' href='../../bower_components/paper-input/paper-textarea.html'>
|
||||
<link rel='import' href='../../bower_components/paper-item/paper-item.html'>
|
||||
<link rel='import' href='../../bower_components/paper-item/paper-item-body.html'>
|
||||
<link rel='import' href='../../bower_components/paper-card/paper-card.html'>
|
||||
import '../../src/components/ha-menu-button.js';
|
||||
import '../../src/resources/ha-style.js';
|
||||
import '../../src/util/hass-mixins.js';
|
||||
|
||||
<link rel='import' href='../../bower_components/app-layout/app-header-layout/app-header-layout.html'>
|
||||
<link rel='import' href='../../bower_components/app-layout/app-header/app-header.html'>
|
||||
<link rel='import' href='../../bower_components/app-layout/app-toolbar/app-toolbar.html'>
|
||||
<link rel="import" href="../../bower_components/app-storage/app-localstorage/app-localstorage-document.html">
|
||||
|
||||
<link rel='import' href='../../src/components/ha-menu-button.html'>
|
||||
<link rel='import' href='../../src/resources/ha-style.html'>
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
|
||||
|
||||
<dom-module id='ha-panel-mailbox'>
|
||||
<template>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaPanelMailbox extends window.hassMixins.LocalizeMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include='ha-style'>
|
||||
:host {
|
||||
-ms-user-select: initial;
|
||||
@ -120,7 +121,7 @@
|
||||
</div>
|
||||
</paper-item-body>
|
||||
</paper-item>
|
||||
</template>
|
||||
</template>
|
||||
</paper-card>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
@ -135,7 +136,7 @@
|
||||
</h2>
|
||||
<div id="transcribe"></div>
|
||||
<div>
|
||||
<audio id="mp3" preload="none" controls> <source id="mp3src" src="" type="audio/mpeg"></audio>
|
||||
<audio id="mp3" preload="none" controls> <source id="mp3src" src="" type="audio/mpeg" /></audio>
|
||||
</div>
|
||||
</paper-dialog>
|
||||
|
||||
@ -146,14 +147,8 @@
|
||||
<paper-button dialog-confirm autofocus on-click="deleteSelected">[[localize('ui.panel.mailbox.delete_button')]]</paper-button>
|
||||
</div>
|
||||
</paper-dialog>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaPanelMailbox extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
`;
|
||||
}
|
||||
static get is() { return 'ha-panel-mailbox'; }
|
||||
|
||||
static get properties() {
|
||||
@ -272,5 +267,3 @@ class HaPanelMailbox extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HaPanelMailbox.is, HaPanelMailbox);
|
||||
|
||||
</script>
|
||||
@ -1,11 +1,13 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../bower_components/iron-image/iron-image.html'>
|
||||
<link rel='import' href='../../bower_components/iron-icon/iron-icon.html'>
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import '@polymer/iron-image/iron-image.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
import '../../src/util/hass-mixins.js';
|
||||
|
||||
<dom-module id='ha-entity-marker'>
|
||||
<template>
|
||||
class HaEntityMarker extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style is="custom-style" include="iron-positioning"></style>
|
||||
<style>
|
||||
.marker {
|
||||
@ -28,17 +30,15 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class='marker'>
|
||||
<template is='dom-if' if='[[entityName]]'>[[entityName]]</template>
|
||||
<template is='dom-if' if='[[entityPicture]]'>
|
||||
<iron-image sizing='cover' class='fit' src='[[entityPicture]]'></iron-image>
|
||||
<div class="marker">
|
||||
<template is="dom-if" if="[[entityName]]">[[entityName]]</template>
|
||||
<template is="dom-if" if="[[entityPicture]]">
|
||||
<iron-image sizing="cover" class="fit" src="[[entityPicture]]"></iron-image>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaEntityMarker extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-entity-marker'; }
|
||||
|
||||
static get properties() {
|
||||
@ -78,4 +78,3 @@ class HaEntityMarker extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HaEntityMarker.is, HaEntityMarker);
|
||||
</script>
|
||||
@ -1,15 +1,20 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel='import' href='../../bower_components/iron-icon/iron-icon.html'>
|
||||
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<script src="../../bower_components/leaflet/dist/leaflet.js"></script>
|
||||
import '../../src/components/ha-menu-button.js';
|
||||
import '../../src/util/hass-mixins.js';
|
||||
import './ha-entity-marker.js';
|
||||
|
||||
<link rel="import" href="../../src/components/ha-menu-button.html">
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
<link rel="import" href="./ha-entity-marker.html">
|
||||
window.L.Icon.Default.imagePath = '/static/images/leaflet';
|
||||
|
||||
<dom-module id="ha-panel-map">
|
||||
<template>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaPanelMap extends window.hassMixins.LocalizeMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style">
|
||||
#map {
|
||||
height: calc(100% - 64px);
|
||||
@ -24,16 +29,8 @@
|
||||
</app-toolbar>
|
||||
|
||||
<div id='map'></div>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
window.L.Icon.Default.imagePath = '/static/images/leaflet';
|
||||
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaPanelMap extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
`;
|
||||
}
|
||||
static get is() { return 'ha-panel-map'; }
|
||||
|
||||
static get properties() {
|
||||
@ -197,4 +194,3 @@ class HaPanelMap extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HaPanelMap.is, HaPanelMap);
|
||||
</script>
|
||||
@ -1,23 +1,28 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/app-layout/app-header-layout/app-header-layout.html">
|
||||
<link rel="import" href="../../bower_components/app-layout/app-header/app-header.html">
|
||||
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../bower_components/paper-input/paper-input.html">
|
||||
<link rel="import" href="../../bower_components/paper-item/paper-icon-item.html">
|
||||
<link rel="import" href="../../bower_components/paper-item/paper-item-body.html">
|
||||
<link rel="import" href="../../bower_components/paper-checkbox/paper-checkbox.html">
|
||||
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
<link rel="import" href="../../bower_components/paper-menu-button/paper-menu-button.html">
|
||||
<link rel="import" href="../../bower_components/paper-listbox/paper-listbox.html">
|
||||
<link rel="import" href="../../bower_components/paper-item/paper-item.html">
|
||||
import '@polymer/app-layout/app-header-layout/app-header-layout.js';
|
||||
import '@polymer/app-layout/app-header/app-header.js';
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import '@polymer/paper-checkbox/paper-checkbox.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import '@polymer/paper-item/paper-icon-item.js';
|
||||
import '@polymer/paper-item/paper-item-body.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import '@polymer/paper-menu-button/paper-menu-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
<link rel="import" href="../../src/components/ha-menu-button.html">
|
||||
<link rel="import" href="../../src/components/ha-start-voice-button.html">
|
||||
import '../../src/components/ha-menu-button.js';
|
||||
import '../../src/components/ha-start-voice-button.js';
|
||||
import '../../src/util/hass-mixins.js';
|
||||
|
||||
<dom-module id="ha-panel-shopping-list">
|
||||
<template>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaPanelShoppingList extends window.hassMixins.LocalizeMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style">
|
||||
:host {
|
||||
height: 100%;
|
||||
@ -128,14 +133,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaPanelShoppingList extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
`;
|
||||
}
|
||||
static get is() { return 'ha-panel-shopping-list'; }
|
||||
|
||||
static get properties() {
|
||||
@ -217,4 +216,3 @@ class HaPanelShoppingList extends window.hassMixins.LocalizeMixin(Polymer.Elemen
|
||||
}
|
||||
|
||||
customElements.define(HaPanelShoppingList.is, HaPanelShoppingList);
|
||||
</script>
|
||||
41
polymer.json
41
polymer.json
@ -1,23 +1,22 @@
|
||||
{
|
||||
"entrypoint": "index.html",
|
||||
"shell": "src/home-assistant.html",
|
||||
"shell": "src/home-assistant.js",
|
||||
"fragments": [
|
||||
"panels/config/ha-panel-config.html",
|
||||
"panels/dev-event/ha-panel-dev-event.html",
|
||||
"panels/dev-info/ha-panel-dev-info.html",
|
||||
"panels/dev-mqtt/ha-panel-dev-mqtt.html",
|
||||
"panels/dev-service/ha-panel-dev-service.html",
|
||||
"panels/dev-state/ha-panel-dev-state.html",
|
||||
"panels/dev-template/ha-panel-dev-template.html",
|
||||
"panels/hassio/ha-panel-hassio.html",
|
||||
"panels/history/ha-panel-history.html",
|
||||
"panels/iframe/ha-panel-iframe.html",
|
||||
"panels/kiosk/ha-panel-kiosk.html",
|
||||
"panels/logbook/ha-panel-logbook.html",
|
||||
"panels/map/ha-panel-map.html",
|
||||
"panels/shopping-list/ha-panel-shopping-list.html",
|
||||
"panels/mailbox/ha-panel-mailbox.html",
|
||||
"src/resources/ha-chart-scripts.html"
|
||||
"panels/config/ha-panel-config.js",
|
||||
"panels/dev-event/ha-panel-dev-event.js",
|
||||
"panels/dev-info/ha-panel-dev-info.js",
|
||||
"panels/dev-mqtt/ha-panel-dev-mqtt.js",
|
||||
"panels/dev-service/ha-panel-dev-service.js",
|
||||
"panels/dev-state/ha-panel-dev-state.js",
|
||||
"panels/dev-template/ha-panel-dev-template.js",
|
||||
"panels/hassio/ha-panel-hassio.js",
|
||||
"panels/history/ha-panel-history.js",
|
||||
"panels/iframe/ha-panel-iframe.js",
|
||||
"panels/kiosk/ha-panel-kiosk.js",
|
||||
"panels/logbook/ha-panel-logbook.js",
|
||||
"panels/map/ha-panel-map.js",
|
||||
"panels/shopping-list/ha-panel-shopping-list.js",
|
||||
"panels/mailbox/ha-panel-mailbox.js"
|
||||
],
|
||||
"sources": [
|
||||
"src/**/*",
|
||||
@ -25,7 +24,13 @@
|
||||
"!src/translations/*"
|
||||
],
|
||||
"lint": {
|
||||
"rules": ["polymer-2"]
|
||||
"rules": ["polymer-3"],
|
||||
"filesToIgnore": [
|
||||
"**/*.html",
|
||||
"**/ha-paper-slider.js",
|
||||
"**/hass-mixins.js",
|
||||
"**/ha-iconset-svg.js"
|
||||
]
|
||||
},
|
||||
"builds": [
|
||||
{
|
||||
|
||||
@ -16,45 +16,33 @@ cp -r public/__init__.py $OUTPUT_DIR_ES5/
|
||||
|
||||
# Build frontend
|
||||
BUILD_DEV=0 ./node_modules/.bin/gulp
|
||||
NODE_ENV=production webpack -p
|
||||
BUILD_DEV=0 ./node_modules/.bin/gulp authorize authorize-es5
|
||||
|
||||
# Entry points
|
||||
cp build/*.js build/*.html $OUTPUT_DIR
|
||||
cp build-es5/*.js build-es5/*.html $OUTPUT_DIR_ES5
|
||||
|
||||
# Panels
|
||||
mkdir $OUTPUT_DIR/panels
|
||||
cp build/panels/*.html $OUTPUT_DIR/panels
|
||||
mkdir $OUTPUT_DIR_ES5/panels
|
||||
cp build-es5/panels/*.html $OUTPUT_DIR_ES5/panels
|
||||
|
||||
# Chart code
|
||||
cp build/src/resources/ha-chart-scripts.html $OUTPUT_DIR
|
||||
cp build-es5/src/resources/ha-chart-scripts.html $OUTPUT_DIR_ES5
|
||||
# Copy frontend to output
|
||||
cp build/core.js $OUTPUT_DIR
|
||||
cp build/webpack/* $OUTPUT_DIR
|
||||
cp build-es5/core.js $OUTPUT_DIR_ES5
|
||||
cp build-es5/webpack/* $OUTPUT_DIR_ES5
|
||||
cp build-es5/compatibility.js $OUTPUT_DIR_ES5
|
||||
|
||||
# Translations
|
||||
cp -r build-translations/output $OUTPUT_DIR/translations
|
||||
|
||||
# Local Roboto
|
||||
cp -r bower_components/font-roboto-local/fonts $OUTPUT_DIR
|
||||
cp -r node_modules/@polymer/font-roboto-local/fonts $OUTPUT_DIR
|
||||
|
||||
# Polyfill web components
|
||||
cp bower_components/webcomponentsjs/webcomponents-lite.js $OUTPUT_DIR
|
||||
cp bower_components/webcomponentsjs/custom-elements-es5-adapter.js $OUTPUT_DIR_ES5
|
||||
cp node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js $OUTPUT_DIR
|
||||
cp node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js $OUTPUT_DIR_ES5
|
||||
|
||||
# Icons
|
||||
script/update_mdi.py
|
||||
|
||||
# Leaflet
|
||||
mkdir $OUTPUT_DIR/images/leaflet
|
||||
cp bower_components/leaflet/dist/leaflet.css $OUTPUT_DIR/images/leaflet
|
||||
cp -r bower_components/leaflet/dist/images $OUTPUT_DIR/images/leaflet/
|
||||
|
||||
# Generate service worker
|
||||
BUILD_DEV=0 ./node_modules/.bin/gulp gen-service-worker-es5
|
||||
cp build-es5/service_worker.js $OUTPUT_DIR_ES5
|
||||
BUILD_DEV=0 ./node_modules/.bin/gulp gen-service-worker
|
||||
cp build/service_worker.js $OUTPUT_DIR
|
||||
cp node_modules/leaflet/dist/leaflet.css $OUTPUT_DIR/images/leaflet
|
||||
cp -r node_modules/leaflet/dist/images $OUTPUT_DIR/images/leaflet/
|
||||
|
||||
./node_modules/.bin/gulp compress
|
||||
|
||||
@ -65,7 +53,5 @@ echo "VERSION = '`git rev-parse HEAD`'" >> $OUTPUT_DIR_ES5/__init__.py
|
||||
echo "CREATED_AT = `date +%s`" >> $OUTPUT_DIR_ES5/__init__.py
|
||||
|
||||
# Generate the MD5 hash of the new frontend
|
||||
script/fingerprint_frontend.py --base_dir $OUTPUT_DIR
|
||||
script/fingerprint_frontend.py --base_dir $OUTPUT_DIR_ES5
|
||||
./node_modules/.bin/gulp gen-index-html
|
||||
./node_modules/.bin/gulp gen-index-html-es5
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Set XSS_VERSION or MARKED_VERSION to set package versions. If unset, the latest version will be used.
|
||||
|
||||
# Stop on errors
|
||||
set -e
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
output="public/markdown-js.html"
|
||||
|
||||
echo "<script>" > $output
|
||||
|
||||
pkgs="xss:dist/xss.min.js marked:marked.min.js"
|
||||
|
||||
for pkg in $pkgs; do
|
||||
name="$(cut -d':' -f1 <<< "$pkg")"
|
||||
js_path="$(cut -d':' -f2 <<< "$pkg")"
|
||||
|
||||
# Check env variable for version
|
||||
version=$(eval "echo \$$(echo $name | tr "a-z" "A-Z")_VERSION")
|
||||
if [ -z "$version" ]; then
|
||||
version=$(yarn -s info $name dist-tags.latest)
|
||||
fi
|
||||
|
||||
homepage=$(yarn -s info "$name@$version" homepage)
|
||||
license=$(yarn -s info "$name@$version" license)
|
||||
tarball=$(yarn -s info "$name@$version" dist.tarball)
|
||||
|
||||
cat >>$output <<EOF
|
||||
/*
|
||||
* $name@$version ($license)
|
||||
* $homepage
|
||||
*/
|
||||
EOF
|
||||
echo "Downloading $name@$version"
|
||||
curl -s "$tarball" | tar -xzO "package/$js_path" | ./node_modules/.bin/uglifyjs -c -m >> $output
|
||||
done
|
||||
|
||||
echo "</script>" >> $output
|
||||
|
||||
size=$(wc -c < $output)
|
||||
gzip_size=$(cat $output | gzip | wc -c)
|
||||
|
||||
echo "$size bytes ($gzip_size bytes gzipped) written to $output"
|
||||
@ -1,39 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate a file with all md5 hashes of the assets."""
|
||||
|
||||
from collections import OrderedDict
|
||||
import glob
|
||||
import hashlib
|
||||
import json
|
||||
import argparse
|
||||
from os import path
|
||||
import re
|
||||
|
||||
parser = argparse.ArgumentParser(description='Generate fingerprints of frontend files.')
|
||||
parser.add_argument('--base_dir', type=str, help='Base dir to look for files.', default='hass_frontend')
|
||||
args = parser.parse_args()
|
||||
base_dir = args.base_dir + '/'
|
||||
fingerprint_file = path.join(base_dir, '__init__.py')
|
||||
panel_match = re.compile(r'ha-panel-((\w|-)+)\.html')
|
||||
|
||||
|
||||
def fingerprint():
|
||||
"""Fingerprint the panels."""
|
||||
files = glob.glob(base_dir + 'panels/*.html')
|
||||
md5s = OrderedDict()
|
||||
|
||||
for fil in sorted(files):
|
||||
panel = panel_match.search(fil).groups(0)[0]
|
||||
with open(fil) as fp:
|
||||
md5 = hashlib.md5(fp.read().encode('utf-8')).hexdigest()
|
||||
md5s[panel] = md5
|
||||
|
||||
template = "FINGERPRINTS = {}\n"
|
||||
result = template.format(json.dumps(md5s, indent=4))
|
||||
|
||||
with open(fingerprint_file, 'at') as fp:
|
||||
fp.write(result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
fingerprint()
|
||||
@ -34,7 +34,7 @@ def get_remote_version():
|
||||
|
||||
def clean_component(source):
|
||||
"""Clean component."""
|
||||
return source[source.index(START_ICONSET):]
|
||||
return source[source.index(START_ICONSET):].replace('iron-iconset-svg', 'ha-iconset-svg')
|
||||
|
||||
|
||||
def write_component(source):
|
||||
|
||||
@ -1,41 +1,36 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href='../../bower_components/paper-button/paper-button.html'>
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import '../components/ha-form.js';
|
||||
import '../util/hass-mixins.js';
|
||||
|
||||
<link rel='import' href='../components/ha-form.html'>
|
||||
<link rel='import' href='../util/hass-mixins.html'>
|
||||
|
||||
<dom-module id='ha-auth-flow'>
|
||||
<template>
|
||||
<template is='dom-if' if='[[_equals(_state, "loading")]]'>
|
||||
Please wait
|
||||
</template>
|
||||
<template is='dom-if' if='[[_equals(_state, "error")]]'>
|
||||
Something went wrong
|
||||
</template>
|
||||
<template is='dom-if' if='[[_equals(_state, "step")]]'>
|
||||
<template is='dom-if' if='[[_equals(_step.type, "abort")]]'>
|
||||
Aborted
|
||||
</template>
|
||||
<template is='dom-if' if='[[_equals(_step.type, "create_entry")]]'>
|
||||
Success!
|
||||
</template>
|
||||
<template is='dom-if' if='[[_equals(_step.type, "form")]]'>
|
||||
<ha-form
|
||||
data='{{_stepData}}'
|
||||
schema='[[_step.data_schema]]'
|
||||
error='[[_step.errors]]'
|
||||
></ha-form>
|
||||
</template>
|
||||
<paper-button on-click='_handleSubmit'>[[_computeSubmitCaption(_step.type)]]</paper-button>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaAuthFlow extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
class HaAuthFlow extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<template is="dom-if" if="[[_equals(_state, "loading")]]">
|
||||
Please wait
|
||||
</template>
|
||||
<template is="dom-if" if="[[_equals(_state, "error")]]">
|
||||
Something went wrong
|
||||
</template>
|
||||
<template is="dom-if" if="[[_equals(_state, "step")]]">
|
||||
<template is="dom-if" if="[[_equals(_step.type, "abort")]]">
|
||||
Aborted
|
||||
</template>
|
||||
<template is="dom-if" if="[[_equals(_step.type, "create_entry")]]">
|
||||
Success!
|
||||
</template>
|
||||
<template is="dom-if" if="[[_equals(_step.type, "form")]]">
|
||||
<ha-form data="{{_stepData}}" schema="[[_step.data_schema]]" error="[[_step.errors]]"></ha-form>
|
||||
</template>
|
||||
<paper-button on-click="_handleSubmit">[[_computeSubmitCaption(_step.type)]]</paper-button>
|
||||
</template>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-auth-flow'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -140,4 +135,3 @@ class HaAuthFlow extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
}
|
||||
customElements.define(HaAuthFlow.is, HaAuthFlow);
|
||||
</script>
|
||||
@ -1,13 +1,15 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../bower_components/polymer/lib/elements/dom-if.html'>
|
||||
<link rel='import' href='../../bower_components/polymer/lib/elements/dom-repeat.html'>
|
||||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import '@polymer/polymer/lib/elements/dom-if.js';
|
||||
import '@polymer/polymer/lib/elements/dom-repeat.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='./ha-pick-auth-provider.html'>
|
||||
<link rel='import' href='./ha-auth-flow.html'>
|
||||
import './ha-auth-flow.js';
|
||||
import './ha-pick-auth-provider.js';
|
||||
|
||||
<dom-module id='ha-authorize'>
|
||||
<template>
|
||||
class HaAuthorize extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style is="custom-style" include="iron-flex iron-positioning"></style>
|
||||
<style>
|
||||
.layout {
|
||||
@ -15,31 +17,18 @@
|
||||
}
|
||||
</style>
|
||||
<div class="layout vertical center fit">
|
||||
<img src="/static/icons/favicon-192x192.png" height="192" />
|
||||
<img src="/static/icons/favicon-192x192.png" height="192">
|
||||
|
||||
<template is='dom-if' if='[[_authProvider]]'>
|
||||
<ha-auth-flow
|
||||
client-id='[[clientId]]'
|
||||
client-secret='[[clientSecret]]'
|
||||
redirect-uri='[[redirectUri]]'
|
||||
oauth2-state='[[oauth2State]]'
|
||||
auth-provider='[[_authProvider]]'
|
||||
on-reset='_handleReset'
|
||||
/>
|
||||
</template>
|
||||
<template is='dom-if' if='[[!_authProvider]]'>
|
||||
<ha-pick-auth-provider
|
||||
client-id='[[clientId]]'
|
||||
client-secret='[[clientSecret]]'
|
||||
on-pick='_handleAuthProviderPick'
|
||||
></ha-pick-auth-provider>
|
||||
<template is="dom-if" if="[[_authProvider]]">
|
||||
<ha-auth-flow client-id="[[clientId]]" client-secret="[[clientSecret]]" redirect-uri="[[redirectUri]]" oauth2-state="[[oauth2State]]" auth-provider="[[_authProvider]]" on-reset="_handleReset">
|
||||
</ha-auth-flow></template>
|
||||
<template is="dom-if" if="[[!_authProvider]]">
|
||||
<ha-pick-auth-provider client-id="[[clientId]]" client-secret="[[clientSecret]]" on-pick="_handleAuthProviderPick"></ha-pick-auth-provider>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaAuthorize extends Polymer.Element {
|
||||
static get is() { return 'ha-authorize'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -78,4 +67,3 @@ class HaAuthorize extends Polymer.Element {
|
||||
}
|
||||
}
|
||||
customElements.define(HaAuthorize.is, HaAuthorize);
|
||||
</script>
|
||||
@ -1,10 +1,15 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../bower_components/paper-item/paper-item.html'>
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../util/hass-mixins.html'>
|
||||
import '../util/hass-mixins.js';
|
||||
|
||||
<dom-module id='ha-pick-auth-provider'>
|
||||
<template>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaPickAuthProvider extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
text-align: center;
|
||||
@ -14,29 +19,24 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
<template is='dom-if' if='[[_equal(_state, "loading")]]'>
|
||||
<template is="dom-if" if="[[_equal(_state, "loading")]]">
|
||||
Loading auth providers.
|
||||
</template>
|
||||
<template is='dom-if' if='[[_equal(_state, "no-results")]]'>
|
||||
<template is="dom-if" if="[[_equal(_state, "no-results")]]">
|
||||
No auth providers found.
|
||||
</template>
|
||||
<template is='dom-if' if='[[_equal(_state, "error-loading")]]'>
|
||||
<template is="dom-if" if="[[_equal(_state, "error-loading")]]">
|
||||
Error loading
|
||||
</template>
|
||||
<template is='dom-if' if='[[_equal(_state, "pick")]]'>
|
||||
<template is="dom-if" if="[[_equal(_state, "pick")]]">
|
||||
<p>Log in with</p>
|
||||
<template is='dom-repeat' items='[[authProviders]]'>
|
||||
<paper-item on-click='_handlePick'>[[item.name]]</paper-item>
|
||||
<template is="dom-repeat" items="[[authProviders]]">
|
||||
<paper-item on-click="_handlePick">[[item.name]]</paper-item>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaPickAuthProvider extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-pick-auth-provider'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -83,4 +83,3 @@ class HaPickAuthProvider extends window.hassMixins.EventsMixin(Polymer.Element)
|
||||
}
|
||||
}
|
||||
customElements.define(HaPickAuthProvider.is, HaPickAuthProvider);
|
||||
</script>
|
||||
@ -8,19 +8,19 @@
|
||||
<body>
|
||||
<ha-authorize>Loading</ha-authorize>
|
||||
<script>
|
||||
function addScript(src) {
|
||||
var e = document.createElement('script');
|
||||
e.src = src;
|
||||
document.head.appendChild(e);
|
||||
}
|
||||
var webComponentsSupported = (
|
||||
'customElements' in window &&
|
||||
'import' in document.createElement('link') &&
|
||||
'content' in document.createElement('template'));
|
||||
if (!webComponentsSupported) {
|
||||
addScript('/static/webcomponents-lite.js');
|
||||
}
|
||||
function addScript(src) {
|
||||
var e = document.createElement('script');
|
||||
e.src = src;
|
||||
document.head.appendChild(e);
|
||||
}
|
||||
var webComponentsSupported = (
|
||||
'customElements' in window &&
|
||||
'import' in document.createElement('link') &&
|
||||
'content' in document.createElement('template'));
|
||||
if (!webComponentsSupported) {
|
||||
addScript('/static/webcomponents-lite.js');
|
||||
}
|
||||
</script>
|
||||
<link rel='import' href='./auth/ha-authorize.html'>
|
||||
<script src="/home-assistant-polymer/build/webpack/ha-authorize.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
|
||||
<link rel='import' href='../components/entity/ha-state-label-badge.html'>
|
||||
|
||||
<dom-module id='ha-badges-card'>
|
||||
<template>
|
||||
<style>
|
||||
ha-state-label-badge {
|
||||
display: inline-block;
|
||||
margin-bottom: var(--ha-state-label-badge-margin-bottom, 16px);
|
||||
}
|
||||
</style>
|
||||
<template is='dom-repeat' items='[[states]]'>
|
||||
<ha-state-label-badge hass='[[hass]]' state='[[item]]'></ha-state-label-badge>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaBadgesCard extends Polymer.Element {
|
||||
static get is() { return 'ha-badges-card'; }
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
states: Array,
|
||||
};
|
||||
}
|
||||
}
|
||||
customElements.define(HaBadgesCard.is, HaBadgesCard);
|
||||
</script>
|
||||
29
src/cards/ha-badges-card.js
Normal file
29
src/cards/ha-badges-card.js
Normal file
@ -0,0 +1,29 @@
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../components/entity/ha-state-label-badge.js';
|
||||
|
||||
class HaBadgesCard extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
ha-state-label-badge {
|
||||
display: inline-block;
|
||||
margin-bottom: var(--ha-state-label-badge-margin-bottom, 16px);
|
||||
}
|
||||
</style>
|
||||
<template is="dom-repeat" items="[[states]]">
|
||||
<ha-state-label-badge hass="[[hass]]" state="[[item]]"></ha-state-label-badge>
|
||||
</template>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-badges-card'; }
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
states: Array,
|
||||
};
|
||||
}
|
||||
}
|
||||
customElements.define(HaBadgesCard.is, HaBadgesCard);
|
||||
@ -1,12 +1,22 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href="../../bower_components/paper-material/paper-material.html">
|
||||
import '@polymer/paper-styles/element-styles/paper-material-styles.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../util/hass-mixins.html'>
|
||||
import '../util/hass-mixins.js';
|
||||
|
||||
<dom-module id='ha-camera-card'>
|
||||
<template>
|
||||
<style include="paper-material">
|
||||
{
|
||||
const UPDATE_INTERVAL = 10000; // ms
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaCameraCard extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="paper-material-styles">
|
||||
:host {
|
||||
@apply --paper-material-elevation-1;
|
||||
display: block;
|
||||
position: relative;
|
||||
font-size: 0px;
|
||||
@ -39,29 +49,16 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<img
|
||||
src='[[cameraFeedSrc]]'
|
||||
class='camera-feed'
|
||||
hidden$='[[!imageLoaded]]'
|
||||
alt='[[computeStateName(stateObj)]]'>
|
||||
<div class='caption'>
|
||||
<img src="[[cameraFeedSrc]]" class="camera-feed" hidden\$="[[!imageLoaded]]" alt="[[computeStateName(stateObj)]]">
|
||||
<div class="caption">
|
||||
[[computeStateName(stateObj)]]
|
||||
<template is='dom-if' if='[[!imageLoaded]]'>
|
||||
<template is="dom-if" if="[[!imageLoaded]]">
|
||||
([[localize('ui.card.camera.not_available')]])
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
{
|
||||
const UPDATE_INTERVAL = 10000; // ms
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaCameraCard extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(Polymer.Element)) {
|
||||
static get is() { return 'ha-camera-card'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -75,14 +72,6 @@
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
/**
|
||||
* The z-depth of the card, from 0-5.
|
||||
*/
|
||||
elevation: {
|
||||
type: Number,
|
||||
value: 1,
|
||||
reflectToAttribute: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ -127,4 +116,3 @@
|
||||
}
|
||||
customElements.define(HaCameraCard.is, HaCameraCard);
|
||||
}
|
||||
</script>
|
||||
@ -1,15 +1,14 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='./ha-camera-card.html'>
|
||||
<link rel='import' href='./ha-entities-card.html'>
|
||||
<link rel='import' href='./ha-history_graph-card.html'>
|
||||
<link rel='import' href='./ha-media_player-card.html'>
|
||||
<link rel='import' href='./ha-weather-card.html'>
|
||||
<link rel='import' href='./ha-persistent_notification-card.html'>
|
||||
<link rel='import' href='./ha-plant-card.html'>
|
||||
import './ha-camera-card.js';
|
||||
import './ha-entities-card.js';
|
||||
import './ha-history_graph-card.js';
|
||||
import './ha-media_player-card.js';
|
||||
import './ha-persistent_notification-card.js';
|
||||
import './ha-plant-card.js';
|
||||
import './ha-weather-card.js';
|
||||
|
||||
<script>
|
||||
class HaCardChooser extends Polymer.Element {
|
||||
class HaCardChooser extends PolymerElement {
|
||||
static get is() { return 'ha-card-chooser'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -78,4 +77,3 @@ class HaCardChooser extends Polymer.Element {
|
||||
}
|
||||
}
|
||||
customElements.define(HaCardChooser.is, HaCardChooser);
|
||||
</script>
|
||||
@ -1,14 +1,16 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
import '../components/entity/ha-entity-toggle.js';
|
||||
import '../components/ha-card.js';
|
||||
import '../state-summary/state-card-content.js';
|
||||
import '../util/hass-mixins.js';
|
||||
|
||||
<link rel='import' href='../components/ha-card.html'>
|
||||
<link rel='import' href='../components/entity/ha-entity-toggle.html'>
|
||||
<link rel='import' href='../state-summary/state-card-content.html'>
|
||||
<link rel='import' href='../util/hass-mixins.html'>
|
||||
|
||||
<dom-module id='ha-entities-card'>
|
||||
<template>
|
||||
class HaEntitiesCard extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style is="custom-style" include="iron-flex"></style>
|
||||
<style>
|
||||
ha-card {
|
||||
@ -37,33 +39,25 @@
|
||||
</style>
|
||||
|
||||
<ha-card>
|
||||
<template is='dom-if' if='[[title]]'>
|
||||
<div class$='[[computeTitleClass(groupEntity)]]' on-click='entityTapped'>
|
||||
<div class='flex name'>[[title]]</div>
|
||||
<template is='dom-if' if='[[showGroupToggle(groupEntity, states)]]'>
|
||||
<ha-entity-toggle
|
||||
hass='[[hass]]'
|
||||
state-obj='[[groupEntity]]'></ha-entity-toggle>
|
||||
<template is="dom-if" if="[[title]]">
|
||||
<div class\$="[[computeTitleClass(groupEntity)]]" on-click="entityTapped">
|
||||
<div class="flex name">[[title]]</div>
|
||||
<template is="dom-if" if="[[showGroupToggle(groupEntity, states)]]">
|
||||
<ha-entity-toggle hass="[[hass]]" state-obj="[[groupEntity]]"></ha-entity-toggle>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<div class='states'>
|
||||
<template is='dom-repeat' items='[[states]]' on-dom-change='addTapEvents'>
|
||||
<div class$='[[computeStateClass(item)]]'>
|
||||
<state-card-content
|
||||
hass='[[hass]]'
|
||||
class='state-card'
|
||||
state-obj='[[item]]'></state-card-content>
|
||||
<div class="states">
|
||||
<template is="dom-repeat" items="[[states]]" on-dom-change="addTapEvents">
|
||||
<div class\$="[[computeStateClass(item)]]">
|
||||
<state-card-content hass="[[hass]]" class="state-card" state-obj="[[item]]"></state-card-content>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</ha-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaEntitiesCard extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(Polymer.Element)) {
|
||||
static get is() { return 'ha-entities-card'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -155,4 +149,3 @@ class HaEntitiesCard extends
|
||||
}
|
||||
}
|
||||
customElements.define(HaEntitiesCard.is, HaEntitiesCard);
|
||||
</script>
|
||||
@ -1,12 +1,14 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
import '@polymer/paper-card/paper-card.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../components/state-history-charts.html">
|
||||
<link rel="import" href="../data/ha-state-history-data.html">
|
||||
<link rel='import' href='../util/hass-mixins.html'>
|
||||
import '../components/state-history-charts.js';
|
||||
import '../data/ha-state-history-data.js';
|
||||
import '../util/hass-mixins.js';
|
||||
|
||||
<dom-module id='ha-history_graph-card'>
|
||||
<template>
|
||||
class HaHistoryGraphCard extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
paper-card:not([dialog]) .content {
|
||||
padding: 0 16px 16px;
|
||||
@ -31,32 +33,17 @@
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<ha-state-history-data
|
||||
hass='[[hass]]'
|
||||
filter-type='recent-entity'
|
||||
entity-id='[[computeHistoryEntities(stateObj)]]'
|
||||
data='{{stateHistory}}'
|
||||
is-loading='{{stateHistoryLoading}}'
|
||||
cache-config='[[cacheConfig]]'
|
||||
></ha-state-history-data>
|
||||
<paper-card dialog$='[[inDialog]]'
|
||||
on-click='cardTapped'
|
||||
elevation='[[computeElevation(inDialog)]]'>
|
||||
<div class='header'>[[computeTitle(stateObj)]]</div>
|
||||
<div class='content'>
|
||||
<state-history-charts
|
||||
history-data="[[stateHistory]]"
|
||||
is-loading-data="[[stateHistoryLoading]]"
|
||||
up-to-now
|
||||
no-single>
|
||||
<ha-state-history-data hass="[[hass]]" filter-type="recent-entity" entity-id="[[computeHistoryEntities(stateObj)]]" data="{{stateHistory}}" is-loading="{{stateHistoryLoading}}" cache-config="[[cacheConfig]]"></ha-state-history-data>
|
||||
<paper-card dialog\$="[[inDialog]]" on-click="cardTapped" elevation="[[computeElevation(inDialog)]]">
|
||||
<div class="header">[[computeTitle(stateObj)]]</div>
|
||||
<div class="content">
|
||||
<state-history-charts history-data="[[stateHistory]]" is-loading-data="[[stateHistoryLoading]]" up-to-now="" no-single="">
|
||||
</state-history-charts>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaHistoryGraphCard extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-history_graph-card'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -120,4 +107,3 @@ class HaHistoryGraphCard extends window.hassMixins.EventsMixin(Polymer.Element)
|
||||
}
|
||||
}
|
||||
customElements.define(HaHistoryGraphCard.is, HaHistoryGraphCard);
|
||||
</script>
|
||||
@ -1,18 +1,24 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-progress/paper-progress.js';
|
||||
import '@polymer/paper-styles/element-styles/paper-material-styles.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
import '../util/hass-media-player-model.js';
|
||||
import '../util/hass-mixins.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/paper-material/paper-material.html">
|
||||
<link rel='import' href='../../bower_components/paper-icon-button/paper-icon-button.html'>
|
||||
<link rel='import' href='../../bower_components/paper-progress/paper-progress.html'>
|
||||
|
||||
<link rel='import' href='../util/hass-media-player-model.html'>
|
||||
<link rel='import' href='../util/hass-mixins.html'>
|
||||
|
||||
<dom-module id='ha-media_player-card'>
|
||||
<template>
|
||||
<style include="paper-material iron-flex iron-flex-alignment iron-positioning">
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaMediaPlayerCard extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="paper-material-styles iron-flex iron-flex-alignment iron-positioning">
|
||||
:host {
|
||||
@apply --paper-material-elevation-1;
|
||||
display: block;
|
||||
position: relative;
|
||||
font-size: 0px;
|
||||
@ -148,70 +154,33 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class$='[[computeBannerClasses(playerObj)]]'>
|
||||
<div class='cover' id='cover'></div>
|
||||
<div class\$="[[computeBannerClasses(playerObj)]]">
|
||||
<div class="cover" id="cover"></div>
|
||||
|
||||
<div class='caption'>
|
||||
<div class="caption">
|
||||
[[computeStateName(stateObj)]]
|
||||
<div class='title'>[[computePrimaryText(localize, playerObj)]]</div>
|
||||
[[playerObj.secondaryTitle]]<br />
|
||||
<div class="title">[[computePrimaryText(localize, playerObj)]]</div>
|
||||
[[playerObj.secondaryTitle]]<br>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<paper-progress
|
||||
max='[[stateObj.attributes.media_duration]]'
|
||||
value='[[playbackPosition]]'
|
||||
hidden$='[[computeHideProgress(playerObj)]]'
|
||||
class='progress'
|
||||
></paper-progress>
|
||||
<paper-progress max="[[stateObj.attributes.media_duration]]" value="[[playbackPosition]]" hidden\$="[[computeHideProgress(playerObj)]]" class="progress"></paper-progress>
|
||||
|
||||
<div class='controls layout horizontal justified'>
|
||||
<paper-icon-button
|
||||
icon='mdi:power'
|
||||
on-click='handleTogglePower'
|
||||
invisible$='[[computeHidePowerButton(playerObj)]]'
|
||||
class='self-center secondary'
|
||||
></paper-icon-button>
|
||||
<div class="controls layout horizontal justified">
|
||||
<paper-icon-button icon="mdi:power" on-click="handleTogglePower" invisible\$="[[computeHidePowerButton(playerObj)]]" class="self-center secondary"></paper-icon-button>
|
||||
|
||||
<div>
|
||||
<paper-icon-button
|
||||
icon='mdi:skip-previous'
|
||||
invisible$='[[!playerObj.supportsPreviousTrack]]'
|
||||
disabled='[[playerObj.isOff]]'
|
||||
on-click='handlePrevious'
|
||||
></paper-icon-button>
|
||||
<paper-icon-button
|
||||
class='primary'
|
||||
icon='[[computePlaybackControlIcon(playerObj)]]'
|
||||
invisible$='[[!computePlaybackControlIcon(playerObj)]]'
|
||||
disabled='[[playerObj.isOff]]'
|
||||
on-click='handlePlaybackControl'
|
||||
></paper-icon-button>
|
||||
<paper-icon-button
|
||||
icon='mdi:skip-next'
|
||||
invisible$='[[!playerObj.supportsNextTrack]]'
|
||||
disabled='[[playerObj.isOff]]'
|
||||
on-click='handleNext'
|
||||
></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:skip-previous" invisible\$="[[!playerObj.supportsPreviousTrack]]" disabled="[[playerObj.isOff]]" on-click="handlePrevious"></paper-icon-button>
|
||||
<paper-icon-button class="primary" icon="[[computePlaybackControlIcon(playerObj)]]" invisible\$="[[!computePlaybackControlIcon(playerObj)]]" disabled="[[playerObj.isOff]]" on-click="handlePlaybackControl"></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:skip-next" invisible\$="[[!playerObj.supportsNextTrack]]" disabled="[[playerObj.isOff]]" on-click="handleNext"></paper-icon-button>
|
||||
</div>
|
||||
|
||||
<paper-icon-button
|
||||
icon='mdi:dots-vertical'
|
||||
on-click='handleOpenMoreInfo'
|
||||
class='self-center secondary'
|
||||
></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:dots-vertical" on-click="handleOpenMoreInfo" class="self-center secondary"></paper-icon-button>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaMediaPlayerCard extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(Polymer.Element)) {
|
||||
static get is() { return 'ha-media_player-card'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -227,14 +196,6 @@ class HaMediaPlayerCard extends
|
||||
computed: 'computePlaybackControlIcon(playerObj)',
|
||||
},
|
||||
playbackPosition: Number,
|
||||
/**
|
||||
* The z-depth of the card, from 0-5.
|
||||
*/
|
||||
elevation: {
|
||||
type: Number,
|
||||
value: 1,
|
||||
reflectToAttribute: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ -347,4 +308,3 @@ class HaMediaPlayerCard extends
|
||||
}
|
||||
}
|
||||
customElements.define(HaMediaPlayerCard.is, HaMediaPlayerCard);
|
||||
</script>
|
||||
@ -1,13 +1,17 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../bower_components/paper-button/paper-button.html'>
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../components/ha-card.html'>
|
||||
<link rel='import' href='../components/ha-markdown.html'>
|
||||
import '../components/ha-card.js';
|
||||
import '../components/ha-markdown.js';
|
||||
import '../util/hass-mixins.js';
|
||||
|
||||
<link rel='import' href='../util/hass-mixins.html'>
|
||||
|
||||
<dom-module id='ha-persistent_notification-card'>
|
||||
<template>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaPersistentNotificationCard extends window.hassMixins.LocalizeMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
@apply --paper-font-body1;
|
||||
@ -37,18 +41,13 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<ha-card header='[[computeTitle(stateObj)]]'>
|
||||
<ha-markdown content='[[stateObj.attributes.message]]'></ha-markdown>
|
||||
<paper-button on-click='dismissTap'>[[localize('ui.card.persistent_notification.dismiss')]]</paper-button>
|
||||
<ha-card header="[[computeTitle(stateObj)]]">
|
||||
<ha-markdown content="[[stateObj.attributes.message]]"></ha-markdown>
|
||||
<paper-button on-click="dismissTap">[[localize('ui.card.persistent_notification.dismiss')]]</paper-button>
|
||||
</ha-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaPersistentNotificationCard extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-persistent_notification-card'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -68,4 +67,3 @@ class HaPersistentNotificationCard extends window.hassMixins.LocalizeMixin(Polym
|
||||
}
|
||||
}
|
||||
customElements.define(HaPersistentNotificationCard.is, HaPersistentNotificationCard);
|
||||
</script>
|
||||
@ -1,10 +1,13 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../bower_components/iron-icon/iron-icon.html'>
|
||||
<link rel='import' href='../components/ha-card.html'>
|
||||
<link rel='import' href='../util/hass-mixins.html'>
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id="ha-plant-card">
|
||||
<template>
|
||||
import '../components/ha-card.js';
|
||||
import '../util/hass-mixins.js';
|
||||
|
||||
class HaPlantCard extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
.content {
|
||||
display: flex;
|
||||
@ -30,12 +33,12 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<ha-card header='[[computeTitle(stateObj)]]'>
|
||||
<div class='content'>
|
||||
<ha-card header="[[computeTitle(stateObj)]]">
|
||||
<div class="content">
|
||||
<template is="dom-repeat" items="[[computeAttributes(stateObj.attributes)]]">
|
||||
<div class="attributes" on-click="attributeClicked">
|
||||
<div><iron-icon icon="[[computeIcon(item, stateObj.attributes.battery)]]"></iron-icon></div>
|
||||
<div class$="[[computeClass(stateObj.attributes.problem, item)]]">
|
||||
<div class\$="[[computeClass(stateObj.attributes.problem, item)]]">
|
||||
[[computeValue(stateObj.attributes, item)]]
|
||||
</div>
|
||||
<div class="uom">[[computeUom(stateObj.attributes.unit_of_measurement_dict, item)]]</div>
|
||||
@ -43,11 +46,9 @@
|
||||
</template>
|
||||
</div>
|
||||
</ha-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaPlantCard extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-plant-card'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -105,4 +106,3 @@ class HaPlantCard extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HaPlantCard.is, HaPlantCard);
|
||||
</script>
|
||||
@ -1,11 +1,17 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../bower_components/iron-icon/iron-icon.html'>
|
||||
<link rel='import' href='../components/ha-card.html'>
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../util/hass-mixins.html'>
|
||||
import '../components/ha-card.js';
|
||||
import '../util/hass-mixins.js';
|
||||
|
||||
<dom-module id='ha-weather-card'>
|
||||
<template>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaWeatherCard extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
cursor: pointer;
|
||||
@ -80,8 +86,8 @@
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
</style>
|
||||
<ha-card header='[[stateObj.attributes.friendly_name]]'>
|
||||
<div class='content'>
|
||||
<ha-card header="[[stateObj.attributes.friendly_name]]">
|
||||
<div class="content">
|
||||
<div class="now">
|
||||
<div class="main">
|
||||
<template is="dom-if" if="[[showWeatherIcon(stateObj.state)]]">
|
||||
@ -117,7 +123,7 @@
|
||||
</div>
|
||||
<template is="dom-if" if="[[forecast]]">
|
||||
<div class="forecast">
|
||||
<template is='dom-repeat' items='[[forecast]]'>
|
||||
<template is="dom-repeat" items="[[forecast]]">
|
||||
<div>
|
||||
<div class="weekday">[[computeDateTime(item.datetime)]]</div>
|
||||
<template is="dom-if" if="[[item.condition]]">
|
||||
@ -135,15 +141,9 @@
|
||||
</template>
|
||||
</div>
|
||||
</ha-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaWeatherCard extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(Polymer.Element)) {
|
||||
static get is() { return 'ha-weather-card'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -238,4 +238,3 @@ class HaWeatherCard extends
|
||||
}
|
||||
}
|
||||
customElements.define(HaWeatherCard.is, HaWeatherCard);
|
||||
</script>
|
||||
@ -1,20 +1,16 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="./ha-progress-button.html">
|
||||
<link rel='import' href='../../util/hass-mixins.html'>
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id='ha-call-api-button'>
|
||||
<template>
|
||||
<ha-progress-button
|
||||
id='progress'
|
||||
progress='[[progress]]'
|
||||
on-click='buttonTapped'
|
||||
disabled='[[disabled]]'
|
||||
><slot></slot></ha-progress-button>
|
||||
</template>
|
||||
</dom-module>
|
||||
import '../../util/hass-mixins.js';
|
||||
import './ha-progress-button.js';
|
||||
|
||||
class HaCallApiButton extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<ha-progress-button id="progress" progress="[[progress]]" on-click="buttonTapped" disabled="[[disabled]]"><slot></slot></ha-progress-button>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaCallApiButton extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-call-api-button'; }
|
||||
|
||||
static get properties() {
|
||||
@ -71,4 +67,3 @@ class HaCallApiButton extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HaCallApiButton.is, HaCallApiButton);
|
||||
</script>
|
||||
@ -1,20 +1,16 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="./ha-progress-button.html">
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../util/hass-mixins.html'>
|
||||
import '../../util/hass-mixins.js';
|
||||
import './ha-progress-button.js';
|
||||
|
||||
<dom-module id='ha-call-service-button'>
|
||||
<template>
|
||||
<ha-progress-button
|
||||
id='progress'
|
||||
progress='[[progress]]'
|
||||
on-click='buttonTapped'
|
||||
><slot></slot></ha-progress-button>
|
||||
</template>
|
||||
</dom-module>
|
||||
class HaCallServiceButton extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<ha-progress-button id="progress" progress="[[progress]]" on-click="buttonTapped"><slot></slot></ha-progress-button>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaCallServiceButton extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-call-service-button'; }
|
||||
|
||||
static get properties() {
|
||||
@ -68,4 +64,3 @@ class HaCallServiceButton extends window.hassMixins.EventsMixin(Polymer.Element)
|
||||
}
|
||||
|
||||
customElements.define(HaCallServiceButton.is, HaCallServiceButton);
|
||||
</script>
|
||||
@ -1,9 +1,11 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-spinner/paper-spinner.html">
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-spinner/paper-spinner.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id='ha-progress-button'>
|
||||
<template>
|
||||
class HaProgressButton extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
.container {
|
||||
position: relative;
|
||||
@ -40,25 +42,19 @@
|
||||
bottom: 0;
|
||||
}
|
||||
</style>
|
||||
<div class='container' id='container'>
|
||||
<paper-button
|
||||
id='button'
|
||||
disabled='[[computeDisabled(disabled, progress)]]'
|
||||
on-click='buttonTapped'
|
||||
>
|
||||
<div class="container" id="container">
|
||||
<paper-button id="button" disabled="[[computeDisabled(disabled, progress)]]" on-click="buttonTapped">
|
||||
<slot></slot>
|
||||
</paper-button>
|
||||
<template is='dom-if' if='[[progress]]'>
|
||||
<div class='progress'>
|
||||
<paper-spinner active></paper-spinner>
|
||||
<template is="dom-if" if="[[progress]]">
|
||||
<div class="progress">
|
||||
<paper-spinner active=""></paper-spinner>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaProgressButton extends Polymer.Element {
|
||||
static get is() { return 'ha-progress-button'; }
|
||||
|
||||
static get properties() {
|
||||
@ -110,4 +106,3 @@ class HaProgressButton extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HaProgressButton.is, HaProgressButton);
|
||||
</script>
|
||||
@ -1,15 +1,16 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/iron-icon/iron-icon.html">
|
||||
import domainIcon from '../../js/common/entity/domain_icon.js';
|
||||
|
||||
<dom-module id="domain-icon">
|
||||
<template>
|
||||
class DomainIcon extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<iron-icon icon="[[computeIcon(domain, state)]]"></iron-icon>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class DomainIcon extends Polymer.Element {
|
||||
static get is() { return 'domain-icon'; }
|
||||
|
||||
static get properties() {
|
||||
@ -27,9 +28,8 @@ class DomainIcon extends Polymer.Element {
|
||||
}
|
||||
|
||||
computeIcon(domain, state) {
|
||||
return window.hassUtil.domainIcon(domain, state);
|
||||
return domainIcon(domain, state);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(DomainIcon.is, DomainIcon);
|
||||
</script>
|
||||
@ -1,542 +0,0 @@
|
||||
<link rel='import' href='../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href="../../../bower_components/iron-resizable-behavior/iron-resizable-behavior.html">
|
||||
<link rel='import' href='../../../bower_components/paper-icon-button/paper-icon-button.html'>
|
||||
|
||||
<dom-module id="ha-chart-base">
|
||||
<template>
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
.chartHeader {
|
||||
padding: 6px 0 0 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.chartHeader > div {
|
||||
vertical-align: top;
|
||||
padding: 0 8px;
|
||||
}
|
||||
.chartHeader > div.chartTitle {
|
||||
padding-top: 8px;
|
||||
flex: 0 0 0;
|
||||
max-width: 30%;
|
||||
}
|
||||
.chartHeader > div.chartLegend {
|
||||
flex: 1 1;
|
||||
min-width: 70%;
|
||||
}
|
||||
:root{
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
.chartTooltip {
|
||||
font-size: 90%;
|
||||
opacity: 1;
|
||||
position: absolute;
|
||||
background: rgba(80, 80, 80, .9);
|
||||
color: white;
|
||||
border-radius: 3px;
|
||||
pointer-events: none;
|
||||
transform: translate(-50%, 12px);
|
||||
z-index: 1000;
|
||||
width: 200px;
|
||||
transition: opacity 0.15s ease-in-out;
|
||||
}
|
||||
.chartLegend ul,
|
||||
.chartTooltip ul {
|
||||
display: inline-block;
|
||||
padding: 0 0px;
|
||||
margin: 5px 0 0 0;
|
||||
width: 100%
|
||||
}
|
||||
.chartTooltip li {
|
||||
display: block;
|
||||
white-space: pre-line;
|
||||
}
|
||||
.chartTooltip .title {
|
||||
text-align: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
.chartLegend li {
|
||||
display: inline-block;
|
||||
padding: 0 6px;
|
||||
max-width: 49%;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.chartLegend li:nth-child(odd):last-of-type {
|
||||
/* Make last item take full width if it is odd-numbered. */
|
||||
max-width: 100%;
|
||||
}
|
||||
.chartLegend li[data-hidden] {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
.chartLegend em,
|
||||
.chartTooltip em {
|
||||
border-radius: 5px;
|
||||
display: inline-block;
|
||||
height: 10px;
|
||||
margin-right: 4px;
|
||||
width: 10px;
|
||||
}
|
||||
paper-icon-button {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
</style>
|
||||
<template is="dom-if" if="[[unit]]">
|
||||
<div class="chartHeader">
|
||||
<div class="chartTitle">[[unit]]</div>
|
||||
<div class="chartLegend">
|
||||
<ul>
|
||||
<template is="dom-repeat" items="[[metas]]">
|
||||
<li on-click="_legendClick" data-hidden$="[[item.hidden]]">
|
||||
<em style$="background-color:[[item.bgColor]]"></em>
|
||||
[[item.label]]
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div id="chartTarget" style="height:40px; width:100%">
|
||||
<canvas id="chartCanvas"></canvas>
|
||||
<div class$="chartTooltip [[tooltip.yAlign]]"
|
||||
style$="opacity:[[tooltip.opacity]]; top:[[tooltip.top]]; left:[[tooltip.left]]; padding:[[tooltip.yPadding]]px [[tooltip.xPadding]]px">
|
||||
<div class="title">[[tooltip.title]]</div>
|
||||
<div>
|
||||
<ul>
|
||||
<template is="dom-repeat" items="[[tooltip.lines]]">
|
||||
<li><em style$="background-color:[[item.bgColor]]"></em>[[item.text]]</li>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
<script>
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
/* global Chart moment Color */
|
||||
{
|
||||
let SCRIPT_LOADED = false;
|
||||
|
||||
class HaChartBase extends Polymer.mixinBehaviors([
|
||||
Polymer.IronResizableBehavior
|
||||
], Polymer.Element) {
|
||||
get chart() {
|
||||
return this._chart;
|
||||
}
|
||||
static get is() { return 'ha-chart-base'; }
|
||||
static get properties() {
|
||||
return {
|
||||
data: Object,
|
||||
identifier: String,
|
||||
rendered: {
|
||||
type: Boolean,
|
||||
notify: true,
|
||||
value: false,
|
||||
readOnly: true,
|
||||
},
|
||||
metas: {
|
||||
type: Array,
|
||||
value: () => [],
|
||||
},
|
||||
tooltip: {
|
||||
type: Object,
|
||||
value: () => ({
|
||||
opacity: '0',
|
||||
left: '0',
|
||||
top: '0',
|
||||
xPadding: '5',
|
||||
yPadding: '3'
|
||||
})
|
||||
},
|
||||
unit: Object,
|
||||
};
|
||||
}
|
||||
|
||||
static get observers() {
|
||||
return ['onPropsChange(data)'];
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this._isAttached = true;
|
||||
this.onPropsChange();
|
||||
this._resizeListener = () => {
|
||||
this._debouncer = Polymer.Debouncer.debounce(
|
||||
this._debouncer,
|
||||
Polymer.Async.timeOut.after(10),
|
||||
() => {
|
||||
if (this._isAttached) {
|
||||
this.resizeChart();
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
if (typeof ResizeObserver === 'function') {
|
||||
this.resizeObserver = new ResizeObserver((entries) => {
|
||||
entries.forEach(() => {
|
||||
this._resizeListener();
|
||||
});
|
||||
});
|
||||
this.resizeObserver.observe(this.$.chartTarget);
|
||||
} else {
|
||||
this.addEventListener('iron-resize', this._resizeListener);
|
||||
}
|
||||
|
||||
if (!SCRIPT_LOADED) {
|
||||
Polymer.importHref(
|
||||
window.CHART_SCRIPT,
|
||||
() => {
|
||||
SCRIPT_LOADED = true;
|
||||
this.onPropsChange();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this._isAttached = false;
|
||||
if (this.resizeObserver) {
|
||||
this.resizeObserver.unobserve(this.$.chartTarget);
|
||||
}
|
||||
|
||||
this.removeEventListener('iron-resize', this._resizeListener);
|
||||
|
||||
if (this._resizeTimer !== undefined) {
|
||||
clearInterval(this._resizeTimer);
|
||||
this._resizeTimer = undefined;
|
||||
}
|
||||
}
|
||||
onPropsChange() {
|
||||
if (!this._isAttached || !SCRIPT_LOADED || !this.data) {
|
||||
return;
|
||||
}
|
||||
this.drawChart();
|
||||
}
|
||||
_customTooltips(tooltip) {
|
||||
// Hide if no tooltip
|
||||
if (tooltip.opacity === 0) {
|
||||
this.set(['tooltip', 'opacity'], 0);
|
||||
return;
|
||||
}
|
||||
// Set caret Position
|
||||
if (tooltip.yAlign) {
|
||||
this.set(['tooltip', 'yAlign'], tooltip.yAlign);
|
||||
} else {
|
||||
this.set(['tooltip', 'yAlign'], 'no-transform');
|
||||
}
|
||||
|
||||
const title = tooltip.title ? tooltip.title[0] || '' : '';
|
||||
this.set(['tooltip', 'title'], title);
|
||||
|
||||
const bodyLines = tooltip.body.map(n => n.lines);
|
||||
|
||||
// Set Text
|
||||
if (tooltip.body) {
|
||||
this.set(['tooltip', 'lines'], bodyLines.map((body, i) => {
|
||||
const colors = tooltip.labelColors[i];
|
||||
return {
|
||||
color: colors.borderColor,
|
||||
bgColor: colors.backgroundColor,
|
||||
text: body.join('\n'),
|
||||
};
|
||||
}));
|
||||
}
|
||||
const parentWidth = this.$.chartTarget.clientWidth;
|
||||
let positionX = tooltip.caretX;
|
||||
const positionY = this._chart.canvas.offsetTop + tooltip.caretY;
|
||||
if (tooltip.caretX + 100 > parentWidth) {
|
||||
positionX = parentWidth - 100;
|
||||
} else if (tooltip.caretX < 100) {
|
||||
positionX = 100;
|
||||
}
|
||||
positionX += this._chart.canvas.offsetLeft;
|
||||
// Display, position, and set styles for font
|
||||
this.tooltip = Object.assign({}, this.tooltip, {
|
||||
opacity: 1,
|
||||
left: `${positionX}px`,
|
||||
top: `${positionY}px`,
|
||||
});
|
||||
}
|
||||
|
||||
_legendClick(event) {
|
||||
event = event || window.event;
|
||||
event.stopPropagation();
|
||||
let target = event.target || event.srcElement;
|
||||
while (target.nodeName !== 'LI') { // user clicked child, find parent LI
|
||||
target = target.parentElement;
|
||||
}
|
||||
const index = event.model.itemsIndex;
|
||||
|
||||
const meta = this._chart.getDatasetMeta(index);
|
||||
meta.hidden = meta.hidden === null ? !this._chart.data.datasets[index].hidden : null;
|
||||
this.set(['metas', index, 'hidden'], this._chart.isDatasetVisible(index) ? null : 'hidden');
|
||||
this._chart.update();
|
||||
}
|
||||
_drawLegend() {
|
||||
const chart = this._chart;
|
||||
// New data for old graph. Keep metadata.
|
||||
const preserveVisibility =
|
||||
this._oldIdentifier && this.identifier === this._oldIdentifier;
|
||||
this._oldIdentifier = this.identifier;
|
||||
this.set('metas', this._chart.data.datasets.map((x, i) => ({
|
||||
label: x.label,
|
||||
color: x.color,
|
||||
bgColor: x.backgroundColor,
|
||||
hidden: preserveVisibility && i < this.metas.length ?
|
||||
this.metas[i].hidden : !chart.isDatasetVisible(i),
|
||||
})));
|
||||
let updateNeeded = false;
|
||||
if (preserveVisibility) {
|
||||
for (let i = 0; i < this.metas.length; i++) {
|
||||
const meta = chart.getDatasetMeta(i);
|
||||
if (!!meta.hidden !== !!this.metas[i].hidden) updateNeeded = true;
|
||||
meta.hidden = this.metas[i].hidden ? true : null;
|
||||
}
|
||||
}
|
||||
if (updateNeeded) {
|
||||
chart.update();
|
||||
}
|
||||
this.unit = this.data.unit;
|
||||
}
|
||||
_formatTickValue(value, index, values) {
|
||||
if (values.length === 0) {
|
||||
return value;
|
||||
}
|
||||
const date = new Date(values[index].value);
|
||||
return window.hassUtil.formatTime(date);
|
||||
}
|
||||
drawChart() {
|
||||
const data = this.data.data;
|
||||
const ctx = this.$.chartCanvas;
|
||||
|
||||
if ((!data.datasets || !data.datasets.length) && !this._chart) {
|
||||
return;
|
||||
}
|
||||
if (this.data.type !== 'timeline' && data.datasets.length > 0) {
|
||||
const cnt = data.datasets.length;
|
||||
const colors = this.constructor.getColorList(cnt);
|
||||
for (let loopI = 0; loopI < cnt; loopI++) {
|
||||
data.datasets[loopI].borderColor = colors[loopI].rgbString();
|
||||
data.datasets[loopI].backgroundColor = colors[loopI].alpha(0.6).rgbaString();
|
||||
}
|
||||
}
|
||||
|
||||
if (this._chart) {
|
||||
this._customTooltips({ opacity: 0 });
|
||||
this._chart.data = data;
|
||||
this._chart.update({ duration: 0 });
|
||||
if (this.isTimeline !== true && this.data.legend === true) {
|
||||
this._drawLegend();
|
||||
}
|
||||
this.resizeChart();
|
||||
} else {
|
||||
if (!data.datasets) {
|
||||
return;
|
||||
}
|
||||
this._customTooltips({ opacity: 0 });
|
||||
const plugins = [
|
||||
{ afterRender: () => this._setRendered(true) }
|
||||
];
|
||||
let options = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
animation: {
|
||||
duration: 0,
|
||||
},
|
||||
hover: {
|
||||
animationDuration: 0,
|
||||
},
|
||||
responsiveAnimationDuration: 0,
|
||||
tooltips: {
|
||||
enabled: false,
|
||||
custom: this._customTooltips.bind(this),
|
||||
},
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
line: {
|
||||
spanGaps: true,
|
||||
},
|
||||
elements: {
|
||||
font: "12px 'Roboto', 'sans-serif'",
|
||||
},
|
||||
ticks: {
|
||||
fontFamily: "'Roboto', 'sans-serif'",
|
||||
}
|
||||
};
|
||||
options = Chart.helpers.merge(options, this.data.options);
|
||||
options.scales.xAxes[0].ticks.callback = this._formatTickValue;
|
||||
if (this.data.type === 'timeline') {
|
||||
this.set('isTimeline', true);
|
||||
if (this.data.colors !== undefined) {
|
||||
this._colorFunc = this.constructor.getColorGenerator(
|
||||
this.data.colors.staticColors,
|
||||
this.data.colors.staticColorIndex
|
||||
);
|
||||
}
|
||||
if (this._colorFunc !== undefined) {
|
||||
options.colorFunction = this._colorFunc;
|
||||
}
|
||||
if (data.datasets.length === 1) {
|
||||
if (options.scales.yAxes[0].ticks) {
|
||||
options.scales.yAxes[0].ticks.display = false;
|
||||
} else {
|
||||
options.scales.yAxes[0].ticks = { display: false };
|
||||
}
|
||||
}
|
||||
}
|
||||
this.$.chartTarget.style.height = '160px';
|
||||
this.$.chartTarget.height = '160px';
|
||||
const chartData = {
|
||||
type: this.data.type,
|
||||
data: this.data.data,
|
||||
options: options,
|
||||
plugins: plugins,
|
||||
};
|
||||
// Async resize after dom update
|
||||
this._chart = new Chart(ctx, chartData);
|
||||
if (this.isTimeline !== true && this.data.legend === true) {
|
||||
this._drawLegend();
|
||||
}
|
||||
this.resizeChart();
|
||||
}
|
||||
}
|
||||
|
||||
resizeChart() {
|
||||
if (!this._chart) return;
|
||||
// Chart not ready
|
||||
if (this.$.chartTarget.clientWidth === 0) {
|
||||
if (this._resizeTimer === undefined) {
|
||||
this._resizeTimer = setInterval(this.resizeChart.bind(this), 10);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
clearInterval(this._resizeTimer);
|
||||
this._resizeTimer = undefined;
|
||||
|
||||
this._resizeChart();
|
||||
}
|
||||
|
||||
_resizeChart() {
|
||||
const chartTarget = this.$.chartTarget;
|
||||
|
||||
const options = this.data;
|
||||
const data = options.data;
|
||||
|
||||
if (data.datasets.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.isTimeline) {
|
||||
this._chart.resize();
|
||||
return;
|
||||
}
|
||||
|
||||
// Recalculate chart height for Timeline chart
|
||||
var axis = this._chart.boxes.filter(x => x.position === 'bottom')[0];
|
||||
if (axis && axis.height > 0) {
|
||||
this._axisHeight = axis.height;
|
||||
}
|
||||
if (!this._axisHeight) {
|
||||
chartTarget.style.height = '100px';
|
||||
chartTarget.height = '100px';
|
||||
this._chart.resize();
|
||||
axis = this._chart.boxes.filter(x => x.position === 'bottom')[0];
|
||||
if (axis && axis.height > 0) {
|
||||
this._axisHeight = axis.height;
|
||||
}
|
||||
}
|
||||
if (this._axisHeight) {
|
||||
const cnt = data.datasets.length;
|
||||
const targetHeight = ((30 * cnt) + this._axisHeight) + 'px';
|
||||
if (chartTarget.style.height !== targetHeight) {
|
||||
chartTarget.style.height = targetHeight;
|
||||
chartTarget.height = targetHeight;
|
||||
}
|
||||
this._chart.resize();
|
||||
}
|
||||
}
|
||||
|
||||
// Get HSL distributed color list
|
||||
static getColorList(count) {
|
||||
let processL = false;
|
||||
if (count > 10) {
|
||||
processL = true;
|
||||
count = Math.ceil(count / 2);
|
||||
}
|
||||
const h1 = 360 / count;
|
||||
const result = [];
|
||||
for (let loopI = 0; loopI < count; loopI++) {
|
||||
result[loopI] = Color().hsl(h1 * loopI, 80, 38);
|
||||
if (processL) {
|
||||
result[loopI + count] = Color().hsl(h1 * loopI, 80, 62);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static getColorGenerator(staticColors, startIndex) {
|
||||
// Known colors for static data,
|
||||
// should add for very common state string manually.
|
||||
// Palette modified from http://google.github.io/palette.js/ mpn65, Apache 2.0
|
||||
const palette = [
|
||||
'ff0029', '66a61e', '377eb8', '984ea3', '00d2d5', 'ff7f00', 'af8d00',
|
||||
'7f80cd', 'b3e900', 'c42e60', 'a65628', 'f781bf', '8dd3c7', 'bebada',
|
||||
'fb8072', '80b1d3', 'fdb462', 'fccde5', 'bc80bd', 'ffed6f', 'c4eaff',
|
||||
'cf8c00', '1b9e77', 'd95f02', 'e7298a', 'e6ab02', 'a6761d', '0097ff',
|
||||
'00d067', 'f43600', '4ba93b', '5779bb', '927acc', '97ee3f', 'bf3947',
|
||||
'9f5b00', 'f48758', '8caed6', 'f2b94f', 'eff26e', 'e43872', 'd9b100',
|
||||
'9d7a00', '698cff', 'd9d9d9', '00d27e', 'd06800', '009f82', 'c49200',
|
||||
'cbe8ff', 'fecddf', 'c27eb6', '8cd2ce', 'c4b8d9', 'f883b0', 'a49100',
|
||||
'f48800', '27d0df', 'a04a9b'];
|
||||
function getColorIndex(idx) {
|
||||
// Reuse the color if index too large.
|
||||
return Color('#' + palette[idx % palette.length]);
|
||||
}
|
||||
const colorDict = {};
|
||||
let colorIndex = 0;
|
||||
if (startIndex > 0) colorIndex = startIndex;
|
||||
if (staticColors) {
|
||||
Object.keys(staticColors).forEach((c) => {
|
||||
const c1 = staticColors[c];
|
||||
if (isFinite(c1)) {
|
||||
colorDict[c.toLowerCase()] = getColorIndex(c1);
|
||||
} else {
|
||||
colorDict[c.toLowerCase()] = Color(staticColors[c]);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Custom color assign
|
||||
function getColor(__, data) {
|
||||
let ret;
|
||||
const name = data[3];
|
||||
if (name === null) return Color().hsl(0, 40, 38);
|
||||
if (name === undefined) return Color().hsl(120, 40, 38);
|
||||
const name1 = name.toLowerCase();
|
||||
if (ret === undefined) {
|
||||
ret = colorDict[name1];
|
||||
}
|
||||
if (ret === undefined) {
|
||||
ret = getColorIndex(colorIndex);
|
||||
colorIndex++;
|
||||
colorDict[name1] = ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return getColor;
|
||||
}
|
||||
}
|
||||
customElements.define(HaChartBase.is, HaChartBase);
|
||||
}
|
||||
</script>
|
||||
540
src/components/entity/ha-chart-base.js
Normal file
540
src/components/entity/ha-chart-base.js
Normal file
@ -0,0 +1,540 @@
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
import { IronResizableBehavior } from '@polymer/iron-resizable-behavior/iron-resizable-behavior.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { Debouncer } from '@polymer/polymer/lib/utils/debounce.js';
|
||||
import { timeOut } from '@polymer/polymer/lib/utils/async.js';
|
||||
import { mixinBehaviors } from '@polymer/polymer/lib/legacy/class.js';
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
/* global Chart moment Color */
|
||||
|
||||
let scriptsLoaded = null;
|
||||
|
||||
class HaChartBase extends mixinBehaviors([
|
||||
IronResizableBehavior
|
||||
], PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
.chartHeader {
|
||||
padding: 6px 0 0 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.chartHeader > div {
|
||||
vertical-align: top;
|
||||
padding: 0 8px;
|
||||
}
|
||||
.chartHeader > div.chartTitle {
|
||||
padding-top: 8px;
|
||||
flex: 0 0 0;
|
||||
max-width: 30%;
|
||||
}
|
||||
.chartHeader > div.chartLegend {
|
||||
flex: 1 1;
|
||||
min-width: 70%;
|
||||
}
|
||||
:root{
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
.chartTooltip {
|
||||
font-size: 90%;
|
||||
opacity: 1;
|
||||
position: absolute;
|
||||
background: rgba(80, 80, 80, .9);
|
||||
color: white;
|
||||
border-radius: 3px;
|
||||
pointer-events: none;
|
||||
transform: translate(-50%, 12px);
|
||||
z-index: 1000;
|
||||
width: 200px;
|
||||
transition: opacity 0.15s ease-in-out;
|
||||
}
|
||||
.chartLegend ul,
|
||||
.chartTooltip ul {
|
||||
display: inline-block;
|
||||
padding: 0 0px;
|
||||
margin: 5px 0 0 0;
|
||||
width: 100%
|
||||
}
|
||||
.chartTooltip li {
|
||||
display: block;
|
||||
white-space: pre-line;
|
||||
}
|
||||
.chartTooltip .title {
|
||||
text-align: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
.chartLegend li {
|
||||
display: inline-block;
|
||||
padding: 0 6px;
|
||||
max-width: 49%;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.chartLegend li:nth-child(odd):last-of-type {
|
||||
/* Make last item take full width if it is odd-numbered. */
|
||||
max-width: 100%;
|
||||
}
|
||||
.chartLegend li[data-hidden] {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
.chartLegend em,
|
||||
.chartTooltip em {
|
||||
border-radius: 5px;
|
||||
display: inline-block;
|
||||
height: 10px;
|
||||
margin-right: 4px;
|
||||
width: 10px;
|
||||
}
|
||||
paper-icon-button {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
</style>
|
||||
<template is="dom-if" if="[[unit]]">
|
||||
<div class="chartHeader">
|
||||
<div class="chartTitle">[[unit]]</div>
|
||||
<div class="chartLegend">
|
||||
<ul>
|
||||
<template is="dom-repeat" items="[[metas]]">
|
||||
<li on-click="_legendClick" data-hidden\$="[[item.hidden]]">
|
||||
<em style\$="background-color:[[item.bgColor]]"></em>
|
||||
[[item.label]]
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div id="chartTarget" style="height:40px; width:100%">
|
||||
<canvas id="chartCanvas"></canvas>
|
||||
<div class\$="chartTooltip [[tooltip.yAlign]]" style\$="opacity:[[tooltip.opacity]]; top:[[tooltip.top]]; left:[[tooltip.left]]; padding:[[tooltip.yPadding]]px [[tooltip.xPadding]]px">
|
||||
<div class="title">[[tooltip.title]]</div>
|
||||
<div>
|
||||
<ul>
|
||||
<template is="dom-repeat" items="[[tooltip.lines]]">
|
||||
<li><em style\$="background-color:[[item.bgColor]]"></em>[[item.text]]</li>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
get chart() {
|
||||
return this._chart;
|
||||
}
|
||||
static get is() { return 'ha-chart-base'; }
|
||||
static get properties() {
|
||||
return {
|
||||
data: Object,
|
||||
identifier: String,
|
||||
rendered: {
|
||||
type: Boolean,
|
||||
notify: true,
|
||||
value: false,
|
||||
readOnly: true,
|
||||
},
|
||||
metas: {
|
||||
type: Array,
|
||||
value: () => [],
|
||||
},
|
||||
tooltip: {
|
||||
type: Object,
|
||||
value: () => ({
|
||||
opacity: '0',
|
||||
left: '0',
|
||||
top: '0',
|
||||
xPadding: '5',
|
||||
yPadding: '3'
|
||||
})
|
||||
},
|
||||
unit: Object,
|
||||
};
|
||||
}
|
||||
|
||||
static get observers() {
|
||||
return ['onPropsChange(data)'];
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this._isAttached = true;
|
||||
this.onPropsChange();
|
||||
this._resizeListener = () => {
|
||||
this._debouncer = Debouncer.debounce(
|
||||
this._debouncer,
|
||||
timeOut.after(10),
|
||||
() => {
|
||||
if (this._isAttached) {
|
||||
this.resizeChart();
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
if (typeof ResizeObserver === 'function') {
|
||||
this.resizeObserver = new ResizeObserver((entries) => {
|
||||
entries.forEach(() => {
|
||||
this._resizeListener();
|
||||
});
|
||||
});
|
||||
this.resizeObserver.observe(this.$.chartTarget);
|
||||
} else {
|
||||
this.addEventListener('iron-resize', this._resizeListener);
|
||||
}
|
||||
|
||||
if (scriptsLoaded === null) {
|
||||
scriptsLoaded = import(/* webpackChunkName: "load_chart" */ '../../resources/ha-chart-scripts.js');
|
||||
}
|
||||
scriptsLoaded.then((ChartModule) => {
|
||||
this.ChartClass = ChartModule.default;
|
||||
this.onPropsChange();
|
||||
});
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this._isAttached = false;
|
||||
if (this.resizeObserver) {
|
||||
this.resizeObserver.unobserve(this.$.chartTarget);
|
||||
}
|
||||
|
||||
this.removeEventListener('iron-resize', this._resizeListener);
|
||||
|
||||
if (this._resizeTimer !== undefined) {
|
||||
clearInterval(this._resizeTimer);
|
||||
this._resizeTimer = undefined;
|
||||
}
|
||||
}
|
||||
onPropsChange() {
|
||||
if (!this._isAttached || !this.ChartClass || !this.data) {
|
||||
return;
|
||||
}
|
||||
this.drawChart();
|
||||
}
|
||||
_customTooltips(tooltip) {
|
||||
// Hide if no tooltip
|
||||
if (tooltip.opacity === 0) {
|
||||
this.set(['tooltip', 'opacity'], 0);
|
||||
return;
|
||||
}
|
||||
// Set caret Position
|
||||
if (tooltip.yAlign) {
|
||||
this.set(['tooltip', 'yAlign'], tooltip.yAlign);
|
||||
} else {
|
||||
this.set(['tooltip', 'yAlign'], 'no-transform');
|
||||
}
|
||||
|
||||
const title = tooltip.title ? tooltip.title[0] || '' : '';
|
||||
this.set(['tooltip', 'title'], title);
|
||||
|
||||
const bodyLines = tooltip.body.map(n => n.lines);
|
||||
|
||||
// Set Text
|
||||
if (tooltip.body) {
|
||||
this.set(['tooltip', 'lines'], bodyLines.map((body, i) => {
|
||||
const colors = tooltip.labelColors[i];
|
||||
return {
|
||||
color: colors.borderColor,
|
||||
bgColor: colors.backgroundColor,
|
||||
text: body.join('\n'),
|
||||
};
|
||||
}));
|
||||
}
|
||||
const parentWidth = this.$.chartTarget.clientWidth;
|
||||
let positionX = tooltip.caretX;
|
||||
const positionY = this._chart.canvas.offsetTop + tooltip.caretY;
|
||||
if (tooltip.caretX + 100 > parentWidth) {
|
||||
positionX = parentWidth - 100;
|
||||
} else if (tooltip.caretX < 100) {
|
||||
positionX = 100;
|
||||
}
|
||||
positionX += this._chart.canvas.offsetLeft;
|
||||
// Display, position, and set styles for font
|
||||
this.tooltip = Object.assign({}, this.tooltip, {
|
||||
opacity: 1,
|
||||
left: `${positionX}px`,
|
||||
top: `${positionY}px`,
|
||||
});
|
||||
}
|
||||
|
||||
_legendClick(event) {
|
||||
event = event || window.event;
|
||||
event.stopPropagation();
|
||||
let target = event.target || event.srcElement;
|
||||
while (target.nodeName !== 'LI') { // user clicked child, find parent LI
|
||||
target = target.parentElement;
|
||||
}
|
||||
const index = event.model.itemsIndex;
|
||||
|
||||
const meta = this._chart.getDatasetMeta(index);
|
||||
meta.hidden = meta.hidden === null ? !this._chart.data.datasets[index].hidden : null;
|
||||
this.set(['metas', index, 'hidden'], this._chart.isDatasetVisible(index) ? null : 'hidden');
|
||||
this._chart.update();
|
||||
}
|
||||
_drawLegend() {
|
||||
const chart = this._chart;
|
||||
// New data for old graph. Keep metadata.
|
||||
const preserveVisibility =
|
||||
this._oldIdentifier && this.identifier === this._oldIdentifier;
|
||||
this._oldIdentifier = this.identifier;
|
||||
this.set('metas', this._chart.data.datasets.map((x, i) => ({
|
||||
label: x.label,
|
||||
color: x.color,
|
||||
bgColor: x.backgroundColor,
|
||||
hidden: preserveVisibility && i < this.metas.length ?
|
||||
this.metas[i].hidden : !chart.isDatasetVisible(i),
|
||||
})));
|
||||
let updateNeeded = false;
|
||||
if (preserveVisibility) {
|
||||
for (let i = 0; i < this.metas.length; i++) {
|
||||
const meta = chart.getDatasetMeta(i);
|
||||
if (!!meta.hidden !== !!this.metas[i].hidden) updateNeeded = true;
|
||||
meta.hidden = this.metas[i].hidden ? true : null;
|
||||
}
|
||||
}
|
||||
if (updateNeeded) {
|
||||
chart.update();
|
||||
}
|
||||
this.unit = this.data.unit;
|
||||
}
|
||||
_formatTickValue(value, index, values) {
|
||||
if (values.length === 0) {
|
||||
return value;
|
||||
}
|
||||
const date = new Date(values[index].value);
|
||||
return window.hassUtil.formatTime(date);
|
||||
}
|
||||
drawChart() {
|
||||
const data = this.data.data;
|
||||
const ctx = this.$.chartCanvas;
|
||||
|
||||
if ((!data.datasets || !data.datasets.length) && !this._chart) {
|
||||
return;
|
||||
}
|
||||
if (this.data.type !== 'timeline' && data.datasets.length > 0) {
|
||||
const cnt = data.datasets.length;
|
||||
const colors = this.constructor.getColorList(cnt);
|
||||
for (let loopI = 0; loopI < cnt; loopI++) {
|
||||
data.datasets[loopI].borderColor = colors[loopI].rgbString();
|
||||
data.datasets[loopI].backgroundColor = colors[loopI].alpha(0.6).rgbaString();
|
||||
}
|
||||
}
|
||||
|
||||
if (this._chart) {
|
||||
this._customTooltips({ opacity: 0 });
|
||||
this._chart.data = data;
|
||||
this._chart.update({ duration: 0 });
|
||||
if (this.isTimeline !== true && this.data.legend === true) {
|
||||
this._drawLegend();
|
||||
}
|
||||
this.resizeChart();
|
||||
} else {
|
||||
if (!data.datasets) {
|
||||
return;
|
||||
}
|
||||
this._customTooltips({ opacity: 0 });
|
||||
const plugins = [
|
||||
{ afterRender: () => this._setRendered(true) }
|
||||
];
|
||||
let options = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
animation: {
|
||||
duration: 0,
|
||||
},
|
||||
hover: {
|
||||
animationDuration: 0,
|
||||
},
|
||||
responsiveAnimationDuration: 0,
|
||||
tooltips: {
|
||||
enabled: false,
|
||||
custom: this._customTooltips.bind(this),
|
||||
},
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
line: {
|
||||
spanGaps: true,
|
||||
},
|
||||
elements: {
|
||||
font: "12px 'Roboto', 'sans-serif'",
|
||||
},
|
||||
ticks: {
|
||||
fontFamily: "'Roboto', 'sans-serif'",
|
||||
}
|
||||
};
|
||||
options = Chart.helpers.merge(options, this.data.options);
|
||||
options.scales.xAxes[0].ticks.callback = this._formatTickValue;
|
||||
if (this.data.type === 'timeline') {
|
||||
this.set('isTimeline', true);
|
||||
if (this.data.colors !== undefined) {
|
||||
this._colorFunc = this.constructor.getColorGenerator(
|
||||
this.data.colors.staticColors,
|
||||
this.data.colors.staticColorIndex
|
||||
);
|
||||
}
|
||||
if (this._colorFunc !== undefined) {
|
||||
options.colorFunction = this._colorFunc;
|
||||
}
|
||||
if (data.datasets.length === 1) {
|
||||
if (options.scales.yAxes[0].ticks) {
|
||||
options.scales.yAxes[0].ticks.display = false;
|
||||
} else {
|
||||
options.scales.yAxes[0].ticks = { display: false };
|
||||
}
|
||||
}
|
||||
}
|
||||
this.$.chartTarget.style.height = '160px';
|
||||
this.$.chartTarget.height = '160px';
|
||||
const chartData = {
|
||||
type: this.data.type,
|
||||
data: this.data.data,
|
||||
options: options,
|
||||
plugins: plugins,
|
||||
};
|
||||
// Async resize after dom update
|
||||
this._chart = new this.ChartClass(ctx, chartData);
|
||||
if (this.isTimeline !== true && this.data.legend === true) {
|
||||
this._drawLegend();
|
||||
}
|
||||
this.resizeChart();
|
||||
}
|
||||
}
|
||||
|
||||
resizeChart() {
|
||||
if (!this._chart) return;
|
||||
// Chart not ready
|
||||
if (this.$.chartTarget.clientWidth === 0) {
|
||||
if (this._resizeTimer === undefined) {
|
||||
this._resizeTimer = setInterval(this.resizeChart.bind(this), 10);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
clearInterval(this._resizeTimer);
|
||||
this._resizeTimer = undefined;
|
||||
|
||||
this._resizeChart();
|
||||
}
|
||||
|
||||
_resizeChart() {
|
||||
const chartTarget = this.$.chartTarget;
|
||||
|
||||
const options = this.data;
|
||||
const data = options.data;
|
||||
|
||||
if (data.datasets.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.isTimeline) {
|
||||
this._chart.resize();
|
||||
return;
|
||||
}
|
||||
|
||||
// Recalculate chart height for Timeline chart
|
||||
var axis = this._chart.boxes.filter(x => x.position === 'bottom')[0];
|
||||
if (axis && axis.height > 0) {
|
||||
this._axisHeight = axis.height;
|
||||
}
|
||||
if (!this._axisHeight) {
|
||||
chartTarget.style.height = '100px';
|
||||
chartTarget.height = '100px';
|
||||
this._chart.resize();
|
||||
axis = this._chart.boxes.filter(x => x.position === 'bottom')[0];
|
||||
if (axis && axis.height > 0) {
|
||||
this._axisHeight = axis.height;
|
||||
}
|
||||
}
|
||||
if (this._axisHeight) {
|
||||
const cnt = data.datasets.length;
|
||||
const targetHeight = ((30 * cnt) + this._axisHeight) + 'px';
|
||||
if (chartTarget.style.height !== targetHeight) {
|
||||
chartTarget.style.height = targetHeight;
|
||||
chartTarget.height = targetHeight;
|
||||
}
|
||||
this._chart.resize();
|
||||
}
|
||||
}
|
||||
|
||||
// Get HSL distributed color list
|
||||
static getColorList(count) {
|
||||
let processL = false;
|
||||
if (count > 10) {
|
||||
processL = true;
|
||||
count = Math.ceil(count / 2);
|
||||
}
|
||||
const h1 = 360 / count;
|
||||
const result = [];
|
||||
for (let loopI = 0; loopI < count; loopI++) {
|
||||
result[loopI] = Color().hsl(h1 * loopI, 80, 38);
|
||||
if (processL) {
|
||||
result[loopI + count] = Color().hsl(h1 * loopI, 80, 62);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static getColorGenerator(staticColors, startIndex) {
|
||||
// Known colors for static data,
|
||||
// should add for very common state string manually.
|
||||
// Palette modified from http://google.github.io/palette.js/ mpn65, Apache 2.0
|
||||
const palette = [
|
||||
'ff0029', '66a61e', '377eb8', '984ea3', '00d2d5', 'ff7f00', 'af8d00',
|
||||
'7f80cd', 'b3e900', 'c42e60', 'a65628', 'f781bf', '8dd3c7', 'bebada',
|
||||
'fb8072', '80b1d3', 'fdb462', 'fccde5', 'bc80bd', 'ffed6f', 'c4eaff',
|
||||
'cf8c00', '1b9e77', 'd95f02', 'e7298a', 'e6ab02', 'a6761d', '0097ff',
|
||||
'00d067', 'f43600', '4ba93b', '5779bb', '927acc', '97ee3f', 'bf3947',
|
||||
'9f5b00', 'f48758', '8caed6', 'f2b94f', 'eff26e', 'e43872', 'd9b100',
|
||||
'9d7a00', '698cff', 'd9d9d9', '00d27e', 'd06800', '009f82', 'c49200',
|
||||
'cbe8ff', 'fecddf', 'c27eb6', '8cd2ce', 'c4b8d9', 'f883b0', 'a49100',
|
||||
'f48800', '27d0df', 'a04a9b'];
|
||||
function getColorIndex(idx) {
|
||||
// Reuse the color if index too large.
|
||||
return Color('#' + palette[idx % palette.length]);
|
||||
}
|
||||
const colorDict = {};
|
||||
let colorIndex = 0;
|
||||
if (startIndex > 0) colorIndex = startIndex;
|
||||
if (staticColors) {
|
||||
Object.keys(staticColors).forEach((c) => {
|
||||
const c1 = staticColors[c];
|
||||
if (isFinite(c1)) {
|
||||
colorDict[c.toLowerCase()] = getColorIndex(c1);
|
||||
} else {
|
||||
colorDict[c.toLowerCase()] = Color(staticColors[c]);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Custom color assign
|
||||
function getColor(__, data) {
|
||||
let ret;
|
||||
const name = data[3];
|
||||
if (name === null) return Color().hsl(0, 40, 38);
|
||||
if (name === undefined) return Color().hsl(120, 40, 38);
|
||||
const name1 = name.toLowerCase();
|
||||
if (ret === undefined) {
|
||||
ret = colorDict[name1];
|
||||
}
|
||||
if (ret === undefined) {
|
||||
ret = getColorIndex(colorIndex);
|
||||
colorIndex++;
|
||||
colorDict[name1] = ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return getColor;
|
||||
}
|
||||
}
|
||||
customElements.define(HaChartBase.is, HaChartBase);
|
||||
@ -1,16 +1,20 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/vaadin-combo-box/vaadin-combo-box-light.html">
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-icon-item.html">
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item-body.html">
|
||||
<link rel="import" href="../../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-input/paper-input.html">
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import '@polymer/paper-item/paper-icon-item.js';
|
||||
import '@polymer/paper-item/paper-item-body.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
import '@vaadin/vaadin-combo-box/vaadin-combo-box-light.js';
|
||||
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
import '../../util/hass-mixins.js';
|
||||
import './state-badge.js';
|
||||
|
||||
<link rel="import" href="./state-badge.html">
|
||||
|
||||
<dom-module id="ha-entity-picker">
|
||||
<template>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaEntityPicker extends window.hassMixins.LocalizeMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
paper-input > paper-icon-button {
|
||||
width: 24px;
|
||||
@ -22,34 +26,10 @@
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<vaadin-combo-box-light
|
||||
items='[[_states]]'
|
||||
item-value-path='entity_id'
|
||||
item-label-path='entity_id'
|
||||
value='{{value}}'
|
||||
opened='{{opened}}'
|
||||
allow-custom-value='[[allowCustomEntity]]'
|
||||
>
|
||||
<paper-input
|
||||
autofocus="[[autofocus]]"
|
||||
label="[[_computeLabel(label, localize)]]"
|
||||
class="input"
|
||||
value='[[value]]'
|
||||
disabled='[[disabled]]'
|
||||
>
|
||||
<paper-icon-button
|
||||
slot="suffix"
|
||||
class="clear-button"
|
||||
icon="mdi:close"
|
||||
no-ripple
|
||||
hidden$='[[!value]]'
|
||||
>Clear</paper-icon-button>
|
||||
<paper-icon-button
|
||||
slot="suffix"
|
||||
class="toggle-button"
|
||||
icon='[[_computeToggleIcon(opened)]]'
|
||||
hidden='[[!_states.length]]'
|
||||
>Toggle</paper-icon-button>
|
||||
<vaadin-combo-box-light items="[[_states]]" item-value-path="entity_id" item-label-path="entity_id" value="{{value}}" opened="{{opened}}" allow-custom-value="[[allowCustomEntity]]">
|
||||
<paper-input autofocus="[[autofocus]]" label="[[_computeLabel(label, localize)]]" class="input" value="[[value]]" disabled="[[disabled]]">
|
||||
<paper-icon-button slot="suffix" class="clear-button" icon="mdi:close" no-ripple="" hidden\$="[[!value]]">Clear</paper-icon-button>
|
||||
<paper-icon-button slot="suffix" class="toggle-button" icon="[[_computeToggleIcon(opened)]]" hidden="[[!_states.length]]">Toggle</paper-icon-button>
|
||||
</paper-input>
|
||||
<template>
|
||||
<style>
|
||||
@ -58,22 +38,17 @@
|
||||
}
|
||||
</style>
|
||||
<paper-icon-item>
|
||||
<state-badge state-obj="[[item]]" slot='item-icon'></state-badge>
|
||||
<paper-item-body two-line>
|
||||
<state-badge state-obj="[[item]]" slot="item-icon"></state-badge>
|
||||
<paper-item-body two-line="">
|
||||
<div>[[computeStateName(item)]]</div>
|
||||
<div secondary>[[item.entity_id]]</div>
|
||||
<div secondary="">[[item.entity_id]]</div>
|
||||
</paper-item-body>
|
||||
</paper-icon-item>
|
||||
</template>
|
||||
</vaadin-combo-box-light>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaEntityPicker extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-entity-picker'; }
|
||||
|
||||
static get properties() {
|
||||
@ -162,4 +137,3 @@ class HaEntityPicker extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HaEntityPicker.is, HaEntityPicker);
|
||||
</script>
|
||||
@ -1,9 +1,11 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/paper-toggle-button/paper-toggle-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-toggle-button/paper-toggle-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id="ha-entity-toggle">
|
||||
<template>
|
||||
class HaEntityToggle extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
white-space: nowrap;
|
||||
@ -24,20 +26,16 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<template is='dom-if' if='[[stateObj.attributes.assumed_state]]'>
|
||||
<paper-icon-button icon="mdi:flash-off" on-click="turnOff" state-active$='[[!isOn]]'></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:flash" on-click="turnOn" state-active$='[[isOn]]'></paper-icon-button>
|
||||
<template is="dom-if" if="[[stateObj.attributes.assumed_state]]">
|
||||
<paper-icon-button icon="mdi:flash-off" on-click="turnOff" state-active\$="[[!isOn]]"></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:flash" on-click="turnOn" state-active\$="[[isOn]]"></paper-icon-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[!stateObj.attributes.assumed_state]]'>
|
||||
<paper-toggle-button
|
||||
checked="[[toggleChecked]]"
|
||||
on-change="toggleChanged"></paper-toggle-button>
|
||||
<template is="dom-if" if="[[!stateObj.attributes.assumed_state]]">
|
||||
<paper-toggle-button checked="[[toggleChecked]]" on-change="toggleChanged"></paper-toggle-button>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaEntityToggle extends Polymer.Element {
|
||||
static get is() { return 'ha-entity-toggle'; }
|
||||
|
||||
static get properties() {
|
||||
@ -150,4 +148,3 @@ class HaEntityToggle extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HaEntityToggle.is, HaEntityToggle);
|
||||
</script>
|
||||
@ -1,29 +0,0 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
|
||||
<link rel="import" href="../../../bower_components/iron-icon/iron-icon.html">
|
||||
|
||||
<dom-module id="ha-state-icon">
|
||||
<template>
|
||||
<iron-icon icon="[[computeIcon(stateObj)]]"></iron-icon>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaStateIcon extends Polymer.Element {
|
||||
static get is() { return 'ha-state-icon'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
stateObj: {
|
||||
type: Object,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
computeIcon(stateObj) {
|
||||
return window.hassUtil.stateIcon(stateObj);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaStateIcon.is, HaStateIcon);
|
||||
</script>
|
||||
29
src/components/entity/ha-state-icon.js
Normal file
29
src/components/entity/ha-state-icon.js
Normal file
@ -0,0 +1,29 @@
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import stateIcon from '../../../js/common/entity/state_icon.js';
|
||||
|
||||
class HaStateIcon extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<iron-icon icon="[[computeIcon(stateObj)]]"></iron-icon>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-state-icon'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
stateObj: {
|
||||
type: Object,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
computeIcon(stateObj) {
|
||||
return stateIcon(stateObj);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaStateIcon.is, HaStateIcon);
|
||||
@ -1,12 +1,18 @@
|
||||
<link rel='import' href='../../../bower_components/polymer/polymer-element.html'>
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../../src/util/hass-mixins.html'>
|
||||
<link rel="import" href="../../../src/util/hass-util.html">
|
||||
import '../../util/hass-mixins.js';
|
||||
import '../../util/hass-util.js';
|
||||
import '../ha-label-badge.js';
|
||||
|
||||
<link rel='import' href='../ha-label-badge.html'>
|
||||
|
||||
<dom-module id='ha-state-label-badge'>
|
||||
<template>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaStateLabelBadge extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
cursor: pointer;
|
||||
@ -45,23 +51,10 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<ha-label-badge class$='[[computeClassNames(state)]]'
|
||||
value='[[computeValue(localize, state)]]'
|
||||
icon='[[computeIcon(state)]]'
|
||||
image='[[computeImage(state)]]'
|
||||
label='[[computeLabel(localize, state, timerTimeRemaining)]]'
|
||||
description='[[computeDescription(state)]]'
|
||||
></ha-label-badge>
|
||||
</template>
|
||||
</dom-module>
|
||||
<ha-label-badge class\$="[[computeClassNames(state)]]" value="[[computeValue(localize, state)]]" icon="[[computeIcon(state)]]" image="[[computeImage(state)]]" label="[[computeLabel(localize, state, timerTimeRemaining)]]" description="[[computeDescription(state)]]"></ha-label-badge>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaStateLabelBadge extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(Polymer.Element)) {
|
||||
static get is() { return 'ha-state-label-badge'; }
|
||||
|
||||
static get properties() {
|
||||
@ -211,4 +204,3 @@ class HaStateLabelBadge extends
|
||||
}
|
||||
|
||||
customElements.define(HaStateLabelBadge.is, HaStateLabelBadge);
|
||||
</script>
|
||||
@ -1,9 +1,12 @@
|
||||
<link rel='import' href='../../../bower_components/polymer/polymer-element.html'>
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='./ha-state-icon.html'>
|
||||
import './ha-state-icon.js';
|
||||
import computeStateDomain from '../../../js/common/entity/compute_state_domain.js';
|
||||
|
||||
<dom-module id='state-badge'>
|
||||
<template>
|
||||
class StateBadge extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
position: relative;
|
||||
@ -36,17 +39,10 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<ha-state-icon
|
||||
id='icon'
|
||||
state-obj='[[stateObj]]'
|
||||
data-domain$='[[computeDomain(stateObj)]]'
|
||||
data-state$='[[stateObj.state]]'
|
||||
></ha-state-icon>
|
||||
</template>
|
||||
</dom-module>
|
||||
<ha-state-icon id="icon" state-obj="[[stateObj]]" data-domain\$="[[computeDomain(stateObj)]]" data-state\$="[[stateObj.state]]"></ha-state-icon>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class StateBadge extends Polymer.Element {
|
||||
static get is() { return 'state-badge'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -58,7 +54,7 @@ class StateBadge extends Polymer.Element {
|
||||
}
|
||||
|
||||
computeDomain(stateObj) {
|
||||
return window.hassUtil.computeDomain(stateObj);
|
||||
return computeStateDomain(stateObj);
|
||||
}
|
||||
|
||||
|
||||
@ -92,4 +88,3 @@ class StateBadge extends Polymer.Element {
|
||||
}
|
||||
}
|
||||
customElements.define(StateBadge.is, StateBadge);
|
||||
</script>
|
||||
@ -1,11 +1,13 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="./state-badge.html">
|
||||
<link rel="import" href="../ha-relative-time.html">
|
||||
<link rel="import" href="../../util/hass-util.html">
|
||||
import '../ha-relative-time.js';
|
||||
import './state-badge.js';
|
||||
import computeStateName from '../../../js/common/entity/compute_state_name.js';
|
||||
|
||||
<dom-module id="state-info">
|
||||
<template>
|
||||
class StateInfo extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
@apply --paper-font-body1;
|
||||
@ -37,27 +39,25 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<state-badge state-obj='[[stateObj]]'></state-badge>
|
||||
<state-badge state-obj="[[stateObj]]"></state-badge>
|
||||
|
||||
<div class='info'>
|
||||
<div class='name' in-dialog$='[[inDialog]]'>[[computeStateName(stateObj)]]</div>
|
||||
<div class="info">
|
||||
<div class="name" in-dialog\$="[[inDialog]]">[[computeStateName(stateObj)]]</div>
|
||||
|
||||
<template is='dom-if' if='[[inDialog]]'>
|
||||
<div class='time-ago'>
|
||||
<ha-relative-time datetime='[[stateObj.last_changed]]'></ha-relative-time>
|
||||
<template is="dom-if" if="[[inDialog]]">
|
||||
<div class="time-ago">
|
||||
<ha-relative-time datetime="[[stateObj.last_changed]]"></ha-relative-time>
|
||||
</div>
|
||||
</template>
|
||||
<template is='dom-if' if='[[!inDialog]]'>
|
||||
<div class='extra-info'>
|
||||
<template is="dom-if" if="[[!inDialog]]">
|
||||
<div class="extra-info">
|
||||
<slot>
|
||||
</div>
|
||||
</slot></div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class StateInfo extends Polymer.Element {
|
||||
static get is() { return 'state-info'; }
|
||||
|
||||
static get properties() {
|
||||
@ -78,9 +78,8 @@ class StateInfo extends Polymer.Element {
|
||||
}
|
||||
|
||||
computeStateName(stateObj) {
|
||||
return window.hassUtil.computeStateName(stateObj);
|
||||
return computeStateName(stateObj);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(StateInfo.is, StateInfo);
|
||||
</script>
|
||||
@ -1,11 +1,12 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
import '../util/hass-attributes-util.js';
|
||||
|
||||
<link rel="import" href="../util/hass-attributes-util.html">
|
||||
|
||||
<dom-module id="ha-attributes">
|
||||
<template>
|
||||
class HaAttributes extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style is="custom-style" include="iron-flex iron-flex-alignment"></style>
|
||||
<style>
|
||||
.data-entry .value {
|
||||
@ -17,20 +18,18 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class='layout vertical'>
|
||||
<template is='dom-repeat' items="[[computeDisplayAttributes(stateObj, filtersArray)]]" as="attribute">
|
||||
<div class='data-entry layout justified horizontal'>
|
||||
<div class='key'>[[formatAttribute(attribute)]]</div>
|
||||
<div class='value'>[[formatAttributeValue(stateObj, attribute)]]</div>
|
||||
<div class="layout vertical">
|
||||
<template is="dom-repeat" items="[[computeDisplayAttributes(stateObj, filtersArray)]]" as="attribute">
|
||||
<div class="data-entry layout justified horizontal">
|
||||
<div class="key">[[formatAttribute(attribute)]]</div>
|
||||
<div class="value">[[formatAttributeValue(stateObj, attribute)]]</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class='attribution' hidden$='[[!computeAttribution(stateObj)]]'>[[computeAttribution(stateObj)]]</div>
|
||||
<div class="attribution" hidden\$="[[!computeAttribution(stateObj)]]">[[computeAttribution(stateObj)]]</div>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaAttributes extends Polymer.Element {
|
||||
static get is() { return 'ha-attributes'; }
|
||||
|
||||
static get properties() {
|
||||
@ -81,4 +80,3 @@ class HaAttributes extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HaAttributes.is, HaAttributes);
|
||||
</script>
|
||||
@ -1,14 +1,16 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href="../../bower_components/paper-material/paper-material.html">
|
||||
import '@polymer/paper-styles/element-styles/paper-material-styles.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id='ha-card'>
|
||||
<template>
|
||||
<style include="paper-material">
|
||||
class HaCard extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="paper-material-styles">
|
||||
:host {
|
||||
@apply --paper-material-elevation-1;
|
||||
display: block;
|
||||
border-radius: 2px;
|
||||
transition: all 0.30s ease-out;
|
||||
|
||||
background-color: var(--paper-card-background-color, white);
|
||||
}
|
||||
.header {
|
||||
@ -20,15 +22,13 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<template is='dom-if' if='[[header]]'>
|
||||
<div class='header'>[[header]]</div>
|
||||
<template is="dom-if" if="[[header]]">
|
||||
<div class="header">[[header]]</div>
|
||||
</template>
|
||||
<slot></slot>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaCard extends Polymer.Element {
|
||||
static get is() { return 'ha-card'; }
|
||||
|
||||
static get properties() {
|
||||
@ -36,17 +36,8 @@ class HaCard extends Polymer.Element {
|
||||
header: {
|
||||
type: String,
|
||||
},
|
||||
/**
|
||||
* The z-depth of the card, from 0-5.
|
||||
*/
|
||||
elevation: {
|
||||
type: Number,
|
||||
value: 1,
|
||||
reflectToAttribute: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaCard.is, HaCard);
|
||||
</script>
|
||||
@ -1,84 +1,14 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/polymer/lib/utils/debounce.html">
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import { timeOut } from '@polymer/polymer/lib/utils/async.js';
|
||||
import { Debouncer } from '@polymer/polymer/lib/utils/debounce.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
import '../cards/ha-badges-card.js';
|
||||
import '../cards/ha-card-chooser.js';
|
||||
import '../util/hass-util.js';
|
||||
import './ha-demo-badge.js';
|
||||
|
||||
<link rel="import" href="./ha-demo-badge.html">
|
||||
<link rel="import" href="../cards/ha-badges-card.html">
|
||||
<link rel="import" href="../cards/ha-card-chooser.html">
|
||||
|
||||
<link rel="import" href="../util/hass-util.html">
|
||||
|
||||
<dom-module id="ha-cards">
|
||||
<template>
|
||||
<style is="custom-style" include="iron-flex iron-flex-factors"></style>
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
padding-top: 8px;
|
||||
padding-right: 8px;
|
||||
transform: translateZ(0);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.badges {
|
||||
font-size: 85%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.column {
|
||||
max-width: 500px;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
ha-card-chooser {
|
||||
display: block;
|
||||
margin-left: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
:host {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
ha-card-chooser {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 599px) {
|
||||
.column {
|
||||
max-width: 600px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id='main'>
|
||||
<template is='dom-if' if='[[cards.badges]]'>
|
||||
<div class='badges'>
|
||||
<template is='dom-if' if='[[cards.demo]]'>
|
||||
<ha-demo-badge></ha-demo-badge>
|
||||
</template>
|
||||
|
||||
<ha-badges-card states='[[cards.badges]]' hass='[[hass]]'></ha-badges-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class='horizontal layout center-justified'>
|
||||
<template is='dom-repeat' items='[[cards.columns]]' as='column'>
|
||||
<div class='column flex-1'>
|
||||
<template is='dom-repeat' items='[[column]]' as='card'>
|
||||
<ha-card-chooser card-data='[[card]]'></ha-card-chooser>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
{
|
||||
// mapping domain to size of the card.
|
||||
const DOMAINS_WITH_CARD = {
|
||||
@ -145,7 +75,76 @@
|
||||
|
||||
const computeDomain = window.hassUtil.computeDomain;
|
||||
|
||||
class HaCards extends Polymer.Element {
|
||||
class HaCards extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style is="custom-style" include="iron-flex iron-flex-factors"></style>
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
padding-top: 8px;
|
||||
padding-right: 8px;
|
||||
transform: translateZ(0);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.badges {
|
||||
font-size: 85%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.column {
|
||||
max-width: 500px;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
ha-card-chooser {
|
||||
display: block;
|
||||
margin-left: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
:host {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
ha-card-chooser {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 599px) {
|
||||
.column {
|
||||
max-width: 600px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="main">
|
||||
<template is="dom-if" if="[[cards.badges]]">
|
||||
<div class="badges">
|
||||
<template is="dom-if" if="[[cards.demo]]">
|
||||
<ha-demo-badge></ha-demo-badge>
|
||||
</template>
|
||||
|
||||
<ha-badges-card states="[[cards.badges]]" hass="[[hass]]"></ha-badges-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="horizontal layout center-justified">
|
||||
<template is="dom-repeat" items="[[cards.columns]]" as="column">
|
||||
<div class="column flex-1">
|
||||
<template is="dom-repeat" items="[[column]]" as="card">
|
||||
<ha-card-chooser card-data="[[card]]"></ha-card-chooser>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-cards'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -192,9 +191,9 @@
|
||||
} else if (!this.$.main.parentNode && this.$.main._parentNode) {
|
||||
this.$.main._parentNode.appendChild(this.$.main);
|
||||
}
|
||||
this._debouncer = Polymer.Debouncer.debounce(
|
||||
this._debouncer = Debouncer.debounce(
|
||||
this._debouncer,
|
||||
Polymer.Async.timeOut.after(10),
|
||||
timeOut.after(10),
|
||||
() => {
|
||||
// Things might have changed since it got scheduled.
|
||||
if (this.panelVisible && this.viewVisible) {
|
||||
@ -367,4 +366,3 @@
|
||||
}
|
||||
customElements.define(HaCards.is, HaCards);
|
||||
}
|
||||
</script>
|
||||
@ -1,11 +1,13 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../util/hass-mixins.html'>
|
||||
import '../util/hass-mixins.js';
|
||||
|
||||
<dom-module id="ha-climate-control">
|
||||
<template>
|
||||
class HaClimateControl extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style is="custom-style" include="iron-flex iron-flex-alignment"></style>
|
||||
<style>
|
||||
/* local DOM styles go here */
|
||||
@ -43,10 +45,9 @@
|
||||
<paper-icon-button icon="mdi:chevron-down" on-click="decrementValue"></paper-icon-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
<script>
|
||||
class HaClimateControl extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-climate-control'; }
|
||||
|
||||
static get properties() {
|
||||
@ -123,4 +124,3 @@ class HaClimateControl extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HaClimateControl.is, HaClimateControl);
|
||||
</script>
|
||||
@ -1,7 +1,9 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id="ha-climate-state">
|
||||
<template>
|
||||
class HaClimateState extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
display: flex;
|
||||
@ -24,23 +26,21 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class='target'>
|
||||
<div class="target">
|
||||
<span class="state-label">
|
||||
[[stateObj.state]]
|
||||
</span>
|
||||
[[computeTarget(stateObj)]]
|
||||
</div>
|
||||
|
||||
<template is='dom-if' if='[[currentStatus]]'>
|
||||
<div class='current'>
|
||||
<template is="dom-if" if="[[currentStatus]]">
|
||||
<div class="current">
|
||||
Currently: [[currentStatus]]
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaClimateState extends Polymer.Element {
|
||||
static get is() { return 'ha-climate-state'; }
|
||||
|
||||
static get properties() {
|
||||
@ -81,4 +81,3 @@ class HaClimateState extends Polymer.Element {
|
||||
}
|
||||
}
|
||||
customElements.define(HaClimateState.is, HaClimateState);
|
||||
</script>
|
||||
@ -1,9 +1,14 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
import '../util/hass-mixins.js';
|
||||
|
||||
<dom-module id='ha-color-picker'>
|
||||
<template>
|
||||
/**
|
||||
* Color-picker custom element
|
||||
*/
|
||||
class HaColorPicker extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
user-select: none;
|
||||
@ -55,29 +60,24 @@
|
||||
}
|
||||
|
||||
</style>
|
||||
<div id='canvas'>
|
||||
<svg id='interactionLayer'>
|
||||
<div id="canvas">
|
||||
<svg id="interactionLayer">
|
||||
<defs>
|
||||
<filter id="marker-shadow" x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox">
|
||||
<feOffset result="offOut" in="SourceAlpha" dx="2" dy="2" />
|
||||
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="2" />
|
||||
<feOffset result="offOut" in="SourceAlpha" dx="2" dy="2"></feOffset>
|
||||
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="2"></feGaussianBlur>
|
||||
<feComponentTransfer in="blurOut" result="alphaOut">
|
||||
<feFuncA type="linear" slope="0.3" />
|
||||
<feFuncA type="linear" slope="0.3"></feFuncA>
|
||||
</feComponentTransfer>
|
||||
<feBlend in="SourceGraphic" in2="alphaOut" mode="normal" />
|
||||
<feBlend in="SourceGraphic" in2="alphaOut" mode="normal"></feBlend>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
<canvas id='backgroundLayer'></canvas>
|
||||
<canvas id="backgroundLayer"></canvas>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
/**
|
||||
* Color-picker custom element
|
||||
*/
|
||||
class HaColorPicker extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-color-picker'; }
|
||||
|
||||
static get properties() {
|
||||
@ -526,4 +526,3 @@ class HaColorPicker extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
}
|
||||
customElements.define(HaColorPicker.is, HaColorPicker);
|
||||
</script>
|
||||
@ -1,11 +1,13 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/vaadin-combo-box/vaadin-combo-box-light.html">
|
||||
<link rel="import" href="../../bower_components/paper-item/paper-item.html">
|
||||
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
<link rel="import" href="../../bower_components/paper-input/paper-input.html">
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
import '@vaadin/vaadin-combo-box/vaadin-combo-box-light.js';
|
||||
|
||||
<dom-module id="ha-combo-box">
|
||||
<template>
|
||||
class HaComboBox extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
paper-input > paper-icon-button {
|
||||
width: 24px;
|
||||
@ -17,32 +19,10 @@
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<vaadin-combo-box-light
|
||||
items='[[_items]]'
|
||||
item-value-path='[[itemValuePath]]'
|
||||
item-label-path='[[itemLabelPath]]'
|
||||
value='{{value}}'
|
||||
opened='{{opened}}'
|
||||
allow-custom-value='[[allowCustomValue]]'
|
||||
>
|
||||
<paper-input
|
||||
autofocus="[[autofocus]]"
|
||||
label="[[label]]"
|
||||
class="input"
|
||||
value='[[value]]'
|
||||
>
|
||||
<paper-icon-button
|
||||
slot="suffix"
|
||||
class="clear-button"
|
||||
icon="mdi:close"
|
||||
hidden$='[[!value]]'
|
||||
>Clear</paper-icon-button>
|
||||
<paper-icon-button
|
||||
slot="suffix"
|
||||
class="toggle-button"
|
||||
icon='[[_computeToggleIcon(opened)]]'
|
||||
hidden$='[[!items.length]]'
|
||||
>Toggle</paper-icon-button>
|
||||
<vaadin-combo-box-light items="[[_items]]" item-value-path="[[itemValuePath]]" item-label-path="[[itemLabelPath]]" value="{{value}}" opened="{{opened}}" allow-custom-value="[[allowCustomValue]]">
|
||||
<paper-input autofocus="[[autofocus]]" label="[[label]]" class="input" value="[[value]]">
|
||||
<paper-icon-button slot="suffix" class="clear-button" icon="mdi:close" hidden\$="[[!value]]">Clear</paper-icon-button>
|
||||
<paper-icon-button slot="suffix" class="toggle-button" icon="[[_computeToggleIcon(opened)]]" hidden\$="[[!items.length]]">Toggle</paper-icon-button>
|
||||
</paper-input>
|
||||
<template>
|
||||
<style>
|
||||
@ -53,11 +33,9 @@
|
||||
<paper-item>[[_computeItemLabel(item, itemLabelPath)]]</paper-item>
|
||||
</template>
|
||||
</vaadin-combo-box-light>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaComboBox extends Polymer.Element {
|
||||
static get is() { return 'ha-combo-box'; }
|
||||
|
||||
static get properties() {
|
||||
@ -106,4 +84,3 @@ class HaComboBox extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HaComboBox.is, HaComboBox);
|
||||
</script>
|
||||
@ -1,10 +1,12 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../util/cover-model.html">
|
||||
import '../util/cover-model.js';
|
||||
|
||||
<dom-module id="ha-cover-controls">
|
||||
<template>
|
||||
class HaCoverControls extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
.state {
|
||||
white-space: nowrap;
|
||||
@ -14,21 +16,14 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class='state'>
|
||||
<paper-icon-button icon="mdi:arrow-up" on-click='onOpenTap'
|
||||
invisible$='[[!entityObj.supportsOpen]]'
|
||||
disabled='[[computeOpenDisabled(stateObj, entityObj)]]'></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:stop" on-click='onStopTap'
|
||||
invisible$='[[!entityObj.supportsStop]]'></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:arrow-down" on-click='onCloseTap'
|
||||
invisible$='[[!entityObj.supportsClose]]'
|
||||
disabled='[[computeClosedDisabled(stateObj, entityObj)]]'></paper-icon-button>
|
||||
<div class="state">
|
||||
<paper-icon-button icon="mdi:arrow-up" on-click="onOpenTap" invisible\$="[[!entityObj.supportsOpen]]" disabled="[[computeOpenDisabled(stateObj, entityObj)]]"></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:stop" on-click="onStopTap" invisible\$="[[!entityObj.supportsStop]]"></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:arrow-down" on-click="onCloseTap" invisible\$="[[!entityObj.supportsClose]]" disabled="[[computeClosedDisabled(stateObj, entityObj)]]"></paper-icon-button>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaCoverControls extends Polymer.Element {
|
||||
static get is() { return 'ha-cover-controls'; }
|
||||
|
||||
static get properties() {
|
||||
@ -71,4 +66,3 @@ class HaCoverControls extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HaCoverControls.is, HaCoverControls);
|
||||
</script>
|
||||
@ -1,12 +1,13 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
import '../util/cover-model.js';
|
||||
|
||||
<link rel='import' href='../util/cover-model.html'>
|
||||
|
||||
<dom-module id='ha-cover-tilt-controls'>
|
||||
<template>
|
||||
class HaCoverTiltControls extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style is="custom-style" include="iron-flex"></style>
|
||||
<style>
|
||||
:host {
|
||||
@ -16,22 +17,12 @@
|
||||
visibility: hidden !important;
|
||||
}
|
||||
</style>
|
||||
<paper-icon-button icon="mdi:arrow-top-right"
|
||||
on-click='onOpenTiltTap' title='Open tilt'
|
||||
invisible$='[[!entityObj.supportsOpenTilt]]'
|
||||
disabled='[[computeOpenDisabled(stateObj, entityObj)]]'></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:stop" on-click='onStopTiltTap'
|
||||
invisible$='[[!entityObj.supportsStopTilt]]'
|
||||
title='Stop tilt'></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:arrow-bottom-left"
|
||||
on-click='onCloseTiltTap' title='Close tilt'
|
||||
invisible$='[[!entityObj.supportsCloseTilt]]'
|
||||
disabled='[[computeClosedDisabled(stateObj, entityObj)]]'></paper-icon-button>
|
||||
</template>
|
||||
</dom-module>
|
||||
<paper-icon-button icon="mdi:arrow-top-right" on-click="onOpenTiltTap" title="Open tilt" invisible\$="[[!entityObj.supportsOpenTilt]]" disabled="[[computeOpenDisabled(stateObj, entityObj)]]"></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:stop" on-click="onStopTiltTap" invisible\$="[[!entityObj.supportsStopTilt]]" title="Stop tilt"></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:arrow-bottom-left" on-click="onCloseTiltTap" title="Close tilt" invisible\$="[[!entityObj.supportsCloseTilt]]" disabled="[[computeClosedDisabled(stateObj, entityObj)]]"></paper-icon-button>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaCoverTiltControls extends Polymer.Element {
|
||||
static get is() { return 'ha-cover-tilt-controls'; }
|
||||
|
||||
static get properties() {
|
||||
@ -74,4 +65,3 @@ class HaCoverTiltControls extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HaCoverTiltControls.is, HaCoverTiltControls);
|
||||
</script>
|
||||
@ -1,27 +0,0 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
|
||||
<link rel='import' href='./ha-label-badge.html'>
|
||||
|
||||
<dom-module id='ha-demo-badge'>
|
||||
<template>
|
||||
<style>
|
||||
:host {
|
||||
--ha-label-badge-color: #dac90d;
|
||||
}
|
||||
</style>
|
||||
|
||||
<ha-label-badge
|
||||
icon='mdi:emoticon'
|
||||
label='Demo'
|
||||
description=''
|
||||
></ha-label-badge>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaDemoBadge extends Polymer.Element {
|
||||
static get is() { return 'ha-demo-badge'; }
|
||||
}
|
||||
|
||||
customElements.define(HaDemoBadge.is, HaDemoBadge);
|
||||
</script>
|
||||
22
src/components/ha-demo-badge.js
Normal file
22
src/components/ha-demo-badge.js
Normal file
@ -0,0 +1,22 @@
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import './ha-label-badge.js';
|
||||
|
||||
class HaDemoBadge extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
--ha-label-badge-color: #dac90d;
|
||||
}
|
||||
</style>
|
||||
|
||||
<ha-label-badge icon="mdi:emoticon" label="Demo" description=""></ha-label-badge>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-demo-badge'; }
|
||||
}
|
||||
|
||||
customElements.define(HaDemoBadge.is, HaDemoBadge);
|
||||
@ -1,153 +0,0 @@
|
||||
<link rel="import" href='../../bower_components/polymer/polymer-element.html'>
|
||||
|
||||
<link rel="import" href='../../bower_components/paper-input/paper-input.html'>
|
||||
<link rel="import" href='../../bower_components/paper-checkbox/paper-checkbox.html'>
|
||||
<link rel='import' href='../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html'>
|
||||
<link rel='import' href='../../bower_components/paper-listbox/paper-listbox.html'>
|
||||
<link rel='import' href='../../bower_components/paper-item/paper-item.html'>
|
||||
|
||||
<link rel='import' href='../util/hass-mixins.html'>
|
||||
<link rel="import" href='./ha-paper-slider.html'>
|
||||
|
||||
|
||||
<dom-module id="ha-form">
|
||||
<template>
|
||||
<style>
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
<template is='dom-if' if='[[_isArray(schema)]]' restamp>
|
||||
<template is='dom-if' if='[[error.base]]'>
|
||||
[[computeError(error.base, schema)]]
|
||||
</template>
|
||||
|
||||
<template is='dom-repeat' items='[[schema]]'>
|
||||
<ha-form
|
||||
data='[[_getValue(data, item)]]'
|
||||
schema='[[item]]'
|
||||
error='[[_getValue(error, item)]]'
|
||||
on-data-changed='_valueChanged'
|
||||
compute-label='[[computeLabel]]'
|
||||
compute-error='[[computeError]]'
|
||||
></ha-form>
|
||||
</template>
|
||||
</template>
|
||||
<template is='dom-if' if='[[!_isArray(schema)]]' restamp>
|
||||
<template is='dom-if' if='[[error]]'>
|
||||
<div class='error'>[[computeError(error, schema)]]</div>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[_equals(schema.type, "string")]]' restamp>
|
||||
<paper-input
|
||||
label='[[computeLabel(schema)]]'
|
||||
value='{{data}}'
|
||||
></paper-input>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[_equals(schema.type, "integer")]]' restamp>
|
||||
<template is='dom-if' if='[[_isRange(schema)]]' restamp>
|
||||
<div>
|
||||
[[computeLabel(schema)]]
|
||||
<ha-paper-slider
|
||||
pin
|
||||
value='{{data}}'
|
||||
min='[[schema.valueMin]]'
|
||||
max='[[schema.valueMax]]'
|
||||
></ha-paper-slider>
|
||||
</div>
|
||||
</template>
|
||||
<template is='dom-if' if='[[!_isRange(schema)]]' restamp>
|
||||
<paper-input
|
||||
label='[[computeLabel(schema)]]'
|
||||
value='{{data}}'
|
||||
type='number'
|
||||
></paper-input>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[_equals(schema.type, "float")]]' restamp>
|
||||
<!--TODO-->
|
||||
<paper-input
|
||||
label='[[computeLabel(schema)]]'
|
||||
value='{{data}}'
|
||||
></paper-input>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[_equals(schema.type, "boolean")]]' restamp>
|
||||
<paper-checkbox
|
||||
checked='{{data}}'
|
||||
>[[computeLabel(schema)]]</paper-checkbox>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[_equals(schema.type, "select")]]' restamp>
|
||||
<paper-dropdown-menu label='[[computeLabel(schema)]]'>
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
attr-for-selected="item-name"
|
||||
selected="{{data}}"
|
||||
>
|
||||
<template is='dom-repeat'
|
||||
items='[[schema.options]]'>
|
||||
<paper-item item-name$='[[item]]'>[[item]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaForm extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-form'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
data: {
|
||||
type: Object,
|
||||
notify: true,
|
||||
},
|
||||
schema: Object,
|
||||
error: Object,
|
||||
|
||||
// A function that will computes the label to be displayed for a given
|
||||
// schema object.
|
||||
computeLabel: {
|
||||
type: Function,
|
||||
value: () => schema => schema && schema.name,
|
||||
},
|
||||
|
||||
// A function that will computes an error message to be displayed for a
|
||||
// given error ID, and relevant schema object
|
||||
computeError: {
|
||||
type: Function,
|
||||
value: () => (error, schema) => error, // eslint-disable-line no-unused-vars
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
_isArray(val) {
|
||||
return Array.isArray(val);
|
||||
}
|
||||
|
||||
_isRange(schema) {
|
||||
return ('valueMin' in schema) && ('valueMax' in schema);
|
||||
}
|
||||
|
||||
_equals(a, b) {
|
||||
return a === b;
|
||||
}
|
||||
|
||||
_getValue(obj, item) {
|
||||
return obj[item.name];
|
||||
}
|
||||
|
||||
_valueChanged(ev) {
|
||||
this.set(['data', ev.model.item.name], ev.detail.value);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaForm.is, HaForm);
|
||||
</script>
|
||||
121
src/components/ha-form.js
Normal file
121
src/components/ha-form.js
Normal file
@ -0,0 +1,121 @@
|
||||
import '@polymer/paper-checkbox/paper-checkbox.js';
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../util/hass-mixins.js';
|
||||
import './ha-paper-slider.js';
|
||||
|
||||
class HaForm extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
<template is="dom-if" if="[[_isArray(schema)]]" restamp="">
|
||||
<template is="dom-if" if="[[error.base]]">
|
||||
[[computeError(error.base, schema)]]
|
||||
</template>
|
||||
|
||||
<template is="dom-repeat" items="[[schema]]">
|
||||
<ha-form data="[[_getValue(data, item)]]" schema="[[item]]" error="[[_getValue(error, item)]]" on-data-changed="_valueChanged" compute-label="[[computeLabel]]" compute-error="[[computeError]]"></ha-form>
|
||||
</template>
|
||||
</template>
|
||||
<template is="dom-if" if="[[!_isArray(schema)]]" restamp="">
|
||||
<template is="dom-if" if="[[error]]">
|
||||
<div class="error">[[computeError(error, schema)]]</div>
|
||||
</template>
|
||||
|
||||
<template is="dom-if" if="[[_equals(schema.type, "string")]]" restamp="">
|
||||
<paper-input label="[[computeLabel(schema)]]" value="{{data}}"></paper-input>
|
||||
</template>
|
||||
|
||||
<template is="dom-if" if="[[_equals(schema.type, "integer")]]" restamp="">
|
||||
<template is="dom-if" if="[[_isRange(schema)]]" restamp="">
|
||||
<div>
|
||||
[[computeLabel(schema)]]
|
||||
<ha-paper-slider pin="" value="{{data}}" min="[[schema.valueMin]]" max="[[schema.valueMax]]"></ha-paper-slider>
|
||||
</div>
|
||||
</template>
|
||||
<template is="dom-if" if="[[!_isRange(schema)]]" restamp="">
|
||||
<paper-input label="[[computeLabel(schema)]]" value="{{data}}" type="number"></paper-input>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template is="dom-if" if="[[_equals(schema.type, "float")]]" restamp="">
|
||||
<!--TODO-->
|
||||
<paper-input label="[[computeLabel(schema)]]" value="{{data}}"></paper-input>
|
||||
</template>
|
||||
|
||||
<template is="dom-if" if="[[_equals(schema.type, "boolean")]]" restamp="">
|
||||
<paper-checkbox checked="{{data}}">[[computeLabel(schema)]]</paper-checkbox>
|
||||
</template>
|
||||
|
||||
<template is="dom-if" if="[[_equals(schema.type, "select")]]" restamp="">
|
||||
<paper-dropdown-menu label="[[computeLabel(schema)]]">
|
||||
<paper-listbox slot="dropdown-content" attr-for-selected="item-name" selected="{{data}}">
|
||||
<template is="dom-repeat" items="[[schema.options]]">
|
||||
<paper-item item-name\$="[[item]]">[[item]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-form'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
data: {
|
||||
type: Object,
|
||||
notify: true,
|
||||
},
|
||||
schema: Object,
|
||||
error: Object,
|
||||
|
||||
// A function that will computes the label to be displayed for a given
|
||||
// schema object.
|
||||
computeLabel: {
|
||||
type: Function,
|
||||
value: () => schema => schema && schema.name,
|
||||
},
|
||||
|
||||
// A function that will computes an error message to be displayed for a
|
||||
// given error ID, and relevant schema object
|
||||
computeError: {
|
||||
type: Function,
|
||||
value: () => (error, schema) => error, // eslint-disable-line no-unused-vars
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
_isArray(val) {
|
||||
return Array.isArray(val);
|
||||
}
|
||||
|
||||
_isRange(schema) {
|
||||
return ('valueMin' in schema) && ('valueMax' in schema);
|
||||
}
|
||||
|
||||
_equals(a, b) {
|
||||
return a === b;
|
||||
}
|
||||
|
||||
_getValue(obj, item) {
|
||||
return obj[item.name];
|
||||
}
|
||||
|
||||
_valueChanged(ev) {
|
||||
this.set(['data', ev.model.item.name], ev.detail.value);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaForm.is, HaForm);
|
||||
35
src/components/ha-iconset-svg.js
Normal file
35
src/components/ha-iconset-svg.js
Normal file
@ -0,0 +1,35 @@
|
||||
import '@polymer/iron-iconset-svg/iron-iconset-svg.js';
|
||||
|
||||
const IronIconsetClass = customElements.get('iron-iconset-svg');
|
||||
|
||||
class HaIconset extends IronIconsetClass {
|
||||
/**
|
||||
* Fire 'iron-iconset-added' event at next microtask.
|
||||
*/
|
||||
_fireIronIconsetAdded() {
|
||||
this.async(function () {
|
||||
this.fire('iron-iconset-added', this, { node: window });
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* When name is changed, register iconset metadata
|
||||
*
|
||||
*/
|
||||
_nameChanged() {
|
||||
this._meta.value = null;
|
||||
this._meta.key = this.name;
|
||||
this._meta.value = this;
|
||||
if (this.ownerDocument && this.ownerDocument.readyState === 'loading') {
|
||||
// Document still loading. It could be that not all icons in the iconset are parsed yet.
|
||||
this.ownerDocument.addEventListener('DOMContentLoaded', function () {
|
||||
this._fireIronIconsetAdded();
|
||||
}.bind(this));
|
||||
} else {
|
||||
this._fireIronIconsetAdded();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('ha-iconset-svg', HaIconset);
|
||||
@ -1,8 +1,10 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../bower_components/iron-icon/iron-icon.html'>
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id='ha-label-badge'>
|
||||
<template>
|
||||
class HaLabelBadge extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
.badge-container {
|
||||
display: inline-block;
|
||||
@ -78,23 +80,21 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class='badge-container'>
|
||||
<div class='label-badge' id='badge'>
|
||||
<div class$='[[computeValueClasses(value)]]'>
|
||||
<iron-icon icon='[[icon]]' hidden$='[[computeHideIcon(icon, value, image)]]'></iron-icon>
|
||||
<span hidden$='[[computeHideValue(value, image)]]'>[[value]]</span>
|
||||
<div class="badge-container">
|
||||
<div class="label-badge" id="badge">
|
||||
<div class\$="[[computeValueClasses(value)]]">
|
||||
<iron-icon icon="[[icon]]" hidden\$="[[computeHideIcon(icon, value, image)]]"></iron-icon>
|
||||
<span hidden\$="[[computeHideValue(value, image)]]">[[value]]</span>
|
||||
</div>
|
||||
<div hidden$='[[computeHideLabel(label)]]' class$='[[computeLabelClasses(label)]]'>
|
||||
<div hidden\$="[[computeHideLabel(label)]]" class\$="[[computeLabelClasses(label)]]">
|
||||
<span>[[label]]</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='title' hidden$='[[!description]]'>[[description]]</div>
|
||||
<div class="title" hidden\$="[[!description]]">[[description]]</div>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaLabelBadge extends Polymer.Element {
|
||||
static get is() { return 'ha-label-badge'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -135,4 +135,3 @@ class HaLabelBadge extends Polymer.Element {
|
||||
}
|
||||
}
|
||||
customElements.define(HaLabelBadge.is, HaLabelBadge);
|
||||
</script>
|
||||
@ -1,9 +1,12 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../bower_components/iron-icon/iron-icon.html'>
|
||||
<link rel="import" href='./ha-paper-slider.html'>
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id='ha-labeled-slider'>
|
||||
<template>
|
||||
import './ha-paper-slider.js';
|
||||
|
||||
class HaLabeledSlider extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
@ -30,17 +33,15 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class='title'>[[caption]]</div>
|
||||
<iron-icon icon='[[icon]]'></iron-icon>
|
||||
<div class='slider-container'>
|
||||
<ha-paper-slider min='[[min]]' max='[[max]]' value='{{value}}' ignore-bar-touch='[[ignoreBarTouch]]'>
|
||||
<div class="title">[[caption]]</div>
|
||||
<iron-icon icon="[[icon]]"></iron-icon>
|
||||
<div class="slider-container">
|
||||
<ha-paper-slider min="[[min]]" max="[[max]]" value="{{value}}" ignore-bar-touch="[[ignoreBarTouch]]">
|
||||
</ha-paper-slider>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaLabeledSlider extends Polymer.Element {
|
||||
static get is() { return 'ha-labeled-slider'; }
|
||||
|
||||
static get properties() {
|
||||
@ -60,4 +61,3 @@ class HaLabeledSlider extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HaLabeledSlider.is, HaLabeledSlider);
|
||||
</script>
|
||||
@ -1,12 +1,12 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
import '../util/hass-mixins.js';
|
||||
|
||||
<link rel='import' href='../util/hass-mixins.html'>
|
||||
let loaded = null;
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaMarkdown extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
class HaMarkdown extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get is() { return 'ha-markdown'; }
|
||||
|
||||
static get properties() {
|
||||
@ -24,11 +24,13 @@ class HaMarkdown extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
this._renderScheduled = false;
|
||||
this._resize = () => this.fire('iron-resize');
|
||||
|
||||
Polymer.importHref(
|
||||
'/static/markdown-js.html',
|
||||
() => { this._scriptLoaded = 1; this._render(); },
|
||||
() => { this._scriptLoaded = 2; this._render(); },
|
||||
);
|
||||
if (!loaded) {
|
||||
loaded = import(/* webpackChunkName: "load_markdown" */ '../resources/load_markdown.js');
|
||||
}
|
||||
loaded.then(
|
||||
() => { this._scriptLoaded = 1; },
|
||||
() => { this._scriptLoaded = 2; },
|
||||
).then(() => this._render());
|
||||
}
|
||||
|
||||
_render() {
|
||||
@ -71,4 +73,3 @@ class HaMarkdown extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HaMarkdown.is, HaMarkdown);
|
||||
</script>
|
||||
@ -1,25 +1,21 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../bower_components/paper-icon-button/paper-icon-button.html'>
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
import '../util/hass-mixins.js';
|
||||
|
||||
<dom-module id='ha-menu-button'>
|
||||
<template>
|
||||
class HaMenuButton extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
.invisible {
|
||||
visibility: hidden;
|
||||
}
|
||||
</style>
|
||||
<paper-icon-button
|
||||
icon='mdi:menu'
|
||||
class$='[[computeMenuButtonClass(narrow, showMenu)]]'
|
||||
on-click='toggleMenu'
|
||||
></paper-icon-button>
|
||||
</template>
|
||||
</dom-module>
|
||||
<paper-icon-button icon="mdi:menu" class\$="[[computeMenuButtonClass(narrow, showMenu)]]" on-click="toggleMenu"></paper-icon-button>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaMenuButton extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-menu-button'; }
|
||||
|
||||
static get properties() {
|
||||
@ -47,4 +43,3 @@ class HaMenuButton extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HaMenuButton.is, HaMenuButton);
|
||||
</script>
|
||||
@ -1,9 +1,12 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../bower_components/paper-slider/paper-slider.html">
|
||||
import '@polymer/paper-slider/paper-slider.js';
|
||||
import { DomModule } from '@polymer/polymer/lib/elements/dom-module.js';
|
||||
import '@polymer/polymer/polymer-legacy.js';
|
||||
|
||||
const documentContainer = document.createElement('template');
|
||||
documentContainer.setAttribute('style', 'display: none;');
|
||||
|
||||
<dom-module id="ha-paper-slider">
|
||||
<template strip-whitespace>
|
||||
documentContainer.innerHTML = `<dom-module id="ha-paper-slider">
|
||||
<template strip-whitespace="">
|
||||
<style include="paper-slider">
|
||||
.pin > .slider-knob > .slider-knob-inner {
|
||||
font-size: var(--ha-paper-slider-pin-font-size, 10px);
|
||||
@ -53,36 +56,36 @@
|
||||
</style>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
{
|
||||
/**
|
||||
* @polymer
|
||||
* @customElement
|
||||
* @appliesMixin paper-slider
|
||||
*/
|
||||
const PaperSliderClass = customElements.get('paper-slider');
|
||||
let myTemplate;
|
||||
</dom-module>`;
|
||||
|
||||
class HaPaperSlider extends PaperSliderClass {
|
||||
static get is() { return 'ha-paper-slider'; }
|
||||
document.head.appendChild(documentContainer.content);
|
||||
|
||||
static get template() {
|
||||
if (!myTemplate) {
|
||||
// Retrieve this element's dom-module template
|
||||
myTemplate = Polymer.DomModule.import(HaPaperSlider.is, 'template');
|
||||
// Clone the contents of the superclass template
|
||||
const superTemplateContents = document.importNode(PaperSliderClass.template.content, true);
|
||||
// Remove the style from superclass contents, we already included them in our own <style>
|
||||
superTemplateContents.querySelector('style').remove();
|
||||
// Insert the superclass contents
|
||||
myTemplate.content.append(superTemplateContents);
|
||||
}
|
||||
return myTemplate;
|
||||
}
|
||||
{
|
||||
/**
|
||||
* @polymer
|
||||
* @customElement
|
||||
* @appliesMixin paper-slider
|
||||
*/
|
||||
const PaperSliderClass = customElements.get('paper-slider');
|
||||
let myTemplate;
|
||||
|
||||
class HaPaperSlider extends PaperSliderClass {
|
||||
static get is() { return 'ha-paper-slider'; }
|
||||
|
||||
static get template() {
|
||||
if (!myTemplate) {
|
||||
// Retrieve this element's dom-module template
|
||||
myTemplate = DomModule.import(HaPaperSlider.is, 'template');
|
||||
// Clone the contents of the superclass template
|
||||
const superTemplateContents = document.importNode(PaperSliderClass.template.content, true);
|
||||
// Remove the style from superclass contents, we already included them in our own <style>
|
||||
superTemplateContents.querySelector('style').remove();
|
||||
// Insert the superclass contents
|
||||
myTemplate.content.append(superTemplateContents);
|
||||
}
|
||||
customElements.define(HaPaperSlider.is, HaPaperSlider);
|
||||
return myTemplate;
|
||||
}
|
||||
</script>
|
||||
</dom-module>
|
||||
}
|
||||
customElements.define(HaPaperSlider.is, HaPaperSlider);
|
||||
}
|
||||
@ -1,20 +1,16 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-toggle-button/paper-toggle-button.html">
|
||||
import '@polymer/paper-toggle-button/paper-toggle-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../util/hass-mixins.html'>
|
||||
import '../util/hass-mixins.js';
|
||||
|
||||
<dom-module id='ha-push-notifications-toggle'>
|
||||
<template>
|
||||
<paper-toggle-button
|
||||
hidden$='[[!pushSupported]]'
|
||||
disabled='[[loading]]'
|
||||
checked='{{pushChecked}}'
|
||||
></paper-toggle-button>
|
||||
</template>
|
||||
</dom-module>
|
||||
class HaPushNotificationsToggle extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<paper-toggle-button hidden\$="[[!pushSupported]]" disabled="[[loading]]" checked="{{pushChecked}}"></paper-toggle-button>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaPushNotificationsToggle extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-push-notifications-toggle'; }
|
||||
|
||||
static get properties() {
|
||||
@ -127,4 +123,3 @@ class HaPushNotificationsToggle extends window.hassMixins.EventsMixin(Polymer.El
|
||||
}
|
||||
|
||||
customElements.define(HaPushNotificationsToggle.is, HaPushNotificationsToggle);
|
||||
</script>
|
||||
@ -1,7 +1,9 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<script>
|
||||
class HaRelativeTime extends Polymer.Element {
|
||||
import relativeTime from '../../js/common/datetime/relative_time.js';
|
||||
|
||||
class HaRelativeTime extends PolymerElement {
|
||||
static get is() { return 'ha-relative-time'; }
|
||||
|
||||
static get properties() {
|
||||
@ -51,11 +53,10 @@ class HaRelativeTime extends Polymer.Element {
|
||||
}
|
||||
|
||||
updateRelative() {
|
||||
var root = Polymer.dom(this);
|
||||
var root = dom(this);
|
||||
root.innerHTML = this.parsedDateTime ?
|
||||
window.hassUtil.relativeTime(this.parsedDateTime) : 'never';
|
||||
relativeTime(this.parsedDateTime) : 'never';
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaRelativeTime.is, HaRelativeTime);
|
||||
</script>
|
||||
@ -1,13 +1,13 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id='ha-service-description'>
|
||||
<template>
|
||||
class HaServiceDescription extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
[[_getDescription(hass, domain, service)]]
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaServiceDescription extends Polymer.Element {
|
||||
static get is() { return 'ha-service-description'; }
|
||||
|
||||
static get properties() {
|
||||
@ -28,4 +28,3 @@ class HaServiceDescription extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(HaServiceDescription.is, HaServiceDescription);
|
||||
</script>
|
||||
@ -1,25 +1,19 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../util/hass-mixins.html">
|
||||
import '../util/hass-mixins.js';
|
||||
import './ha-combo-box.js';
|
||||
|
||||
<link rel="import" href="./ha-combo-box.html">
|
||||
|
||||
<dom-module id="ha-service-picker">
|
||||
<template>
|
||||
<ha-combo-box
|
||||
label="[[localize('ui.components.service-picker.service')]]"
|
||||
items='[[_services]]'
|
||||
value='{{value}}'
|
||||
allow-custom-value
|
||||
></ha-combo-box>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaServicePicker extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
class HaServicePicker extends window.hassMixins.LocalizeMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<ha-combo-box label="[[localize('ui.components.service-picker.service')]]" items="[[_services]]" value="{{value}}" allow-custom-value=""></ha-combo-box>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'ha-service-picker'; }
|
||||
|
||||
static get properties() {
|
||||
@ -58,4 +52,3 @@ class HaServicePicker extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(HaServicePicker.is, HaServicePicker);
|
||||
</script>
|
||||
@ -1,18 +1,24 @@
|
||||
<link rel="import" href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
<link rel='import' href='../../bower_components/iron-icon/iron-icon.html'>
|
||||
<link rel='import' href='../../bower_components/paper-listbox/paper-listbox.html'>
|
||||
<link rel='import' href='../../bower_components/paper-item/paper-item.html'>
|
||||
<link rel='import' href='../../bower_components/paper-item/paper-icon-item.html'>
|
||||
<link rel='import' href='../../bower_components/paper-icon-button/paper-icon-button.html'>
|
||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-item/paper-icon-item.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
import '../util/hass-mixins.js';
|
||||
import '../util/hass-translation.js';
|
||||
|
||||
<link rel='import' href='../util/hass-mixins.html'>
|
||||
<link rel='import' href='../util/hass-translation.html'>
|
||||
|
||||
<dom-module id='ha-sidebar'>
|
||||
<template>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaSidebar extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.NavigateMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex iron-flex-alignment iron-positioning">
|
||||
:host {
|
||||
--sidebar-text: {
|
||||
@ -94,73 +100,48 @@
|
||||
</style>
|
||||
|
||||
<app-toolbar>
|
||||
<div main-title>Home Assistant</div>
|
||||
<paper-icon-button icon='mdi:chevron-left' hidden$='[[narrow]]' on-click='toggleMenu'></paper-icon-button>
|
||||
<div main-title="">Home Assistant</div>
|
||||
<paper-icon-button icon="mdi:chevron-left" hidden\$="[[narrow]]" on-click="toggleMenu"></paper-icon-button>
|
||||
</app-toolbar>
|
||||
|
||||
<paper-listbox attr-for-selected='data-panel' selected='[[hass.panelUrl]]'>
|
||||
<paper-icon-item on-click='menuClicked' data-panel='states'>
|
||||
<iron-icon slot="item-icon" icon='mdi:apps'></iron-icon>
|
||||
<span class='item-text'>[[localize('panel.states')]]</span>
|
||||
<paper-listbox attr-for-selected="data-panel" selected="[[hass.panelUrl]]">
|
||||
<paper-icon-item on-click="menuClicked" data-panel="states">
|
||||
<iron-icon slot="item-icon" icon="mdi:apps"></iron-icon>
|
||||
<span class="item-text">[[localize('panel.states')]]</span>
|
||||
</paper-icon-item>
|
||||
|
||||
<template is='dom-repeat' items='[[panels]]'>
|
||||
<paper-icon-item on-click='menuClicked' data-panel$='[[item.url_path]]'>
|
||||
<iron-icon slot="item-icon" icon='[[item.icon]]'></iron-icon>
|
||||
<span class='item-text'>[[computePanelName(localize, item)]]</span>
|
||||
<template is="dom-repeat" items="[[panels]]">
|
||||
<paper-icon-item on-click="menuClicked">
|
||||
<iron-icon slot="item-icon" icon="[[item.icon]]"></iron-icon>
|
||||
<span class="item-text">[[computePanelName(localize, item)]]</span>
|
||||
</paper-icon-item>
|
||||
</template>
|
||||
|
||||
<paper-icon-item on-click='menuClicked' data-panel='logout' class='logout'>
|
||||
<iron-icon slot="item-icon" icon='mdi:exit-to-app'></iron-icon>
|
||||
<span class='item-text'>[[localize('ui.sidebar.log_out')]]</span>
|
||||
<paper-icon-item on-click="menuClicked" data-panel="logout" class="logout">
|
||||
<iron-icon slot="item-icon" icon="mdi:exit-to-app"></iron-icon>
|
||||
<span class="item-text">[[localize('ui.sidebar.log_out')]]</span>
|
||||
</paper-icon-item>
|
||||
</paper-listbox>
|
||||
|
||||
<div>
|
||||
<div class='divider'></div>
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class='subheader'>[[localize('ui.sidebar.developer_tools')]]</div>
|
||||
<div class="subheader">[[localize('ui.sidebar.developer_tools')]]</div>
|
||||
|
||||
<div class='dev-tools layout horizontal justified'>
|
||||
<paper-icon-button
|
||||
icon='mdi:remote' data-panel='dev-service'
|
||||
alt="[[localize('panel.dev-services')]]" title="[[localize('panel.dev-services')]]"
|
||||
on-click='menuClicked'></paper-icon-button>
|
||||
<paper-icon-button
|
||||
icon='mdi:code-tags' data-panel='dev-state'
|
||||
alt="[[localize('panel.dev-states')]]" title="[[localize('panel.dev-states')]]"
|
||||
on-click='menuClicked'></paper-icon-button>
|
||||
<paper-icon-button
|
||||
icon='mdi:radio-tower' data-panel='dev-event'
|
||||
alt="[[localize('panel.dev-events')]]" title="[[localize('panel.dev-events')]]"
|
||||
on-click='menuClicked'></paper-icon-button>
|
||||
<paper-icon-button
|
||||
icon='mdi:file-xml' data-panel='dev-template'
|
||||
alt="[[localize('panel.dev-templates')]]" title="[[localize('panel.dev-templates')]]"
|
||||
on-click='menuClicked'></paper-icon-button>
|
||||
<template is='dom-if' if='[[_mqttLoaded(hass)]]'>
|
||||
<paper-icon-button
|
||||
icon='mdi:altimeter' data-panel='dev-mqtt'
|
||||
alt="[[localize('panel.dev-mqtt')]]" title="[[localize('panel.dev-mqtt')]]"
|
||||
on-click='menuClicked'></paper-icon-button>
|
||||
<div class="dev-tools layout horizontal justified">
|
||||
<paper-icon-button icon="mdi:remote" data-panel="dev-service" alt="[[localize('panel.dev-services')]]" title="[[localize('panel.dev-services')]]" on-click="menuClicked"></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:code-tags" data-panel="dev-state" alt="[[localize('panel.dev-states')]]" title="[[localize('panel.dev-states')]]" on-click="menuClicked"></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:radio-tower" data-panel="dev-event" alt="[[localize('panel.dev-events')]]" title="[[localize('panel.dev-events')]]" on-click="menuClicked"></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:file-xml" data-panel="dev-template" alt="[[localize('panel.dev-templates')]]" title="[[localize('panel.dev-templates')]]" on-click="menuClicked"></paper-icon-button>
|
||||
<template is="dom-if" if="[[_mqttLoaded(hass)]]">
|
||||
<paper-icon-button icon="mdi:altimeter" data-panel="dev-mqtt" alt="[[localize('panel.dev-mqtt')]]" title="[[localize('panel.dev-mqtt')]]" on-click="menuClicked"></paper-icon-button>
|
||||
</template>
|
||||
<paper-icon-button
|
||||
icon='mdi:information-outline' data-panel='dev-info'
|
||||
alt="[[localize('panel.dev-info')]]" title="[[localize('panel.dev-info')]]"
|
||||
on-click='menuClicked'></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:information-outline" data-panel="dev-info" alt="[[localize('panel.dev-info')]]" title="[[localize('panel.dev-info')]]" on-click="menuClicked"></paper-icon-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
* @appliesMixin window.hassMixins.EventsMixin
|
||||
*/
|
||||
class HaSidebar extends
|
||||
window.hassMixins.LocalizeMixin(window.hassMixins.NavigateMixin(Polymer.Element)) {
|
||||
static get is() { return 'ha-sidebar'; }
|
||||
|
||||
static get properties() {
|
||||
@ -230,18 +211,23 @@ class HaSidebar extends
|
||||
}
|
||||
|
||||
menuClicked(ev) {
|
||||
var target = ev.target;
|
||||
var checks = 5;
|
||||
var attr = target.getAttribute('data-panel');
|
||||
|
||||
// find panel to select
|
||||
while (checks && !attr) {
|
||||
target = target.parentElement;
|
||||
attr = target.getAttribute('data-panel');
|
||||
checks--;
|
||||
// Selection made inside dom-repeat
|
||||
if (ev.model) {
|
||||
this.selectPanel(ev.model.item.component_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (checks) {
|
||||
let target = ev.target;
|
||||
let checks = 5;
|
||||
let attr;
|
||||
|
||||
do {
|
||||
attr = target.getAttribute('data-panel');
|
||||
target = target.parentElement;
|
||||
checks--;
|
||||
} while (checks > 0 && target !== null && !attr);
|
||||
|
||||
if (checks > 0 && target !== null) {
|
||||
this.selectPanel(attr);
|
||||
}
|
||||
}
|
||||
@ -268,4 +254,3 @@ class HaSidebar extends
|
||||
}
|
||||
|
||||
customElements.define(HaSidebar.is, HaSidebar);
|
||||
</script>
|
||||
@ -1,20 +1,16 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
import '../util/hass-mixins.js';
|
||||
|
||||
<dom-module id='ha-start-voice-button'>
|
||||
<template>
|
||||
<paper-icon-button
|
||||
icon="mdi:microphone" hidden$='[[!canListen]]'
|
||||
on-click="handleListenClick"
|
||||
></paper-icon-button>
|
||||
class HaStartVoiceButton extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<paper-icon-button icon="mdi:microphone" hidden\$="[[!canListen]]" on-click="handleListenClick"></paper-icon-button>
|
||||
`;
|
||||
}
|
||||
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaStartVoiceButton extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-start-voice-button'; }
|
||||
|
||||
static get properties() {
|
||||
@ -43,4 +39,3 @@ class HaStartVoiceButton extends window.hassMixins.EventsMixin(Polymer.Element)
|
||||
}
|
||||
|
||||
customElements.define(HaStartVoiceButton.is, HaStartVoiceButton);
|
||||
</script>
|
||||
@ -1,11 +1,13 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../bower_components/iron-icon/iron-icon.html'>
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='./ha-relative-time.html'>
|
||||
<link rel='import' href='../util/hass-util.html'>
|
||||
import '../util/hass-util.js';
|
||||
import './ha-relative-time.js';
|
||||
|
||||
<dom-module id='hassio-card-content'>
|
||||
<template>
|
||||
class HassioCardContent extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
iron-icon {
|
||||
margin-right: 16px;
|
||||
@ -41,23 +43,21 @@
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<iron-icon icon='[[icon]]' class$='[[iconClass]]' title='[[iconTitle]]'></iron-icon>
|
||||
<iron-icon icon="[[icon]]" class\$="[[iconClass]]" title="[[iconTitle]]"></iron-icon>
|
||||
<div>
|
||||
<div class='title'>[[title]]</div>
|
||||
<div class='addition'>
|
||||
<template is='dom-if' if='[[description]]'>
|
||||
<div class="title">[[title]]</div>
|
||||
<div class="addition">
|
||||
<template is="dom-if" if="[[description]]">
|
||||
[[description]]
|
||||
</template>
|
||||
<template is='dom-if' if='[[datetime]]'>
|
||||
<ha-relative-time class='addition' datetime='[[datetime]]'></ha-relative-time>
|
||||
<template is="dom-if" if="[[datetime]]">
|
||||
<ha-relative-time class="addition" datetime="[[datetime]]"></ha-relative-time>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HassioCardContent extends Polymer.Element {
|
||||
static get is() { return 'hassio-card-content'; }
|
||||
|
||||
static get properties() {
|
||||
@ -75,4 +75,3 @@ class HassioCardContent extends Polymer.Element {
|
||||
}
|
||||
}
|
||||
customElements.define(HassioCardContent.is, HassioCardContent);
|
||||
</script>
|
||||
@ -1,9 +1,12 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/polymer/lib/utils/debounce.html">
|
||||
<link rel="import" href="./entity/ha-chart-base.html">
|
||||
import '@polymer/polymer/lib/utils/debounce.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id='state-history-chart-line'>
|
||||
<template>
|
||||
import './entity/ha-chart-base.js';
|
||||
|
||||
class StateHistoryChartLine extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
@ -12,16 +15,10 @@
|
||||
transition: height 0.3s ease-in-out;
|
||||
}
|
||||
</style>
|
||||
<ha-chart-base
|
||||
id='chart'
|
||||
data="[[chartData]]"
|
||||
identifier="[[identifier]]"
|
||||
rendered="{{rendered}}"
|
||||
></ha-chart-base>
|
||||
</template>
|
||||
</dom-module>
|
||||
<script>
|
||||
class StateHistoryChartLine extends Polymer.Element {
|
||||
<ha-chart-base id="chart" data="[[chartData]]" identifier="[[identifier]]" rendered="{{rendered}}"></ha-chart-base>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'state-history-chart-line'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -299,4 +296,3 @@ class StateHistoryChartLine extends Polymer.Element {
|
||||
}
|
||||
}
|
||||
customElements.define(StateHistoryChartLine.is, StateHistoryChartLine);
|
||||
</script>
|
||||
@ -1,9 +1,12 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href="../../bower_components/polymer/lib/utils/debounce.html">
|
||||
<link rel='import' href='./entity/ha-chart-base.html'>
|
||||
import '@polymer/polymer/lib/utils/debounce.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<dom-module id='state-history-chart-timeline'>
|
||||
<template>
|
||||
import './entity/ha-chart-base.js';
|
||||
|
||||
class StateHistoryChartTimeline extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
@ -15,16 +18,10 @@
|
||||
}
|
||||
|
||||
</style>
|
||||
<ha-chart-base
|
||||
data="[[chartData]]"
|
||||
rendered="{{rendered}}"
|
||||
></ha-chart-base>
|
||||
</template>
|
||||
</dom-module>
|
||||
<script>
|
||||
'use strict';
|
||||
<ha-chart-base data="[[chartData]]" rendered="{{rendered}}"></ha-chart-base>
|
||||
`;
|
||||
}
|
||||
|
||||
class StateHistoryChartTimeline extends Polymer.Element {
|
||||
static get is() { return 'state-history-chart-timeline'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -195,5 +192,3 @@ class StateHistoryChartTimeline extends Polymer.Element {
|
||||
}
|
||||
}
|
||||
customElements.define(StateHistoryChartTimeline.is, StateHistoryChartTimeline);
|
||||
|
||||
</script>
|
||||
@ -1,11 +1,13 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-spinner/paper-spinner.html">
|
||||
import '@polymer/paper-spinner/paper-spinner.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="./state-history-chart-timeline.html">
|
||||
<link rel="import" href="./state-history-chart-line.html">
|
||||
import './state-history-chart-line.js';
|
||||
import './state-history-chart-timeline.js';
|
||||
|
||||
<dom-module id="state-history-charts">
|
||||
<template>
|
||||
class StateHistoryCharts extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
@ -18,36 +20,26 @@
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
</style>
|
||||
<template is='dom-if' class='info' if='[[_computeIsLoading(isLoadingData)]]'>
|
||||
<div class='info'>Loading state history...</div>
|
||||
<template is="dom-if" class="info" if="[[_computeIsLoading(isLoadingData)]]">
|
||||
<div class="info">Loading state history...</div>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' class='info' if='[[_computeIsEmpty(isLoadingData, historyData)]]'>
|
||||
<div class='info'>No state history found.</div>
|
||||
<template is="dom-if" class="info" if="[[_computeIsEmpty(isLoadingData, historyData)]]">
|
||||
<div class="info">No state history found.</div>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[historyData.timeline.length]]'>
|
||||
<state-history-chart-timeline
|
||||
data='[[historyData.timeline]]'
|
||||
end-time='[[_computeEndTime(endTime, upToNow, historyData)]]'
|
||||
no-single='[[noSingle]]'>
|
||||
<template is="dom-if" if="[[historyData.timeline.length]]">
|
||||
<state-history-chart-timeline data="[[historyData.timeline]]" end-time="[[_computeEndTime(endTime, upToNow, historyData)]]" no-single="[[noSingle]]">
|
||||
</state-history-chart-timeline>
|
||||
</template>
|
||||
|
||||
<template is='dom-repeat' items='[[historyData.line]]'>
|
||||
<state-history-chart-line
|
||||
unit='[[item.unit]]'
|
||||
data='[[item.data]]'
|
||||
identifier='[[item.identifier]]'
|
||||
is-single-device='[[_computeIsSingleLineChart(item.data, noSingle)]]'
|
||||
end-time='[[_computeEndTime(endTime, upToNow, historyData)]]'>
|
||||
<template is="dom-repeat" items="[[historyData.line]]">
|
||||
<state-history-chart-line unit="[[item.unit]]" data="[[item.data]]" identifier="[[item.identifier]]" is-single-device="[[_computeIsSingleLineChart(item.data, noSingle)]]" end-time="[[_computeEndTime(endTime, upToNow, historyData)]]">
|
||||
</state-history-chart-line>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class StateHistoryCharts extends Polymer.Element {
|
||||
static get is() { return 'state-history-charts'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -91,4 +83,3 @@ class StateHistoryCharts extends Polymer.Element {
|
||||
}
|
||||
}
|
||||
customElements.define(StateHistoryCharts.is, StateHistoryCharts);
|
||||
</script>
|
||||
@ -1,10 +1,9 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import { timeOut } from '@polymer/polymer/lib/utils/async.js';
|
||||
import { Debouncer } from '@polymer/polymer/lib/utils/debounce.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||
<link rel='import' href='../../src/util/hass-util.html'>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
import '../util/hass-mixins.js';
|
||||
import '../util/hass-util.js';
|
||||
|
||||
{
|
||||
const RECENT_THRESHOLD = 60000; // 1 minute
|
||||
@ -99,7 +98,7 @@
|
||||
/*
|
||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||
*/
|
||||
class HaStateHistoryData extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||
class HaStateHistoryData extends window.hassMixins.LocalizeMixin(PolymerElement) {
|
||||
static get is() { return 'ha-state-history-data'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -165,9 +164,9 @@
|
||||
}
|
||||
|
||||
filterChangedDebouncer(...args) {
|
||||
this._debounceFilterChanged = Polymer.Debouncer.debounce(
|
||||
this._debounceFilterChanged = Debouncer.debounce(
|
||||
this._debounceFilterChanged,
|
||||
Polymer.Async.timeOut.after(0),
|
||||
timeOut.after(0),
|
||||
() => {
|
||||
this.filterChanged(...args);
|
||||
}
|
||||
@ -385,4 +384,3 @@
|
||||
}
|
||||
customElements.define(HaStateHistoryData.is, HaStateHistoryData);
|
||||
}
|
||||
</script>
|
||||
@ -1,15 +1,16 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import '@polymer/paper-dialog-behavior/paper-dialog-shared-styles.js';
|
||||
import '@polymer/paper-dialog-scrollable/paper-dialog-scrollable.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/paper-dialog-behavior/paper-dialog-shared-styles.html">
|
||||
<link rel="import" href="../../bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html">
|
||||
<link rel='import' href='../util/hass-mixins.html'>
|
||||
<link rel='import' href='../resources/ha-style.html'>
|
||||
import '../resources/ha-style.js';
|
||||
import '../util/hass-mixins.js';
|
||||
import './more-info/more-info-controls.js';
|
||||
import './more-info/more-info-settings.js';
|
||||
|
||||
<link rel='import' href='./more-info/more-info-controls.html'>
|
||||
<link rel='import' href='./more-info/more-info-settings.html'>
|
||||
|
||||
<dom-module id="ha-more-info-dialog">
|
||||
<template>
|
||||
class HaMoreInfoDialog extends window.hassMixins.DialogMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style-dialog paper-dialog-shared-styles">
|
||||
:host {
|
||||
font-size: 14px;
|
||||
@ -64,29 +65,15 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<template is='dom-if' if='[[!_page]]'>
|
||||
<more-info-controls
|
||||
class='no-padding'
|
||||
hass='[[hass]]'
|
||||
state-obj='[[stateObj]]'
|
||||
dialog-element='[[_dialogElement]]'
|
||||
can-configure='[[_registryInfo]]'
|
||||
large='{{large}}'
|
||||
></more-info-controls>
|
||||
<template is="dom-if" if="[[!_page]]">
|
||||
<more-info-controls class="no-padding" hass="[[hass]]" state-obj="[[stateObj]]" dialog-element="[[_dialogElement]]" can-configure="[[_registryInfo]]" large="{{large}}"></more-info-controls>
|
||||
</template>
|
||||
<template is='dom-if' if='[[_equals(_page, "settings")]]'>
|
||||
<more-info-settings
|
||||
class='no-padding'
|
||||
hass='[[hass]]'
|
||||
state-obj='[[stateObj]]'
|
||||
registry-info='{{_registryInfo}}'
|
||||
></more-info-settings>
|
||||
<template is="dom-if" if="[[_equals(_page, "settings")]]">
|
||||
<more-info-settings class="no-padding" hass="[[hass]]" state-obj="[[stateObj]]" registry-info="{{_registryInfo}}"></more-info-settings>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class HaMoreInfoDialog extends window.hassMixins.DialogMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-more-info-dialog'; }
|
||||
static get properties() {
|
||||
return {
|
||||
@ -176,4 +163,3 @@ class HaMoreInfoDialog extends window.hassMixins.DialogMixin(Polymer.Element) {
|
||||
}
|
||||
}
|
||||
customElements.define(HaMoreInfoDialog.is, HaMoreInfoDialog);
|
||||
</script>
|
||||
@ -1,12 +1,12 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import '@polymer/paper-dialog-behavior/paper-dialog-shared-styles.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../bower_components/paper-dialog-behavior/paper-dialog-shared-styles.html">
|
||||
|
||||
<link rel="import" href="../../bower_components/iron-icon/iron-icon.html">
|
||||
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
|
||||
<dom-module id="ha-voice-command-dialog">
|
||||
<template>
|
||||
class HaVoiceCommandDialog extends window.hassMixins.DialogMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="paper-dialog-shared-styles">
|
||||
iron-icon {
|
||||
margin-right: 8px;
|
||||
@ -105,34 +105,28 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class='content'>
|
||||
<div class='messages' id='messages'>
|
||||
<template is='dom-repeat' items='[[_conversation]]' as='message'>
|
||||
<div class$='[[_computeMessageClasses(message)]]'>[[message.text]]</div>
|
||||
<div class="content">
|
||||
<div class="messages" id="messages">
|
||||
<template is="dom-repeat" items="[[_conversation]]" as="message">
|
||||
<div class\$="[[_computeMessageClasses(message)]]">[[message.text]]</div>
|
||||
</template>
|
||||
</div>
|
||||
<template is='dom-if' if='[[results]]'>
|
||||
<div class='messages'>
|
||||
<div class='message user'>
|
||||
<template is="dom-if" if="[[results]]">
|
||||
<div class="messages">
|
||||
<div class="message user">
|
||||
<span>{{results.final}}</span>
|
||||
<span class='interimTranscript'>[[results.interim]]</span>
|
||||
<span class="interimTranscript">[[results.interim]]</span>
|
||||
…
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class='icon' hidden$="[[results]]">
|
||||
<paper-icon-button
|
||||
icon="mdi:text-to-speech"
|
||||
on-click='startListening'
|
||||
></paper-icon-button>
|
||||
<div class="icon" hidden\$="[[results]]">
|
||||
<paper-icon-button icon="mdi:text-to-speech" on-click="startListening"></paper-icon-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
`;
|
||||
}
|
||||
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaVoiceCommandDialog extends window.hassMixins.DialogMixin(Polymer.Element) {
|
||||
static get is() { return 'ha-voice-command-dialog'; }
|
||||
|
||||
static get properties() {
|
||||
@ -249,4 +243,3 @@ class HaVoiceCommandDialog extends window.hassMixins.DialogMixin(Polymer.Element
|
||||
}
|
||||
|
||||
customElements.define(HaVoiceCommandDialog.is, HaVoiceCommandDialog);
|
||||
</script>
|
||||
@ -1,45 +1,27 @@
|
||||
<link rel='import' href='../../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href="../../../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../../../bower_components/paper-button/paper-button.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-input/paper-input.html'>
|
||||
import '../../../util/hass-mixins.js';
|
||||
|
||||
<link rel='import' href='../../../../src/util/hass-mixins.html'>
|
||||
|
||||
<dom-module id='more-info-alarm_control_panel'>
|
||||
<template>
|
||||
class MoreInfoAlarmControlPanel extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style is="custom-style" include="iron-flex"></style>
|
||||
|
||||
<div class='layout horizontal'>
|
||||
<paper-input
|
||||
label='code'
|
||||
value='{{enteredCode}}'
|
||||
pattern='[[codeFormat]]'
|
||||
type='password'
|
||||
hidden$='[[!codeFormat]]'
|
||||
disabled='[[!codeInputEnabled]]'
|
||||
></paper-input>
|
||||
<div class="layout horizontal">
|
||||
<paper-input label="code" value="{{enteredCode}}" pattern="[[codeFormat]]" type="password" hidden\$="[[!codeFormat]]" disabled="[[!codeInputEnabled]]"></paper-input>
|
||||
</div>
|
||||
<div class='layout horizontal'>
|
||||
<paper-button
|
||||
on-click='handleDisarmTap'
|
||||
hidden$='[[!disarmButtonVisible]]'
|
||||
disabled='[[!codeValid]]'
|
||||
>Disarm</paper-button>
|
||||
<paper-button
|
||||
on-click='handleHomeTap'
|
||||
hidden$='[[!armHomeButtonVisible]]'
|
||||
disabled=[[!codeValid]]>Arm Home</paper-button>
|
||||
<paper-button
|
||||
on-click='handleAwayTap'
|
||||
hidden$='[[!armAwayButtonVisible]]'
|
||||
disabled='[[!codeValid]]'>Arm Away</paper-button>
|
||||
<div class="layout horizontal">
|
||||
<paper-button on-click="handleDisarmTap" hidden\$="[[!disarmButtonVisible]]" disabled="[[!codeValid]]">Disarm</paper-button>
|
||||
<paper-button on-click="handleHomeTap" hidden\$="[[!armHomeButtonVisible]]" disabled="[[!codeValid]]">Arm Home</paper-button>
|
||||
<paper-button on-click="handleAwayTap" hidden\$="[[!armAwayButtonVisible]]" disabled="[[!codeValid]]">Arm Away</paper-button>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class MoreInfoAlarmControlPanel extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'more-info-alarm_control_panel'; }
|
||||
|
||||
static get properties() {
|
||||
@ -138,4 +120,3 @@ class MoreInfoAlarmControlPanel extends window.hassMixins.EventsMixin(Polymer.El
|
||||
}
|
||||
|
||||
customElements.define(MoreInfoAlarmControlPanel.is, MoreInfoAlarmControlPanel);
|
||||
</script>
|
||||
@ -1,13 +1,13 @@
|
||||
<link rel="import" href="../../../../bower_components/polymer/polymer-element.html">
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
import '../../../components/ha-relative-time.js';
|
||||
|
||||
<link rel="import" href="../../../../bower_components/paper-button/paper-button.html">
|
||||
|
||||
<link rel="import" href="../../../components/ha-relative-time.html">
|
||||
|
||||
<dom-module id="more-info-automation">
|
||||
<template>
|
||||
class MoreInfoAutomation extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
paper-button {
|
||||
color: var(--primary-color);
|
||||
@ -22,13 +22,10 @@
|
||||
<ha-relative-time datetime="[[stateObj.attributes.last_triggered]]"></ha-relative-time>
|
||||
</p>
|
||||
|
||||
<paper-button on-click='handleTriggerTapped'>TRIGGER</paper-button>
|
||||
<paper-button on-click="handleTriggerTapped">TRIGGER</paper-button>
|
||||
`;
|
||||
}
|
||||
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class MoreInfoAutomation extends Polymer.Element {
|
||||
static get is() { return 'more-info-automation'; }
|
||||
|
||||
static get properties() {
|
||||
@ -51,4 +48,3 @@ class MoreInfoAutomation extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(MoreInfoAutomation.is, MoreInfoAutomation);
|
||||
</script>
|
||||
@ -1,9 +1,11 @@
|
||||
<link rel="import" href="../../../../bower_components/polymer/polymer-element.html">
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../../../src/util/hass-mixins.html'>
|
||||
import '../../../util/hass-mixins.js';
|
||||
|
||||
<dom-module id='more-info-camera'>
|
||||
<template>
|
||||
class MoreInfoCamera extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
max-width:640px;
|
||||
@ -14,13 +16,10 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<img class='camera-image' src="[[computeCameraImageUrl(hass, stateObj, isVisible)]]"
|
||||
on-load='imageLoaded' alt='[[computeStateName(stateObj)]]' />
|
||||
</template>
|
||||
</dom-module>
|
||||
<img class="camera-image" src="[[computeCameraImageUrl(hass, stateObj, isVisible)]]" on-load="imageLoaded" alt="[[computeStateName(stateObj)]]">
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class MoreInfoCamera extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'more-info-camera'; }
|
||||
|
||||
static get properties() {
|
||||
@ -71,4 +70,3 @@ class MoreInfoCamera extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(MoreInfoCamera.is, MoreInfoCamera);
|
||||
</script>
|
||||
@ -1,20 +1,20 @@
|
||||
<link rel='import' href='../../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href="../../../../bower_components/polymer/lib/utils/debounce.html">
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import '@polymer/paper-toggle-button/paper-toggle-button.js';
|
||||
import { timeOut } from '@polymer/polymer/lib/utils/async.js';
|
||||
import { Debouncer } from '@polymer/polymer/lib/utils/debounce.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
import '../../../components/ha-climate-control.js';
|
||||
import '../../../components/ha-paper-slider.js';
|
||||
import '../../../util/hass-mixins.js';
|
||||
|
||||
<link rel='import' href='../../../../bower_components/paper-listbox/paper-listbox.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-item/paper-item.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-toggle-button/paper-toggle-button.html'>
|
||||
|
||||
<link rel='import' href='../../../../src/util/hass-mixins.html'>
|
||||
|
||||
<link rel="import" href='../../../components/ha-climate-control.html'>
|
||||
<link rel="import" href='../../../components/ha-paper-slider.html'>
|
||||
|
||||
<dom-module id='more-info-climate'>
|
||||
<template>
|
||||
class MoreInfoClimate extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style is="custom-style" include="iron-flex"></style>
|
||||
<style>
|
||||
:host {
|
||||
@ -105,87 +105,52 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class$='[[computeClassNames(stateObj)]]'>
|
||||
<div class\$="[[computeClassNames(stateObj)]]">
|
||||
|
||||
<template is='dom-if' if='[[supportsOn(stateObj)]]'>
|
||||
<div class='container-on'>
|
||||
<div class='center horizontal layout single-row'>
|
||||
<div class='flex'>On / Off</div>
|
||||
<paper-toggle-button
|
||||
checked='[[onToggleChecked]]'
|
||||
on-change='onToggleChanged'>
|
||||
<template is="dom-if" if="[[supportsOn(stateObj)]]">
|
||||
<div class="container-on">
|
||||
<div class="center horizontal layout single-row">
|
||||
<div class="flex">On / Off</div>
|
||||
<paper-toggle-button checked="[[onToggleChecked]]" on-change="onToggleChanged">
|
||||
</paper-toggle-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class='container-temperature'>
|
||||
<div class$='[[stateObj.attributes.operation_mode]]'>
|
||||
<div hidden$='[[!supportsTemperatureControls(stateObj)]]'>Target
|
||||
<div class="container-temperature">
|
||||
<div class\$="[[stateObj.attributes.operation_mode]]">
|
||||
<div hidden\$="[[!supportsTemperatureControls(stateObj)]]">Target
|
||||
Temperature</div>
|
||||
<template is='dom-if' if='[[supportsTemperature(stateObj)]]'>
|
||||
<ha-climate-control
|
||||
value='[[stateObj.attributes.temperature]]'
|
||||
units='[[stateObj.attributes.unit_of_measurement]]'
|
||||
step='[[computeTemperatureStepSize(stateObj)]]'
|
||||
min='[[stateObj.attributes.min_temp]]'
|
||||
max='[[stateObj.attributes.max_temp]]'
|
||||
on-change='targetTemperatureChanged'
|
||||
>
|
||||
<template is="dom-if" if="[[supportsTemperature(stateObj)]]">
|
||||
<ha-climate-control value="[[stateObj.attributes.temperature]]" units="[[stateObj.attributes.unit_of_measurement]]" step="[[computeTemperatureStepSize(stateObj)]]" min="[[stateObj.attributes.min_temp]]" max="[[stateObj.attributes.max_temp]]" on-change="targetTemperatureChanged">
|
||||
</ha-climate-control>
|
||||
</template>
|
||||
<template is='dom-if' if='[[supportsTemperatureRange(stateObj)]]'>
|
||||
<ha-climate-control
|
||||
value='[[stateObj.attributes.target_temp_low]]'
|
||||
units='[[stateObj.attributes.unit_of_measurement]]'
|
||||
step='[[computeTemperatureStepSize(stateObj)]]'
|
||||
min='[[stateObj.attributes.min_temp]]'
|
||||
max='[[stateObj.attributes.target_temp_high]]'
|
||||
class='range-control-left'
|
||||
on-change='targetTemperatureLowChanged'
|
||||
>
|
||||
<template is="dom-if" if="[[supportsTemperatureRange(stateObj)]]">
|
||||
<ha-climate-control value="[[stateObj.attributes.target_temp_low]]" units="[[stateObj.attributes.unit_of_measurement]]" step="[[computeTemperatureStepSize(stateObj)]]" min="[[stateObj.attributes.min_temp]]" max="[[stateObj.attributes.target_temp_high]]" class="range-control-left" on-change="targetTemperatureLowChanged">
|
||||
</ha-climate-control>
|
||||
<ha-climate-control
|
||||
value='[[stateObj.attributes.target_temp_high]]'
|
||||
units='[[stateObj.attributes.unit_of_measurement]]'
|
||||
step='[[computeTemperatureStepSize(stateObj)]]'
|
||||
min='[[stateObj.attributes.target_temp_low]]'
|
||||
max='[[stateObj.attributes.max_temp]]'
|
||||
class='range-control-right'
|
||||
on-change='targetTemperatureHighChanged'
|
||||
>
|
||||
<ha-climate-control value="[[stateObj.attributes.target_temp_high]]" units="[[stateObj.attributes.unit_of_measurement]]" step="[[computeTemperatureStepSize(stateObj)]]" min="[[stateObj.attributes.target_temp_low]]" max="[[stateObj.attributes.max_temp]]" class="range-control-right" on-change="targetTemperatureHighChanged">
|
||||
</ha-climate-control>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template is='dom-if' if='[[supportsHumidity(stateObj)]]'>
|
||||
<div class='container-humidity'>
|
||||
<template is="dom-if" if="[[supportsHumidity(stateObj)]]">
|
||||
<div class="container-humidity">
|
||||
<div>Target Humidity</div>
|
||||
<div class="single-row">
|
||||
<div class="target-humidity">[[stateObj.attributes.humidity]] %</div>
|
||||
<ha-paper-slider
|
||||
class='humidity'
|
||||
min='[[stateObj.attributes.min_humidity]]'
|
||||
max='[[stateObj.attributes.max_humidity]]'
|
||||
secondary-progress='[[stateObj.attributes.max_humidity]]'
|
||||
step='1' pin
|
||||
value='[[stateObj.attributes.humidity]]'
|
||||
on-change='targetHumiditySliderChanged'
|
||||
ignore-bar-touch>
|
||||
<ha-paper-slider class="humidity" min="[[stateObj.attributes.min_humidity]]" max="[[stateObj.attributes.max_humidity]]" secondary-progress="[[stateObj.attributes.max_humidity]]" step="1" pin="" value="[[stateObj.attributes.humidity]]" on-change="targetHumiditySliderChanged" ignore-bar-touch="">
|
||||
</ha-paper-slider>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[supportsOperationMode(stateObj)]]'>
|
||||
<div class='container-operation_list'>
|
||||
<div class='controls'>
|
||||
<paper-dropdown-menu class='capitalize' label-float dynamic-align label='Operation'>
|
||||
<template is="dom-if" if="[[supportsOperationMode(stateObj)]]">
|
||||
<div class="container-operation_list">
|
||||
<div class="controls">
|
||||
<paper-dropdown-menu class="capitalize" label-float="" dynamic-align="" label="Operation">
|
||||
<paper-listbox slot="dropdown-content" selected="{{operationIndex}}">
|
||||
<template is='dom-repeat'
|
||||
items='[[stateObj.attributes.operation_list]]'
|
||||
on-dom-change='handleOperationListUpdate'>
|
||||
<template is="dom-repeat" items="[[stateObj.attributes.operation_list]]" on-dom-change="handleOperationListUpdate">
|
||||
<paper-item class="capitalize">[[item]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
@ -194,13 +159,11 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[supportsFanMode(stateObj)]]'>
|
||||
<div class='container-fan_list'>
|
||||
<paper-dropdown-menu label-float dynamic-align label='Fan Mode'>
|
||||
<template is="dom-if" if="[[supportsFanMode(stateObj)]]">
|
||||
<div class="container-fan_list">
|
||||
<paper-dropdown-menu label-float="" dynamic-align="" label="Fan Mode">
|
||||
<paper-listbox slot="dropdown-content" selected="{{fanIndex}}">
|
||||
<template is='dom-repeat'
|
||||
items='[[stateObj.attributes.fan_list]]'
|
||||
on-dom-change='handleFanListUpdate'>
|
||||
<template is="dom-repeat" items="[[stateObj.attributes.fan_list]]" on-dom-change="handleFanListUpdate">
|
||||
<paper-item>[[item]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
@ -208,13 +171,11 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[supportsSwingMode(stateObj)]]'>
|
||||
<div class='container-swing_list'>
|
||||
<paper-dropdown-menu label-float dynamic-align label='Swing Mode'>
|
||||
<template is="dom-if" if="[[supportsSwingMode(stateObj)]]">
|
||||
<div class="container-swing_list">
|
||||
<paper-dropdown-menu label-float="" dynamic-align="" label="Swing Mode">
|
||||
<paper-listbox slot="dropdown-content" selected="{{swingIndex}}">
|
||||
<template is='dom-repeat'
|
||||
items='[[stateObj.attributes.swing_list]]'
|
||||
on-dom-change='handleSwingListUpdate'>
|
||||
<template is="dom-repeat" items="[[stateObj.attributes.swing_list]]" on-dom-change="handleSwingListUpdate">
|
||||
<paper-item>[[item]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
@ -222,35 +183,29 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[supportsAwayMode(stateObj)]]'>
|
||||
<div class='container-away_mode'>
|
||||
<div class='center horizontal layout single-row'>
|
||||
<div class='flex'>Away Mode</div>
|
||||
<paper-toggle-button
|
||||
checked='[[awayToggleChecked]]'
|
||||
on-change='awayToggleChanged'>
|
||||
<template is="dom-if" if="[[supportsAwayMode(stateObj)]]">
|
||||
<div class="container-away_mode">
|
||||
<div class="center horizontal layout single-row">
|
||||
<div class="flex">Away Mode</div>
|
||||
<paper-toggle-button checked="[[awayToggleChecked]]" on-change="awayToggleChanged">
|
||||
</paper-toggle-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[supportsAuxHeat(stateObj)]]'>
|
||||
<div class='container-aux_heat'>
|
||||
<div class='center horizontal layout single-row'>
|
||||
<div class='flex'>Aux Heat</div>
|
||||
<paper-toggle-button
|
||||
checked='[[auxToggleChecked]]'
|
||||
on-change='auxToggleChanged'>
|
||||
<template is="dom-if" if="[[supportsAuxHeat(stateObj)]]">
|
||||
<div class="container-aux_heat">
|
||||
<div class="center horizontal layout single-row">
|
||||
<div class="flex">Aux Heat</div>
|
||||
<paper-toggle-button checked="[[auxToggleChecked]]" on-change="auxToggleChanged">
|
||||
</paper-toggle-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class MoreInfoClimate extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'more-info-climate'; }
|
||||
|
||||
static get properties() {
|
||||
@ -297,9 +252,9 @@ class MoreInfoClimate extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
if (oldVal) {
|
||||
this._debouncer = Polymer.Debouncer.debounce(
|
||||
this._debouncer = Debouncer.debounce(
|
||||
this._debouncer,
|
||||
Polymer.Async.timeOut.after(500),
|
||||
timeOut.after(500),
|
||||
() => {
|
||||
this.fire('iron-resize');
|
||||
}
|
||||
@ -504,4 +459,3 @@ class MoreInfoClimate extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(MoreInfoClimate.is, MoreInfoClimate);
|
||||
</script>
|
||||
@ -1,14 +1,16 @@
|
||||
<link rel='import' href='../../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href="../../../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
<link rel='import' href='../../../../bower_components/iron-input/iron-input.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-spinner/paper-spinner.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-button/paper-button.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-input/paper-input.html'>
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import '@polymer/iron-input/iron-input.js';
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import '@polymer/paper-spinner/paper-spinner.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../../components/ha-markdown.html'>
|
||||
import '../../../components/ha-markdown.js';
|
||||
|
||||
<dom-module id='more-info-configurator'>
|
||||
<template>
|
||||
class MoreInfoConfigurator extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style is="custom-style" include="iron-flex"></style>
|
||||
<style>
|
||||
p {
|
||||
@ -47,33 +49,21 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class='layout vertical'>
|
||||
<template is='dom-if' if='[[isConfigurable]]'>
|
||||
<ha-markdown content='[[stateObj.attributes.description]]'></ha-markdown>
|
||||
<div class="layout vertical">
|
||||
<template is="dom-if" if="[[isConfigurable]]">
|
||||
<ha-markdown content="[[stateObj.attributes.description]]"></ha-markdown>
|
||||
|
||||
<p class='error' hidden$='[[!stateObj.attributes.errors]]'>
|
||||
<p class="error" hidden\$="[[!stateObj.attributes.errors]]">
|
||||
[[stateObj.attributes.errors]]
|
||||
</p>
|
||||
|
||||
<template is='dom-repeat' items='[[stateObj.attributes.fields]]'>
|
||||
<paper-input
|
||||
label='[[item.name]]'
|
||||
name='[[item.id]]'
|
||||
type='[[item.type]]'
|
||||
on-change='fieldChanged'
|
||||
></paper-input>
|
||||
<template is="dom-repeat" items="[[stateObj.attributes.fields]]">
|
||||
<paper-input label="[[item.name]]" name="[[item.id]]" type="[[item.type]]" on-change="fieldChanged"></paper-input>
|
||||
</template>
|
||||
|
||||
<p class='submit' hidden$='[[!stateObj.attributes.submit_caption]]'>
|
||||
<paper-button
|
||||
raised
|
||||
disabled='[[isConfiguring]]'
|
||||
on-click='submitClicked'
|
||||
>
|
||||
<paper-spinner
|
||||
active='[[isConfiguring]]'
|
||||
hidden='[[!isConfiguring]]'
|
||||
alt='Configuring'></paper-spinner>
|
||||
<p class="submit" hidden\$="[[!stateObj.attributes.submit_caption]]">
|
||||
<paper-button raised="" disabled="[[isConfiguring]]" on-click="submitClicked">
|
||||
<paper-spinner active="[[isConfiguring]]" hidden="[[!isConfiguring]]" alt="Configuring"></paper-spinner>
|
||||
[[stateObj.attributes.submit_caption]]
|
||||
</paper-button>
|
||||
|
||||
@ -81,11 +71,9 @@
|
||||
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class MoreInfoConfigurator extends Polymer.Element {
|
||||
static get is() { return 'more-info-configurator'; }
|
||||
|
||||
static get properties() {
|
||||
@ -145,4 +133,3 @@ class MoreInfoConfigurator extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(MoreInfoConfigurator.is, MoreInfoConfigurator);
|
||||
</script>
|
||||
@ -1,27 +1,26 @@
|
||||
<link rel='import' href='../../../../bower_components/polymer/polymer-element.html'>
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='more-info-alarm_control_panel.html'>
|
||||
<link rel='import' href='more-info-automation.html'>
|
||||
<link rel='import' href='more-info-camera.html'>
|
||||
<link rel='import' href='more-info-climate.html'>
|
||||
<link rel='import' href='more-info-configurator.html'>
|
||||
<link rel='import' href='more-info-cover.html'>
|
||||
<link rel='import' href='more-info-default.html'>
|
||||
<link rel='import' href='more-info-fan.html'>
|
||||
<link rel='import' href='more-info-history_graph.html'>
|
||||
<link rel='import' href='more-info-group.html'>
|
||||
<link rel='import' href='more-info-light.html'>
|
||||
<link rel='import' href='more-info-lock.html'>
|
||||
<link rel='import' href='more-info-media_player.html'>
|
||||
<link rel='import' href='more-info-script.html'>
|
||||
<link rel='import' href='more-info-sun.html'>
|
||||
<link rel='import' href='more-info-updater.html'>
|
||||
<link rel='import' href='more-info-vacuum.html'>
|
||||
<link rel='import' href='more-info-input_datetime.html'>
|
||||
<link rel='import' href='more-info-weather.html'>
|
||||
import './more-info-alarm_control_panel.js';
|
||||
import './more-info-automation.js';
|
||||
import './more-info-camera.js';
|
||||
import './more-info-climate.js';
|
||||
import './more-info-configurator.js';
|
||||
import './more-info-cover.js';
|
||||
import './more-info-default.js';
|
||||
import './more-info-fan.js';
|
||||
import './more-info-group.js';
|
||||
import './more-info-history_graph.js';
|
||||
import './more-info-input_datetime.js';
|
||||
import './more-info-light.js';
|
||||
import './more-info-lock.js';
|
||||
import './more-info-media_player.js';
|
||||
import './more-info-script.js';
|
||||
import './more-info-sun.js';
|
||||
import './more-info-updater.js';
|
||||
import './more-info-vacuum.js';
|
||||
import './more-info-weather.js';
|
||||
|
||||
<script>
|
||||
class MoreInfoContent extends Polymer.Element {
|
||||
class MoreInfoContent extends PolymerElement {
|
||||
static get is() { return 'more-info-content'; }
|
||||
|
||||
static get properties() {
|
||||
@ -69,4 +68,3 @@ class MoreInfoContent extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(MoreInfoContent.is, MoreInfoContent);
|
||||
</script>
|
||||
@ -1,14 +1,19 @@
|
||||
<link rel='import' href='../../../../bower_components/polymer/polymer-element.html'>
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
<link rel="import" href="../../../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
import '../../../components/ha-cover-tilt-controls.js';
|
||||
import '../../../components/ha-paper-slider.js';
|
||||
import '../../../util/cover-model.js';
|
||||
|
||||
<link rel="import" href='../../../components/ha-paper-slider.html'>
|
||||
<link rel='import' href='../../../util/cover-model.html'>
|
||||
<link rel='import' href='../../../components/ha-cover-tilt-controls.html'>
|
||||
|
||||
<dom-module id='more-info-cover'>
|
||||
<template>
|
||||
{
|
||||
const FEATURE_CLASS_NAMES = {
|
||||
128: 'has-set_tilt_position',
|
||||
};
|
||||
class MoreInfoCover extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style is="custom-style" include="iron-flex"></style>
|
||||
<style>
|
||||
.current_position, .tilt {
|
||||
@ -26,44 +31,26 @@
|
||||
visibility: hidden !important;
|
||||
}
|
||||
</style>
|
||||
<div class$='[[computeClassNames(stateObj)]]'>
|
||||
<div class\$="[[computeClassNames(stateObj)]]">
|
||||
|
||||
<div class='current_position'>
|
||||
<div class="current_position">
|
||||
<div>Position</div>
|
||||
<ha-paper-slider
|
||||
min='0' max='100'
|
||||
value='{{coverPositionSliderValue}}'
|
||||
step='1' pin
|
||||
disabled='[[!entityObj.supportsSetPosition]]'
|
||||
on-change='coverPositionSliderChanged'
|
||||
ignore-bar-touch></ha-paper-slider>
|
||||
<ha-paper-slider min="0" max="100" value="{{coverPositionSliderValue}}" step="1" pin="" disabled="[[!entityObj.supportsSetPosition]]" on-change="coverPositionSliderChanged" ignore-bar-touch=""></ha-paper-slider>
|
||||
</div>
|
||||
|
||||
<div class='tilt'>
|
||||
<div class="tilt">
|
||||
<div>Tilt position</div>
|
||||
<div>
|
||||
<ha-cover-tilt-controls hidden$="[[entityObj.isTiltOnly]]" hass="[[hass]]" state-obj="[[stateObj]]">
|
||||
<ha-cover-tilt-controls hidden\$="[[entityObj.isTiltOnly]]" hass="[[hass]]" state-obj="[[stateObj]]">
|
||||
</ha-cover-tilt-controls>
|
||||
</div>
|
||||
<ha-paper-slider
|
||||
min='0' max='100'
|
||||
value='{{coverTiltPositionSliderValue}}'
|
||||
step='1' pin
|
||||
disabled='[[!entityObj.supportsSetTiltPosition]]'
|
||||
on-change='coverTiltPositionSliderChanged'
|
||||
ignore-bar-touch></ha-paper-slider>
|
||||
<ha-paper-slider min="0" max="100" value="{{coverTiltPositionSliderValue}}" step="1" pin="" disabled="[[!entityObj.supportsSetTiltPosition]]" on-change="coverTiltPositionSliderChanged" ignore-bar-touch=""></ha-paper-slider>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
{
|
||||
const FEATURE_CLASS_NAMES = {
|
||||
128: 'has-set_tilt_position',
|
||||
};
|
||||
class MoreInfoCover extends Polymer.Element {
|
||||
static get is() { return 'more-info-cover'; }
|
||||
|
||||
static get properties() {
|
||||
@ -125,4 +112,3 @@
|
||||
|
||||
customElements.define(MoreInfoCover.is, MoreInfoCover);
|
||||
}
|
||||
</script>
|
||||
@ -1,25 +0,0 @@
|
||||
<link rel="import" href="../../../../bower_components/polymer/polymer-element.html">
|
||||
|
||||
<link rel="import" href="../../../components/ha-attributes.html">
|
||||
|
||||
<dom-module id="more-info-default">
|
||||
<template>
|
||||
<ha-attributes state-obj="[[stateObj]]"></ha-attributes>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class MoreInfoDefault extends Polymer.Element {
|
||||
static get is() { return 'more-info-default'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
stateObj: {
|
||||
type: Object,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(MoreInfoDefault.is, MoreInfoDefault);
|
||||
</script>
|
||||
24
src/dialogs/more-info/controls/more-info-default.js
Normal file
24
src/dialogs/more-info/controls/more-info-default.js
Normal file
@ -0,0 +1,24 @@
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../../../components/ha-attributes.js';
|
||||
|
||||
class MoreInfoDefault extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<ha-attributes state-obj="[[stateObj]]"></ha-attributes>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'more-info-default'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
stateObj: {
|
||||
type: Object,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(MoreInfoDefault.is, MoreInfoDefault);
|
||||
@ -1,19 +1,19 @@
|
||||
<link rel='import' href='../../../../bower_components/polymer/polymer-element.html'>
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import '@polymer/paper-toggle-button/paper-toggle-button.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../../../bower_components/iron-flex-layout/iron-flex-layout-classes.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-listbox/paper-listbox.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-item/paper-item.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-toggle-button/paper-toggle-button.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-icon-button/paper-icon-button.html'>
|
||||
import '../../../components/ha-attributes.js';
|
||||
import '../../../util/hass-mixins.js';
|
||||
|
||||
<link rel='import' href='../../../../src/util/hass-mixins.html'>
|
||||
|
||||
<link rel="import" href="../../../components/ha-attributes.html">
|
||||
|
||||
<dom-module id='more-info-fan'>
|
||||
<template>
|
||||
<style is='custom-style' include='iron-flex'></style>
|
||||
class MoreInfoFan extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style is="custom-style" include="iron-flex"></style>
|
||||
<style>
|
||||
.container-speed_list,
|
||||
.container-direction,
|
||||
@ -36,48 +36,39 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class$='[[computeClassNames(stateObj)]]'>
|
||||
<div class\$="[[computeClassNames(stateObj)]]">
|
||||
|
||||
<div class="container-speed_list">
|
||||
<paper-dropdown-menu label-float dynamic-align label='Speed'>
|
||||
<paper-listbox slot="dropdown-content" selected='{{speedIndex}}'>
|
||||
<template is='dom-repeat'
|
||||
items='[[stateObj.attributes.speed_list]]'>
|
||||
<paper-dropdown-menu label-float="" dynamic-align="" label="Speed">
|
||||
<paper-listbox slot="dropdown-content" selected="{{speedIndex}}">
|
||||
<template is="dom-repeat" items="[[stateObj.attributes.speed_list]]">
|
||||
<paper-item>[[item]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</div>
|
||||
|
||||
<div class='container-oscillating'>
|
||||
<div class='center horizontal layout single-row'>
|
||||
<div class='flex'>Oscillate</div>
|
||||
<paper-toggle-button
|
||||
checked='[[oscillationToggleChecked]]'
|
||||
on-change='oscillationToggleChanged'>
|
||||
<div class="container-oscillating">
|
||||
<div class="center horizontal layout single-row">
|
||||
<div class="flex">Oscillate</div>
|
||||
<paper-toggle-button checked="[[oscillationToggleChecked]]" on-change="oscillationToggleChanged">
|
||||
</paper-toggle-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='container-direction'>
|
||||
<div class='direction'>
|
||||
<div class="container-direction">
|
||||
<div class="direction">
|
||||
<div>Direction</div>
|
||||
<paper-icon-button icon='mdi:rotate-left'
|
||||
on-click='onDirectionLeft' title='Left'
|
||||
disabled='[[computeIsRotatingLeft(stateObj)]]'></paper-icon-button>
|
||||
<paper-icon-button icon='mdi:rotate-right'
|
||||
on-click='onDirectionRight' title='Right'
|
||||
disabled='[[computeIsRotatingRight(stateObj)]]'></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:rotate-left" on-click="onDirectionLeft" title="Left" disabled="[[computeIsRotatingLeft(stateObj)]]"></paper-icon-button>
|
||||
<paper-icon-button icon="mdi:rotate-right" on-click="onDirectionRight" title="Right" disabled="[[computeIsRotatingRight(stateObj)]]"></paper-icon-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ha-attributes state-obj="[[stateObj]]" extra-filters="speed,speed_list,oscillating,direction"></ha-attributes>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class MoreInfoFan extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'more-info-fan'; }
|
||||
|
||||
static get properties() {
|
||||
@ -173,4 +164,3 @@ class MoreInfoFan extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
}
|
||||
|
||||
customElements.define(MoreInfoFan.is, MoreInfoFan);
|
||||
</script>
|
||||
@ -1,9 +1,12 @@
|
||||
<link rel="import" href="../../../../bower_components/polymer/polymer-element.html">
|
||||
import { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../../state-summary/state-card-content.html">
|
||||
import '../../../state-summary/state-card-content.js';
|
||||
|
||||
<dom-module id="more-info-group">
|
||||
<template>
|
||||
class MoreInfoGroup extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
.child-card {
|
||||
margin-bottom: 8px;
|
||||
@ -15,16 +18,14 @@
|
||||
</style>
|
||||
|
||||
<div id="groupedControlDetails"></div>
|
||||
<template is='dom-repeat' items="[[states]]" as='state'>
|
||||
<div class='child-card'>
|
||||
<state-card-content state-obj="[[state]]" hass='[[hass]]'></state-card-content>
|
||||
<template is="dom-repeat" items="[[states]]" as="state">
|
||||
<div class="child-card">
|
||||
<state-card-content state-obj="[[state]]" hass="[[hass]]"></state-card-content>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class MoreInfoGroup extends Polymer.Element {
|
||||
static get is() { return 'more-info-group'; }
|
||||
|
||||
static get properties() {
|
||||
@ -90,7 +91,7 @@ class MoreInfoGroup extends Polymer.Element {
|
||||
}
|
||||
|
||||
if (!groupDomainStateObj) {
|
||||
const el = Polymer.dom(this.$.groupedControlDetails);
|
||||
const el = dom(this.$.groupedControlDetails);
|
||||
if (el.lastChild) {
|
||||
el.removeChild(el.lastChild);
|
||||
}
|
||||
@ -105,4 +106,3 @@ class MoreInfoGroup extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(MoreInfoGroup.is, MoreInfoGroup);
|
||||
</script>
|
||||
@ -1,35 +0,0 @@
|
||||
<link rel="import" href="../../../../bower_components/polymer/polymer-element.html">
|
||||
|
||||
<link rel="import" href="../../../cards/ha-history_graph-card.html">
|
||||
|
||||
<link rel="import" href="../../../components/ha-attributes.html">
|
||||
|
||||
<dom-module id="more-info-history_graph">
|
||||
<template>
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
</style>
|
||||
<ha-history_graph-card
|
||||
hass='[[hass]]'
|
||||
state-obj='[[stateObj]]'
|
||||
in-dialog
|
||||
></ha-graph-card>
|
||||
<ha-attributes state-obj="[[stateObj]]"></ha-attributes>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class MoreInfoHistoryGraph extends Polymer.Element {
|
||||
static get is() { return 'more-info-history_graph'; }
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
stateObj: Object,
|
||||
};
|
||||
}
|
||||
}
|
||||
customElements.define(MoreInfoHistoryGraph.is, MoreInfoHistoryGraph);
|
||||
</script>
|
||||
30
src/dialogs/more-info/controls/more-info-history_graph.js
Normal file
30
src/dialogs/more-info/controls/more-info-history_graph.js
Normal file
@ -0,0 +1,30 @@
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import '../../../cards/ha-history_graph-card.js';
|
||||
import '../../../components/ha-attributes.js';
|
||||
|
||||
class MoreInfoHistoryGraph extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
</style>
|
||||
<ha-history_graph-card hass="[[hass]]" state-obj="[[stateObj]]" in-dialog="">
|
||||
<ha-attributes state-obj="[[stateObj]]"></ha-attributes>
|
||||
</ha-history_graph-card>
|
||||
`;
|
||||
}
|
||||
|
||||
static get is() { return 'more-info-history_graph'; }
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
stateObj: Object,
|
||||
};
|
||||
}
|
||||
}
|
||||
customElements.define(MoreInfoHistoryGraph.is, MoreInfoHistoryGraph);
|
||||
@ -1,28 +1,34 @@
|
||||
<link rel="import" href="../../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
<link rel="import" href="../../../components/ha-relative-time.html">
|
||||
<link rel="import" href="../../../../bower_components/vaadin-date-picker/vaadin-date-picker.html">
|
||||
<link rel="import" href="../../../../bower_components/paper-time-input/paper-time-input.html">
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
import '@polymer/polymer/polymer-legacy.js';
|
||||
import '@vaadin/vaadin-date-picker/vaadin-date-picker.js';
|
||||
|
||||
<dom-module id="more-info-input_datetime">
|
||||
<template>
|
||||
<div class$='[[computeClassNames(stateObj)]]'>
|
||||
<template is="dom-if" if="[[doesHaveDate(stateObj)]]" restamp>
|
||||
import '../../../components/ha-relative-time.js';
|
||||
|
||||
class DatetimeInput extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<div class\$="[[computeClassNames(stateObj)]]">
|
||||
<template is="dom-if" if="[[doesHaveDate(stateObj)]]" restamp="">
|
||||
<div>
|
||||
<vaadin-date-picker id="dateInput" on-value-changed="dateTimeChanged" label="Date" value="{{selectedDate}}"></vaadin-date-picker>
|
||||
</div>
|
||||
</template>
|
||||
<template is="dom-if" if="[[doesHaveTime(stateObj)]]" restamp>
|
||||
<template is="dom-if" if="[[doesHaveTime(stateObj)]]" restamp="">
|
||||
<div>
|
||||
<paper-time-input hour="{{selectedHour}}" min="{{selectedMinute}}" format="24"></paper-time-input>
|
||||
<paper-input
|
||||
type='time'
|
||||
label='time'
|
||||
value='{{selectedTime}}'
|
||||
></paper-input>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class DatetimeInput extends Polymer.Element {
|
||||
static get is() {
|
||||
return 'more-info-input_datetime';
|
||||
}
|
||||
@ -43,18 +49,14 @@ class DatetimeInput extends Polymer.Element {
|
||||
observer: 'stateObjChanged',
|
||||
},
|
||||
|
||||
selectedHour: {
|
||||
type: Number,
|
||||
observer: 'dateTimeChanged',
|
||||
},
|
||||
|
||||
selectedMinute: {
|
||||
type: Number,
|
||||
observer: 'dateTimeChanged',
|
||||
},
|
||||
|
||||
selectedDate: {
|
||||
type: String,
|
||||
observer: 'dateTimeChanged',
|
||||
},
|
||||
|
||||
selectedTime: {
|
||||
type: String,
|
||||
observer: 'dateTimeChanged',
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -66,6 +68,9 @@ class DatetimeInput extends Polymer.Element {
|
||||
|
||||
/* Convert the date in the stateObj into a string useable by vaadin-date-picker */
|
||||
getDateString(stateObj) {
|
||||
if (stateObj.state === 'unknown') {
|
||||
return '';
|
||||
}
|
||||
var monthFiller;
|
||||
if (stateObj.attributes.month < 10) {
|
||||
monthFiller = '0';
|
||||
@ -91,31 +96,23 @@ class DatetimeInput extends Polymer.Element {
|
||||
return;
|
||||
}
|
||||
|
||||
var minuteFiller;
|
||||
var changed = false;
|
||||
let changed = false;
|
||||
|
||||
var serviceData = {
|
||||
const serviceData = {
|
||||
entity_id: this.stateObj.entity_id
|
||||
};
|
||||
|
||||
if (this.stateObj.attributes.has_time) {
|
||||
changed |= (parseInt(this.selectedMinute) !== this.stateObj.attributes.minute);
|
||||
changed |= (parseInt(this.selectedHour) !== this.stateObj.attributes.hour);
|
||||
|
||||
if (this.selectedMinute < 10) {
|
||||
minuteFiller = '0';
|
||||
} else {
|
||||
minuteFiller = '';
|
||||
}
|
||||
|
||||
var timeStr = this.selectedHour + ':' + minuteFiller + this.selectedMinute;
|
||||
|
||||
serviceData.time = timeStr;
|
||||
changed |= this.selectedTime !== `${this.stateObj.attributes.hour}:${this.stateObj.attributes.minute}`;
|
||||
serviceData.time = this.selectedTime;
|
||||
}
|
||||
|
||||
if (this.stateObj.attributes.has_date) {
|
||||
const dateInput = this.shadowRoot.querySelector('#dateInput');
|
||||
const dateValInput = new Date(dateInput.value);
|
||||
if (this.selectedDate.length === 0) {
|
||||
return; // Date was not set
|
||||
}
|
||||
|
||||
const dateValInput = new Date(this.selectedDate);
|
||||
const dateValState = new Date(
|
||||
this.stateObj.attributes.year,
|
||||
this.stateObj.attributes.month - 1,
|
||||
@ -124,10 +121,7 @@ class DatetimeInput extends Polymer.Element {
|
||||
|
||||
changed |= (dateValState !== dateValInput);
|
||||
|
||||
serviceData.date = dateInput.value;
|
||||
if (dateInput.value.length < 1) {
|
||||
return; // Date was not set
|
||||
}
|
||||
serviceData.date = this.selectedDate;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
@ -165,4 +159,3 @@ class DatetimeInput extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(DatetimeInput.is, DatetimeInput);
|
||||
</script>
|
||||
@ -1,18 +1,26 @@
|
||||
<link rel='import' href='../../../../bower_components/polymer/polymer-element.html'>
|
||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||
import '@polymer/paper-item/paper-item.js';
|
||||
import '@polymer/paper-listbox/paper-listbox.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel="import" href="../../../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
<link rel="import" href="../../../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
|
||||
<link rel="import" href="../../../../bower_components/paper-listbox/paper-listbox.html">
|
||||
<link rel="import" href="../../../../bower_components/paper-item/paper-item.html">
|
||||
import '../../../components/ha-attributes.js';
|
||||
import '../../../components/ha-color-picker.js';
|
||||
import '../../../components/ha-labeled-slider.js';
|
||||
import '../../../util/hass-mixins.js';
|
||||
|
||||
<link rel='import' href='../../../../src/util/hass-mixins.html'>
|
||||
|
||||
<link rel='import' href='../../../components/ha-labeled-slider.html'>
|
||||
<link rel='import' href='../../../components/ha-color-picker.html'>
|
||||
<link rel='import' href='../../../components/ha-attributes.html'>
|
||||
|
||||
<dom-module id='more-info-light'>
|
||||
<template>
|
||||
{
|
||||
const FEATURE_CLASS_NAMES = {
|
||||
1: 'has-brightness',
|
||||
2: 'has-color_temp',
|
||||
4: 'has-effect_list',
|
||||
16: 'has-color',
|
||||
128: 'has-white_value',
|
||||
};
|
||||
class MoreInfoLight extends window.hassMixins.EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style is="custom-style" include="iron-flex"></style>
|
||||
<style>
|
||||
.effect_list {
|
||||
@ -66,48 +74,27 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class$='[[computeClassNames(stateObj)]]'>
|
||||
<div class\$="[[computeClassNames(stateObj)]]">
|
||||
|
||||
<div class='control brightness'>
|
||||
<ha-labeled-slider
|
||||
caption='Brightness' icon='mdi:brightness-5' max='255'
|
||||
value='{{brightnessSliderValue}}'
|
||||
on-change='brightnessSliderChanged'
|
||||
ignore-bar-touch></ha-labeled-slider>
|
||||
<div class="control brightness">
|
||||
<ha-labeled-slider caption="Brightness" icon="mdi:brightness-5" max="255" value="{{brightnessSliderValue}}" on-change="brightnessSliderChanged" ignore-bar-touch=""></ha-labeled-slider>
|
||||
</div>
|
||||
|
||||
<div class='control color_temp'>
|
||||
<ha-labeled-slider
|
||||
caption='Color Temperature' icon='mdi:thermometer'
|
||||
min='[[stateObj.attributes.min_mireds]]' max='[[stateObj.attributes.max_mireds]]'
|
||||
value='{{ctSliderValue}}'
|
||||
on-change='ctSliderChanged'
|
||||
ignore-bar-touch></ha-labeled-slider>
|
||||
<div class="control color_temp">
|
||||
<ha-labeled-slider caption="Color Temperature" icon="mdi:thermometer" min="[[stateObj.attributes.min_mireds]]" max="[[stateObj.attributes.max_mireds]]" value="{{ctSliderValue}}" on-change="ctSliderChanged" ignore-bar-touch=""></ha-labeled-slider>
|
||||
</div>
|
||||
|
||||
<div class='control white_value'>
|
||||
<ha-labeled-slider
|
||||
caption='White Value' icon='mdi:file-word-box' max='255'
|
||||
value='{{wvSliderValue}}'
|
||||
on-change='wvSliderChanged'
|
||||
ignore-bar-touch></ha-labeled-slider>
|
||||
<div class="control white_value">
|
||||
<ha-labeled-slider caption="White Value" icon="mdi:file-word-box" max="255" value="{{wvSliderValue}}" on-change="wvSliderChanged" ignore-bar-touch=""></ha-labeled-slider>
|
||||
</div>
|
||||
|
||||
<ha-color-picker
|
||||
class='control color'
|
||||
on-colorselected='colorPicked'
|
||||
desired-hs-color='{{colorPickerColor}}'
|
||||
throttle='500'
|
||||
hue-segments='24'
|
||||
saturation-segments='8'
|
||||
>
|
||||
<ha-color-picker class="control color" on-colorselected="colorPicked" desired-hs-color="{{colorPickerColor}}" throttle="500" hue-segments="24" saturation-segments="8">
|
||||
</ha-color-picker>
|
||||
|
||||
<div class='control effect_list'>
|
||||
<paper-dropdown-menu label-float dynamic-align label='Effect'>
|
||||
<div class="control effect_list">
|
||||
<paper-dropdown-menu label-float="" dynamic-align="" label="Effect">
|
||||
<paper-listbox slot="dropdown-content" selected="{{effectIndex}}">
|
||||
<template is='dom-repeat'
|
||||
items='[[stateObj.attributes.effect_list]]'>
|
||||
<template is="dom-repeat" items="[[stateObj.attributes.effect_list]]">
|
||||
<paper-item>[[item]]</paper-item>
|
||||
</template>
|
||||
</paper-listbox>
|
||||
@ -116,19 +103,9 @@
|
||||
|
||||
<ha-attributes state-obj="[[stateObj]]" extra-filters="brightness,color_temp,white_value,effect_list,effect,hs_color,rgb_color,xy_color,min_mireds,max_mireds"></ha-attributes>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
{
|
||||
const FEATURE_CLASS_NAMES = {
|
||||
1: 'has-brightness',
|
||||
2: 'has-color_temp',
|
||||
4: 'has-effect_list',
|
||||
16: 'has-color',
|
||||
128: 'has-white_value',
|
||||
};
|
||||
class MoreInfoLight extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||
static get is() { return 'more-info-light'; }
|
||||
|
||||
static get properties() {
|
||||
@ -282,4 +259,3 @@
|
||||
|
||||
customElements.define(MoreInfoLight.is, MoreInfoLight);
|
||||
}
|
||||
</script>
|
||||
@ -1,28 +1,28 @@
|
||||
<link rel='import' href='../../../../bower_components/polymer/polymer-element.html'>
|
||||
import '@polymer/paper-button/paper-button.js';
|
||||
import '@polymer/paper-input/paper-input.js';
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
<link rel='import' href='../../../../bower_components/paper-button/paper-button.html'>
|
||||
<link rel='import' href='../../../../bower_components/paper-input/paper-input.html'>
|
||||
<link rel='import' href='../../../components/ha-attributes.html'>
|
||||
import '../../../components/ha-attributes.js';
|
||||
|
||||
<dom-module id='more-info-lock'>
|
||||
<template>
|
||||
class MoreInfoLock extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
paper-input {
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div hidden$='[[!stateObj.attributes.code_format]]'>
|
||||
<paper-input label='code' value='{{enteredCode}}' pattern='[[stateObj.attributes.code_format]]' type='password'></paper-input>
|
||||
<paper-button on-click='handleUnlockTap' hidden$='[[!isLocked]]'>Unlock</paper-button>
|
||||
<paper-button on-click='handleLockTap' hidden$=[[isLocked]]>Lock</paper-button>
|
||||
<div hidden\$="[[!stateObj.attributes.code_format]]">
|
||||
<paper-input label="code" value="{{enteredCode}}" pattern="[[stateObj.attributes.code_format]]" type="password"></paper-input>
|
||||
<paper-button on-click="handleUnlockTap" hidden\$="[[!isLocked]]">Unlock</paper-button>
|
||||
<paper-button on-click="handleLockTap" hidden\$="[[isLocked]]">Lock</paper-button>
|
||||
</div>
|
||||
<ha-attributes state-obj='[[stateObj]]' extra-filters='code_format'></ha-attributes>
|
||||
</template>
|
||||
</dom-module>
|
||||
<ha-attributes state-obj="[[stateObj]]" extra-filters="code_format"></ha-attributes>
|
||||
`;
|
||||
}
|
||||
|
||||
<script>
|
||||
class MoreInfoLock extends Polymer.Element {
|
||||
static get is() { return 'more-info-lock'; }
|
||||
|
||||
static get properties() {
|
||||
@ -65,4 +65,3 @@ class MoreInfoLock extends Polymer.Element {
|
||||
}
|
||||
|
||||
customElements.define(MoreInfoLock.is, MoreInfoLock);
|
||||
</script>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user