mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 23:36:36 +00:00
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>
|
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