mirror of
https://github.com/home-assistant/frontend.git
synced 2025-11-10 03:19:44 +00:00
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"extends": "airbnb-base",
|
"extends": ["airbnb-base", "prettier"],
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaFeatures": {
|
"ecmaFeatures": {
|
||||||
"jsx": true,
|
"jsx": true,
|
||||||
@@ -67,13 +67,11 @@
|
|||||||
"react/no-find-dom-node": 2,
|
"react/no-find-dom-node": 2,
|
||||||
"react/no-is-mounted": 2,
|
"react/no-is-mounted": 2,
|
||||||
"react/jsx-no-comment-textnodes": 2,
|
"react/jsx-no-comment-textnodes": 2,
|
||||||
"react/jsx-curly-spacing": 2,
|
|
||||||
"react/jsx-no-undef": 2,
|
"react/jsx-no-undef": 2,
|
||||||
"react/jsx-uses-react": 2,
|
"react/jsx-uses-react": 2,
|
||||||
"react/jsx-uses-vars": 2,
|
"react/jsx-uses-vars": 2,
|
||||||
"no-restricted-syntax": [0, "ForOfStatement"]
|
"no-restricted-syntax": [0, "ForOfStatement"],
|
||||||
|
"prettier/prettier": "error"
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": ["react", "prettier"]
|
||||||
"react"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
import JsYaml from 'js-yaml';
|
import JsYaml from "js-yaml";
|
||||||
|
|
||||||
import HomeAssistant from '../data/hass.js';
|
import HomeAssistant from "../data/hass.js";
|
||||||
import demoConfig from '../data/demo_config.js';
|
import demoConfig from "../data/demo_config.js";
|
||||||
import demoResources from '../data/demo_resources.js';
|
import demoResources from "../data/demo_resources.js";
|
||||||
import demoStates from '../data/demo_states.js';
|
import demoStates from "../data/demo_states.js";
|
||||||
import createCardElement from '../../../src/panels/lovelace/common/create-card-element.js';
|
import createCardElement from "../../../src/panels/lovelace/common/create-card-element.js";
|
||||||
|
|
||||||
class DemoCard extends PolymerElement {
|
class DemoCard extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -50,11 +50,11 @@ class DemoCard extends PolymerElement {
|
|||||||
return {
|
return {
|
||||||
hass: {
|
hass: {
|
||||||
type: Object,
|
type: Object,
|
||||||
observer: '_hassChanged',
|
observer: "_hassChanged",
|
||||||
},
|
},
|
||||||
config: {
|
config: {
|
||||||
type: Object,
|
type: Object,
|
||||||
observer: '_configChanged'
|
observer: "_configChanged",
|
||||||
},
|
},
|
||||||
showConfig: Boolean,
|
showConfig: Boolean,
|
||||||
};
|
};
|
||||||
@@ -74,7 +74,7 @@ class DemoCard extends PolymerElement {
|
|||||||
const hass = new HomeAssistant(demoStates);
|
const hass = new HomeAssistant(demoStates);
|
||||||
hass.config = demoConfig;
|
hass.config = demoConfig;
|
||||||
hass.resources = demoResources;
|
hass.resources = demoResources;
|
||||||
hass.language = 'en';
|
hass.language = "en";
|
||||||
hass.states = demoStates;
|
hass.states = demoStates;
|
||||||
el.hass = hass;
|
el.hass = hass;
|
||||||
}
|
}
|
||||||
@@ -92,4 +92,4 @@ class DemoCard extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-card', DemoCard);
|
customElements.define("demo-card", DemoCard);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
import "@polymer/app-layout/app-toolbar/app-toolbar.js";
|
||||||
import '@polymer/paper-toggle-button/paper-toggle-button.js';
|
import "@polymer/paper-toggle-button/paper-toggle-button.js";
|
||||||
|
|
||||||
import './demo-card.js';
|
import "./demo-card.js";
|
||||||
|
|
||||||
class DemoCards extends PolymerElement {
|
class DemoCards extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -50,9 +50,9 @@ class DemoCards extends PolymerElement {
|
|||||||
_showConfig: {
|
_showConfig: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false,
|
value: false,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-cards', DemoCards);
|
customElements.define("demo-cards", DemoCards);
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../../src/state-summary/state-card-content.js';
|
|
||||||
import '../../../src/dialogs/more-info/controls/more-info-content.js';
|
|
||||||
import '../../../src/components/ha-card.js';
|
|
||||||
|
|
||||||
|
import "../../../src/state-summary/state-card-content.js";
|
||||||
|
import "../../../src/dialogs/more-info/controls/more-info-content.js";
|
||||||
|
import "../../../src/components/ha-card.js";
|
||||||
|
|
||||||
class DemoMoreInfo extends PolymerElement {
|
class DemoMoreInfo extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -68,8 +67,8 @@ class DemoMoreInfo extends PolymerElement {
|
|||||||
showConfig: Boolean,
|
showConfig: Boolean,
|
||||||
_stateObj: {
|
_stateObj: {
|
||||||
type: Object,
|
type: Object,
|
||||||
computed: '_getState(entityId, hass.states)'
|
computed: "_getState(entityId, hass.states)",
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +81,7 @@ class DemoMoreInfo extends PolymerElement {
|
|||||||
// (it sucks, we will remove in the future)
|
// (it sucks, we will remove in the future)
|
||||||
const tmp = {};
|
const tmp = {};
|
||||||
Object.keys(stateObj).forEach((key) => {
|
Object.keys(stateObj).forEach((key) => {
|
||||||
if (key[0] !== '_') {
|
if (key[0] !== "_") {
|
||||||
tmp[key] = stateObj[key];
|
tmp[key] = stateObj[key];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -90,4 +89,4 @@ class DemoMoreInfo extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-more-info', DemoMoreInfo);
|
customElements.define("demo-more-info", DemoMoreInfo);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
import "@polymer/app-layout/app-toolbar/app-toolbar.js";
|
||||||
import '@polymer/paper-toggle-button/paper-toggle-button.js';
|
import "@polymer/paper-toggle-button/paper-toggle-button.js";
|
||||||
|
|
||||||
import './demo-more-info.js';
|
import "./demo-more-info.js";
|
||||||
|
|
||||||
class DemoMoreInfos extends PolymerElement {
|
class DemoMoreInfos extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -50,9 +50,9 @@ class DemoMoreInfos extends PolymerElement {
|
|||||||
_showConfig: {
|
_showConfig: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false,
|
value: false,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-more-infos', DemoMoreInfos);
|
customElements.define("demo-more-infos", DemoMoreInfos);
|
||||||
|
|||||||
@@ -4,172 +4,106 @@ export default {
|
|||||||
latitude: 51.5287352,
|
latitude: 51.5287352,
|
||||||
longitude: -0.381773,
|
longitude: -0.381773,
|
||||||
unit_system: {
|
unit_system: {
|
||||||
length: 'km',
|
length: "km",
|
||||||
mass: 'kg',
|
mass: "kg",
|
||||||
temperature: '°C',
|
temperature: "°C",
|
||||||
volume: 'L'
|
volume: "L",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
services: {
|
services: {
|
||||||
configurator: [
|
configurator: ["configure"],
|
||||||
'configure'
|
tts: ["demo_say", "clear_cache"],
|
||||||
],
|
|
||||||
tts: [
|
|
||||||
'demo_say',
|
|
||||||
'clear_cache'
|
|
||||||
],
|
|
||||||
cover: [
|
cover: [
|
||||||
'open_cover',
|
"open_cover",
|
||||||
'close_cover',
|
"close_cover",
|
||||||
'open_cover_tilt',
|
"open_cover_tilt",
|
||||||
'close_cover_tilt',
|
"close_cover_tilt",
|
||||||
'set_cover_tilt_position',
|
"set_cover_tilt_position",
|
||||||
'set_cover_position',
|
"set_cover_position",
|
||||||
'stop_cover_tilt',
|
"stop_cover_tilt",
|
||||||
'stop_cover'
|
"stop_cover",
|
||||||
],
|
|
||||||
group: [
|
|
||||||
'set',
|
|
||||||
'reload',
|
|
||||||
'remove',
|
|
||||||
'set_visibility'
|
|
||||||
],
|
],
|
||||||
|
group: ["set", "reload", "remove", "set_visibility"],
|
||||||
alarm_control_panel: [
|
alarm_control_panel: [
|
||||||
'alarm_arm_night',
|
"alarm_arm_night",
|
||||||
'alarm_disarm',
|
"alarm_disarm",
|
||||||
'alarm_trigger',
|
"alarm_trigger",
|
||||||
'alarm_arm_home',
|
"alarm_arm_home",
|
||||||
'alarm_arm_away',
|
"alarm_arm_away",
|
||||||
'alarm_arm_custom_bypass'
|
"alarm_arm_custom_bypass",
|
||||||
],
|
|
||||||
conversation: [
|
|
||||||
'process'
|
|
||||||
],
|
|
||||||
notify: [
|
|
||||||
'demo_test_target_name',
|
|
||||||
'notify'
|
|
||||||
],
|
|
||||||
lock: [
|
|
||||||
'open',
|
|
||||||
'lock',
|
|
||||||
'unlock'
|
|
||||||
],
|
],
|
||||||
|
conversation: ["process"],
|
||||||
|
notify: ["demo_test_target_name", "notify"],
|
||||||
|
lock: ["open", "lock", "unlock"],
|
||||||
input_select: [
|
input_select: [
|
||||||
'select_previous',
|
"select_previous",
|
||||||
'set_options',
|
"set_options",
|
||||||
'select_next',
|
"select_next",
|
||||||
'select_option'
|
"select_option",
|
||||||
],
|
|
||||||
recorder: [
|
|
||||||
'purge'
|
|
||||||
],
|
|
||||||
persistent_notification: [
|
|
||||||
'create',
|
|
||||||
'dismiss'
|
|
||||||
],
|
|
||||||
timer: [
|
|
||||||
'pause',
|
|
||||||
'cancel',
|
|
||||||
'finish',
|
|
||||||
'start'
|
|
||||||
],
|
|
||||||
input_boolean: [
|
|
||||||
'turn_off',
|
|
||||||
'toggle',
|
|
||||||
'turn_on'
|
|
||||||
],
|
],
|
||||||
|
recorder: ["purge"],
|
||||||
|
persistent_notification: ["create", "dismiss"],
|
||||||
|
timer: ["pause", "cancel", "finish", "start"],
|
||||||
|
input_boolean: ["turn_off", "toggle", "turn_on"],
|
||||||
fan: [
|
fan: [
|
||||||
'set_speed',
|
"set_speed",
|
||||||
'turn_on',
|
"turn_on",
|
||||||
'turn_off',
|
"turn_off",
|
||||||
'set_direction',
|
"set_direction",
|
||||||
'oscillate',
|
"oscillate",
|
||||||
'toggle'
|
"toggle",
|
||||||
],
|
],
|
||||||
climate: [
|
climate: [
|
||||||
'set_humidity',
|
"set_humidity",
|
||||||
'set_operation_mode',
|
"set_operation_mode",
|
||||||
'set_aux_heat',
|
"set_aux_heat",
|
||||||
'turn_on',
|
"turn_on",
|
||||||
'set_hold_mode',
|
"set_hold_mode",
|
||||||
'set_away_mode',
|
"set_away_mode",
|
||||||
'turn_off',
|
"turn_off",
|
||||||
'set_fan_mode',
|
"set_fan_mode",
|
||||||
'set_temperature',
|
"set_temperature",
|
||||||
'set_swing_mode'
|
"set_swing_mode",
|
||||||
],
|
|
||||||
switch: [
|
|
||||||
'turn_off',
|
|
||||||
'toggle',
|
|
||||||
'turn_on'
|
|
||||||
],
|
|
||||||
script: [
|
|
||||||
'turn_off',
|
|
||||||
'demo',
|
|
||||||
'reload',
|
|
||||||
'toggle',
|
|
||||||
'turn_on'
|
|
||||||
],
|
|
||||||
scene: [
|
|
||||||
'turn_on'
|
|
||||||
],
|
|
||||||
system_log: [
|
|
||||||
'clear',
|
|
||||||
'write'
|
|
||||||
],
|
|
||||||
camera: [
|
|
||||||
'disable_motion_detection',
|
|
||||||
'enable_motion_detection',
|
|
||||||
'snapshot'
|
|
||||||
],
|
|
||||||
image_processing: [
|
|
||||||
'scan'
|
|
||||||
],
|
],
|
||||||
|
switch: ["turn_off", "toggle", "turn_on"],
|
||||||
|
script: ["turn_off", "demo", "reload", "toggle", "turn_on"],
|
||||||
|
scene: ["turn_on"],
|
||||||
|
system_log: ["clear", "write"],
|
||||||
|
camera: ["disable_motion_detection", "enable_motion_detection", "snapshot"],
|
||||||
|
image_processing: ["scan"],
|
||||||
media_player: [
|
media_player: [
|
||||||
'media_previous_track',
|
"media_previous_track",
|
||||||
'clear_playlist',
|
"clear_playlist",
|
||||||
'shuffle_set',
|
"shuffle_set",
|
||||||
'media_seek',
|
"media_seek",
|
||||||
'turn_on',
|
"turn_on",
|
||||||
'media_play_pause',
|
"media_play_pause",
|
||||||
'media_next_track',
|
"media_next_track",
|
||||||
'media_pause',
|
"media_pause",
|
||||||
'volume_down',
|
"volume_down",
|
||||||
'volume_set',
|
"volume_set",
|
||||||
'media_stop',
|
"media_stop",
|
||||||
'toggle',
|
"toggle",
|
||||||
'media_play',
|
"media_play",
|
||||||
'play_media',
|
"play_media",
|
||||||
'volume_mute',
|
"volume_mute",
|
||||||
'turn_off',
|
"turn_off",
|
||||||
'select_sound_mode',
|
"select_sound_mode",
|
||||||
'select_source',
|
"select_source",
|
||||||
'volume_up'
|
"volume_up",
|
||||||
],
|
|
||||||
input_number: [
|
|
||||||
'set_value',
|
|
||||||
'increment',
|
|
||||||
'decrement'
|
|
||||||
],
|
|
||||||
device_tracker: [
|
|
||||||
'see'
|
|
||||||
],
|
],
|
||||||
|
input_number: ["set_value", "increment", "decrement"],
|
||||||
|
device_tracker: ["see"],
|
||||||
homeassistant: [
|
homeassistant: [
|
||||||
'stop',
|
"stop",
|
||||||
'check_config',
|
"check_config",
|
||||||
'reload_core_config',
|
"reload_core_config",
|
||||||
'turn_on',
|
"turn_on",
|
||||||
'turn_off',
|
"turn_off",
|
||||||
'restart',
|
"restart",
|
||||||
'toggle'
|
"toggle",
|
||||||
],
|
],
|
||||||
light: [
|
light: ["turn_off", "toggle", "turn_on"],
|
||||||
'turn_off',
|
input_text: ["set_value"],
|
||||||
'toggle',
|
},
|
||||||
'turn_on'
|
|
||||||
],
|
|
||||||
input_text: [
|
|
||||||
'set_value'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,253 +1,264 @@
|
|||||||
export default {
|
export default {
|
||||||
en: {
|
en: {
|
||||||
'state.default.off': 'Off',
|
"state.default.off": "Off",
|
||||||
'state.default.on': 'On',
|
"state.default.on": "On",
|
||||||
'state.default.unknown': 'Unknown',
|
"state.default.unknown": "Unknown",
|
||||||
'state.default.unavailable': 'Unavailable',
|
"state.default.unavailable": "Unavailable",
|
||||||
'state.alarm_control_panel.armed': 'Armed',
|
"state.alarm_control_panel.armed": "Armed",
|
||||||
'state.alarm_control_panel.disarmed': 'Disarmed',
|
"state.alarm_control_panel.disarmed": "Disarmed",
|
||||||
'state.alarm_control_panel.armed_home': 'Armed home',
|
"state.alarm_control_panel.armed_home": "Armed home",
|
||||||
'state.alarm_control_panel.armed_away': 'Armed away',
|
"state.alarm_control_panel.armed_away": "Armed away",
|
||||||
'state.alarm_control_panel.armed_night': 'Armed night',
|
"state.alarm_control_panel.armed_night": "Armed night",
|
||||||
'state.alarm_control_panel.armed_custom_bypass': 'Armed custom bypass',
|
"state.alarm_control_panel.armed_custom_bypass": "Armed custom bypass",
|
||||||
'state.alarm_control_panel.pending': 'Pending',
|
"state.alarm_control_panel.pending": "Pending",
|
||||||
'state.alarm_control_panel.arming': 'Arming',
|
"state.alarm_control_panel.arming": "Arming",
|
||||||
'state.alarm_control_panel.disarming': 'Disarming',
|
"state.alarm_control_panel.disarming": "Disarming",
|
||||||
'state.alarm_control_panel.triggered': 'Triggered',
|
"state.alarm_control_panel.triggered": "Triggered",
|
||||||
'state.automation.off': 'Off',
|
"state.automation.off": "Off",
|
||||||
'state.automation.on': 'On',
|
"state.automation.on": "On",
|
||||||
'state.binary_sensor.default.off': 'Off',
|
"state.binary_sensor.default.off": "Off",
|
||||||
'state.binary_sensor.default.on': 'On',
|
"state.binary_sensor.default.on": "On",
|
||||||
'state.binary_sensor.battery.off': 'Normal',
|
"state.binary_sensor.battery.off": "Normal",
|
||||||
'state.binary_sensor.battery.on': 'Low',
|
"state.binary_sensor.battery.on": "Low",
|
||||||
'state.binary_sensor.cold.off': 'Normal',
|
"state.binary_sensor.cold.off": "Normal",
|
||||||
'state.binary_sensor.cold.on': 'Cold',
|
"state.binary_sensor.cold.on": "Cold",
|
||||||
'state.binary_sensor.connectivity.off': 'Disconnected',
|
"state.binary_sensor.connectivity.off": "Disconnected",
|
||||||
'state.binary_sensor.connectivity.on': 'Connected',
|
"state.binary_sensor.connectivity.on": "Connected",
|
||||||
'state.binary_sensor.door.off': 'Closed',
|
"state.binary_sensor.door.off": "Closed",
|
||||||
'state.binary_sensor.door.on': 'Open',
|
"state.binary_sensor.door.on": "Open",
|
||||||
'state.binary_sensor.garage_door.off': 'Closed',
|
"state.binary_sensor.garage_door.off": "Closed",
|
||||||
'state.binary_sensor.garage_door.on': 'Open',
|
"state.binary_sensor.garage_door.on": "Open",
|
||||||
'state.binary_sensor.gas.off': 'Clear',
|
"state.binary_sensor.gas.off": "Clear",
|
||||||
'state.binary_sensor.gas.on': 'Detected',
|
"state.binary_sensor.gas.on": "Detected",
|
||||||
'state.binary_sensor.heat.off': 'Normal',
|
"state.binary_sensor.heat.off": "Normal",
|
||||||
'state.binary_sensor.heat.on': 'Hot',
|
"state.binary_sensor.heat.on": "Hot",
|
||||||
'state.binary_sensor.lock.off': 'Locked',
|
"state.binary_sensor.lock.off": "Locked",
|
||||||
'state.binary_sensor.lock.on': 'Unlocked',
|
"state.binary_sensor.lock.on": "Unlocked",
|
||||||
'state.binary_sensor.moisture.off': 'Dry',
|
"state.binary_sensor.moisture.off": "Dry",
|
||||||
'state.binary_sensor.moisture.on': 'Wet',
|
"state.binary_sensor.moisture.on": "Wet",
|
||||||
'state.binary_sensor.motion.off': 'Clear',
|
"state.binary_sensor.motion.off": "Clear",
|
||||||
'state.binary_sensor.motion.on': 'Detected',
|
"state.binary_sensor.motion.on": "Detected",
|
||||||
'state.binary_sensor.occupancy.off': 'Clear',
|
"state.binary_sensor.occupancy.off": "Clear",
|
||||||
'state.binary_sensor.occupancy.on': 'Detected',
|
"state.binary_sensor.occupancy.on": "Detected",
|
||||||
'state.binary_sensor.opening.off': 'Closed',
|
"state.binary_sensor.opening.off": "Closed",
|
||||||
'state.binary_sensor.opening.on': 'Open',
|
"state.binary_sensor.opening.on": "Open",
|
||||||
'state.binary_sensor.presence.off': 'Away',
|
"state.binary_sensor.presence.off": "Away",
|
||||||
'state.binary_sensor.presence.on': 'Home',
|
"state.binary_sensor.presence.on": "Home",
|
||||||
'state.binary_sensor.problem.off': 'OK',
|
"state.binary_sensor.problem.off": "OK",
|
||||||
'state.binary_sensor.problem.on': 'Problem',
|
"state.binary_sensor.problem.on": "Problem",
|
||||||
'state.binary_sensor.safety.off': 'Safe',
|
"state.binary_sensor.safety.off": "Safe",
|
||||||
'state.binary_sensor.safety.on': 'Unsafe',
|
"state.binary_sensor.safety.on": "Unsafe",
|
||||||
'state.binary_sensor.smoke.off': 'Clear',
|
"state.binary_sensor.smoke.off": "Clear",
|
||||||
'state.binary_sensor.smoke.on': 'Detected',
|
"state.binary_sensor.smoke.on": "Detected",
|
||||||
'state.binary_sensor.sound.off': 'Clear',
|
"state.binary_sensor.sound.off": "Clear",
|
||||||
'state.binary_sensor.sound.on': 'Detected',
|
"state.binary_sensor.sound.on": "Detected",
|
||||||
'state.binary_sensor.vibration.off': 'Clear',
|
"state.binary_sensor.vibration.off": "Clear",
|
||||||
'state.binary_sensor.vibration.on': 'Detected',
|
"state.binary_sensor.vibration.on": "Detected",
|
||||||
'state.binary_sensor.window.off': 'Closed',
|
"state.binary_sensor.window.off": "Closed",
|
||||||
'state.binary_sensor.window.on': 'Open',
|
"state.binary_sensor.window.on": "Open",
|
||||||
'state.calendar.off': 'Off',
|
"state.calendar.off": "Off",
|
||||||
'state.calendar.on': 'On',
|
"state.calendar.on": "On",
|
||||||
'state.camera.recording': 'Recording',
|
"state.camera.recording": "Recording",
|
||||||
'state.camera.streaming': 'Streaming',
|
"state.camera.streaming": "Streaming",
|
||||||
'state.camera.idle': 'Idle',
|
"state.camera.idle": "Idle",
|
||||||
'state.climate.off': 'Off',
|
"state.climate.off": "Off",
|
||||||
'state.climate.on': 'On',
|
"state.climate.on": "On",
|
||||||
'state.climate.heat': 'Heat',
|
"state.climate.heat": "Heat",
|
||||||
'state.climate.cool': 'Cool',
|
"state.climate.cool": "Cool",
|
||||||
'state.climate.idle': 'Idle',
|
"state.climate.idle": "Idle",
|
||||||
'state.climate.auto': 'Auto',
|
"state.climate.auto": "Auto",
|
||||||
'state.climate.dry': 'Dry',
|
"state.climate.dry": "Dry",
|
||||||
'state.climate.fan_only': 'Fan only',
|
"state.climate.fan_only": "Fan only",
|
||||||
'state.climate.eco': 'Eco',
|
"state.climate.eco": "Eco",
|
||||||
'state.climate.electric': 'Electric',
|
"state.climate.electric": "Electric",
|
||||||
'state.climate.performance': 'Performance',
|
"state.climate.performance": "Performance",
|
||||||
'state.climate.high_demand': 'High demand',
|
"state.climate.high_demand": "High demand",
|
||||||
'state.climate.heat_pump': 'Heat pump',
|
"state.climate.heat_pump": "Heat pump",
|
||||||
'state.climate.gas': 'Gas',
|
"state.climate.gas": "Gas",
|
||||||
'state.configurator.configure': 'Configure',
|
"state.configurator.configure": "Configure",
|
||||||
'state.configurator.configured': 'Configured',
|
"state.configurator.configured": "Configured",
|
||||||
'state.cover.open': 'Open',
|
"state.cover.open": "Open",
|
||||||
'state.cover.opening': 'Opening',
|
"state.cover.opening": "Opening",
|
||||||
'state.cover.closed': 'Closed',
|
"state.cover.closed": "Closed",
|
||||||
'state.cover.closing': 'Closing',
|
"state.cover.closing": "Closing",
|
||||||
'state.cover.stopped': 'Stopped',
|
"state.cover.stopped": "Stopped",
|
||||||
'state.device_tracker.home': 'Home',
|
"state.device_tracker.home": "Home",
|
||||||
'state.device_tracker.not_home': 'Away',
|
"state.device_tracker.not_home": "Away",
|
||||||
'state.fan.off': 'Off',
|
"state.fan.off": "Off",
|
||||||
'state.fan.on': 'On',
|
"state.fan.on": "On",
|
||||||
'state.group.off': 'Off',
|
"state.group.off": "Off",
|
||||||
'state.group.on': 'On',
|
"state.group.on": "On",
|
||||||
'state.group.home': 'Home',
|
"state.group.home": "Home",
|
||||||
'state.group.not_home': 'Away',
|
"state.group.not_home": "Away",
|
||||||
'state.group.open': 'Open',
|
"state.group.open": "Open",
|
||||||
'state.group.opening': 'Opening',
|
"state.group.opening": "Opening",
|
||||||
'state.group.closed': 'Closed',
|
"state.group.closed": "Closed",
|
||||||
'state.group.closing': 'Closing',
|
"state.group.closing": "Closing",
|
||||||
'state.group.stopped': 'Stopped',
|
"state.group.stopped": "Stopped",
|
||||||
'state.group.locked': 'Locked',
|
"state.group.locked": "Locked",
|
||||||
'state.group.unlocked': 'Unlocked',
|
"state.group.unlocked": "Unlocked",
|
||||||
'state.group.ok': 'OK',
|
"state.group.ok": "OK",
|
||||||
'state.group.problem': 'Problem',
|
"state.group.problem": "Problem",
|
||||||
'state.input_boolean.off': 'Off',
|
"state.input_boolean.off": "Off",
|
||||||
'state.input_boolean.on': 'On',
|
"state.input_boolean.on": "On",
|
||||||
'state.light.off': 'Off',
|
"state.light.off": "Off",
|
||||||
'state.light.on': 'On',
|
"state.light.on": "On",
|
||||||
'state.lock.locked': 'Locked',
|
"state.lock.locked": "Locked",
|
||||||
'state.lock.unlocked': 'Unlocked',
|
"state.lock.unlocked": "Unlocked",
|
||||||
'state.media_player.off': 'Off',
|
"state.media_player.off": "Off",
|
||||||
'state.media_player.on': 'On',
|
"state.media_player.on": "On",
|
||||||
'state.media_player.playing': 'Playing',
|
"state.media_player.playing": "Playing",
|
||||||
'state.media_player.paused': 'Paused',
|
"state.media_player.paused": "Paused",
|
||||||
'state.media_player.idle': 'Idle',
|
"state.media_player.idle": "Idle",
|
||||||
'state.media_player.standby': 'Standby',
|
"state.media_player.standby": "Standby",
|
||||||
'state.plant.ok': 'OK',
|
"state.plant.ok": "OK",
|
||||||
'state.plant.problem': 'Problem',
|
"state.plant.problem": "Problem",
|
||||||
'state.remote.off': 'Off',
|
"state.remote.off": "Off",
|
||||||
'state.remote.on': 'On',
|
"state.remote.on": "On",
|
||||||
'state.scene.scening': 'Scening',
|
"state.scene.scening": "Scening",
|
||||||
'state.script.off': 'Off',
|
"state.script.off": "Off",
|
||||||
'state.script.on': 'On',
|
"state.script.on": "On",
|
||||||
'state.sensor.off': 'Off',
|
"state.sensor.off": "Off",
|
||||||
'state.sensor.on': 'On',
|
"state.sensor.on": "On",
|
||||||
'state.sun.above_horizon': 'Above horizon',
|
"state.sun.above_horizon": "Above horizon",
|
||||||
'state.sun.below_horizon': 'Below horizon',
|
"state.sun.below_horizon": "Below horizon",
|
||||||
'state.switch.off': 'Off',
|
"state.switch.off": "Off",
|
||||||
'state.switch.on': 'On',
|
"state.switch.on": "On",
|
||||||
'state.weather.clear-night': 'Clear, night',
|
"state.weather.clear-night": "Clear, night",
|
||||||
'state.weather.cloudy': 'Cloudy',
|
"state.weather.cloudy": "Cloudy",
|
||||||
'state.weather.fog': 'Fog',
|
"state.weather.fog": "Fog",
|
||||||
'state.weather.hail': 'Hail',
|
"state.weather.hail": "Hail",
|
||||||
'state.weather.lightning': 'Lightning',
|
"state.weather.lightning": "Lightning",
|
||||||
'state.weather.lightning-rainy': 'Lightning, rainy',
|
"state.weather.lightning-rainy": "Lightning, rainy",
|
||||||
'state.weather.partlycloudy': 'Partly cloudy',
|
"state.weather.partlycloudy": "Partly cloudy",
|
||||||
'state.weather.pouring': 'Pouring',
|
"state.weather.pouring": "Pouring",
|
||||||
'state.weather.rainy': 'Rainy',
|
"state.weather.rainy": "Rainy",
|
||||||
'state.weather.snowy': 'Snowy',
|
"state.weather.snowy": "Snowy",
|
||||||
'state.weather.snowy-rainy': 'Snowy, rainy',
|
"state.weather.snowy-rainy": "Snowy, rainy",
|
||||||
'state.weather.sunny': 'Sunny',
|
"state.weather.sunny": "Sunny",
|
||||||
'state.weather.windy': 'Windy',
|
"state.weather.windy": "Windy",
|
||||||
'state.weather.windy-variant': 'Windy',
|
"state.weather.windy-variant": "Windy",
|
||||||
'state.zwave.default.initializing': 'Initializing',
|
"state.zwave.default.initializing": "Initializing",
|
||||||
'state.zwave.default.dead': 'Dead',
|
"state.zwave.default.dead": "Dead",
|
||||||
'state.zwave.default.sleeping': 'Sleeping',
|
"state.zwave.default.sleeping": "Sleeping",
|
||||||
'state.zwave.default.ready': 'Ready',
|
"state.zwave.default.ready": "Ready",
|
||||||
'state.zwave.query_stage.initializing': 'Initializing ({query_stage})',
|
"state.zwave.query_stage.initializing": "Initializing ({query_stage})",
|
||||||
'state.zwave.query_stage.dead': 'Dead ({query_stage})',
|
"state.zwave.query_stage.dead": "Dead ({query_stage})",
|
||||||
'state_badge.default.unknown': 'Unk',
|
"state_badge.default.unknown": "Unk",
|
||||||
'state_badge.default.unavailable': 'Unavai',
|
"state_badge.default.unavailable": "Unavai",
|
||||||
'state_badge.alarm_control_panel.armed': 'Armed',
|
"state_badge.alarm_control_panel.armed": "Armed",
|
||||||
'state_badge.alarm_control_panel.disarmed': 'Disarm',
|
"state_badge.alarm_control_panel.disarmed": "Disarm",
|
||||||
'state_badge.alarm_control_panel.armed_home': 'Armed',
|
"state_badge.alarm_control_panel.armed_home": "Armed",
|
||||||
'state_badge.alarm_control_panel.armed_away': 'Armed',
|
"state_badge.alarm_control_panel.armed_away": "Armed",
|
||||||
'state_badge.alarm_control_panel.armed_night': 'Armed',
|
"state_badge.alarm_control_panel.armed_night": "Armed",
|
||||||
'state_badge.alarm_control_panel.armed_custom_bypass': 'Armed',
|
"state_badge.alarm_control_panel.armed_custom_bypass": "Armed",
|
||||||
'state_badge.alarm_control_panel.pending': 'Pend',
|
"state_badge.alarm_control_panel.pending": "Pend",
|
||||||
'state_badge.alarm_control_panel.arming': 'Arming',
|
"state_badge.alarm_control_panel.arming": "Arming",
|
||||||
'state_badge.alarm_control_panel.disarming': 'Disarm',
|
"state_badge.alarm_control_panel.disarming": "Disarm",
|
||||||
'state_badge.alarm_control_panel.triggered': 'Trig',
|
"state_badge.alarm_control_panel.triggered": "Trig",
|
||||||
'state_badge.device_tracker.home': 'Home',
|
"state_badge.device_tracker.home": "Home",
|
||||||
'state_badge.device_tracker.not_home': 'Away',
|
"state_badge.device_tracker.not_home": "Away",
|
||||||
'ui.card.alarm_control_panel.code': 'Code',
|
"ui.card.alarm_control_panel.code": "Code",
|
||||||
'ui.card.alarm_control_panel.clear_code': 'Clear',
|
"ui.card.alarm_control_panel.clear_code": "Clear",
|
||||||
'ui.card.alarm_control_panel.disarm': 'Disarm',
|
"ui.card.alarm_control_panel.disarm": "Disarm",
|
||||||
'ui.card.alarm_control_panel.arm_home': 'Arm home',
|
"ui.card.alarm_control_panel.arm_home": "Arm home",
|
||||||
'ui.card.alarm_control_panel.arm_away': 'Arm away',
|
"ui.card.alarm_control_panel.arm_away": "Arm away",
|
||||||
'ui.card.automation.last_triggered': 'Last triggered',
|
"ui.card.automation.last_triggered": "Last triggered",
|
||||||
'ui.card.automation.trigger': 'Trigger',
|
"ui.card.automation.trigger": "Trigger",
|
||||||
'ui.card.camera.not_available': 'Image not available',
|
"ui.card.camera.not_available": "Image not available",
|
||||||
'ui.card.climate.currently': 'Currently',
|
"ui.card.climate.currently": "Currently",
|
||||||
'ui.card.climate.on_off': 'On / off',
|
"ui.card.climate.on_off": "On / off",
|
||||||
'ui.card.climate.target_temperature': 'Target temperature',
|
"ui.card.climate.target_temperature": "Target temperature",
|
||||||
'ui.card.climate.target_humidity': 'Target humidity',
|
"ui.card.climate.target_humidity": "Target humidity",
|
||||||
'ui.card.climate.operation': 'Operation',
|
"ui.card.climate.operation": "Operation",
|
||||||
'ui.card.climate.fan_mode': 'Fan mode',
|
"ui.card.climate.fan_mode": "Fan mode",
|
||||||
'ui.card.climate.swing_mode': 'Swing mode',
|
"ui.card.climate.swing_mode": "Swing mode",
|
||||||
'ui.card.climate.away_mode': 'Away mode',
|
"ui.card.climate.away_mode": "Away mode",
|
||||||
'ui.card.climate.aux_heat': 'Aux heat',
|
"ui.card.climate.aux_heat": "Aux heat",
|
||||||
'ui.card.cover.position': 'Position',
|
"ui.card.cover.position": "Position",
|
||||||
'ui.card.cover.tilt_position': 'Tilt position',
|
"ui.card.cover.tilt_position": "Tilt position",
|
||||||
'ui.card.fan.speed': 'Speed',
|
"ui.card.fan.speed": "Speed",
|
||||||
'ui.card.fan.oscillate': 'Oscillate',
|
"ui.card.fan.oscillate": "Oscillate",
|
||||||
'ui.card.fan.direction': 'Direction',
|
"ui.card.fan.direction": "Direction",
|
||||||
'ui.card.light.brightness': 'Brightness',
|
"ui.card.light.brightness": "Brightness",
|
||||||
'ui.card.light.color_temperature': 'Color temperature',
|
"ui.card.light.color_temperature": "Color temperature",
|
||||||
'ui.card.light.white_value': 'White value',
|
"ui.card.light.white_value": "White value",
|
||||||
'ui.card.light.effect': 'Effect',
|
"ui.card.light.effect": "Effect",
|
||||||
'ui.card.lock.code': 'Code',
|
"ui.card.lock.code": "Code",
|
||||||
'ui.card.lock.lock': 'Lock',
|
"ui.card.lock.lock": "Lock",
|
||||||
'ui.card.lock.unlock': 'Unlock',
|
"ui.card.lock.unlock": "Unlock",
|
||||||
'ui.card.media_player.source': 'Source',
|
"ui.card.media_player.source": "Source",
|
||||||
'ui.card.media_player.sound_mode': 'Sound mode',
|
"ui.card.media_player.sound_mode": "Sound mode",
|
||||||
'ui.card.media_player.text_to_speak': 'Text to speak',
|
"ui.card.media_player.text_to_speak": "Text to speak",
|
||||||
'ui.card.persistent_notification.dismiss': 'Dismiss',
|
"ui.card.persistent_notification.dismiss": "Dismiss",
|
||||||
'ui.card.scene.activate': 'Activate',
|
"ui.card.scene.activate": "Activate",
|
||||||
'ui.card.script.execute': 'Execute',
|
"ui.card.script.execute": "Execute",
|
||||||
'ui.card.weather.attributes.air_pressure': 'Air pressure',
|
"ui.card.weather.attributes.air_pressure": "Air pressure",
|
||||||
'ui.card.weather.attributes.humidity': 'Humidity',
|
"ui.card.weather.attributes.humidity": "Humidity",
|
||||||
'ui.card.weather.attributes.temperature': 'Temperature',
|
"ui.card.weather.attributes.temperature": "Temperature",
|
||||||
'ui.card.weather.attributes.visibility': 'Visibility',
|
"ui.card.weather.attributes.visibility": "Visibility",
|
||||||
'ui.card.weather.attributes.wind_speed': 'Wind speed',
|
"ui.card.weather.attributes.wind_speed": "Wind speed",
|
||||||
'ui.card.weather.cardinal_direction.e': 'E',
|
"ui.card.weather.cardinal_direction.e": "E",
|
||||||
'ui.card.weather.cardinal_direction.ene': 'ENE',
|
"ui.card.weather.cardinal_direction.ene": "ENE",
|
||||||
'ui.card.weather.cardinal_direction.ese': 'ESE',
|
"ui.card.weather.cardinal_direction.ese": "ESE",
|
||||||
'ui.card.weather.cardinal_direction.n': 'N',
|
"ui.card.weather.cardinal_direction.n": "N",
|
||||||
'ui.card.weather.cardinal_direction.ne': 'NE',
|
"ui.card.weather.cardinal_direction.ne": "NE",
|
||||||
'ui.card.weather.cardinal_direction.nne': 'NNE',
|
"ui.card.weather.cardinal_direction.nne": "NNE",
|
||||||
'ui.card.weather.cardinal_direction.nw': 'NW',
|
"ui.card.weather.cardinal_direction.nw": "NW",
|
||||||
'ui.card.weather.cardinal_direction.nnw': 'NNW',
|
"ui.card.weather.cardinal_direction.nnw": "NNW",
|
||||||
'ui.card.weather.cardinal_direction.s': 'S',
|
"ui.card.weather.cardinal_direction.s": "S",
|
||||||
'ui.card.weather.cardinal_direction.se': 'SE',
|
"ui.card.weather.cardinal_direction.se": "SE",
|
||||||
'ui.card.weather.cardinal_direction.sse': 'SSE',
|
"ui.card.weather.cardinal_direction.sse": "SSE",
|
||||||
'ui.card.weather.cardinal_direction.ssw': 'SSW',
|
"ui.card.weather.cardinal_direction.ssw": "SSW",
|
||||||
'ui.card.weather.cardinal_direction.sw': 'SW',
|
"ui.card.weather.cardinal_direction.sw": "SW",
|
||||||
'ui.card.weather.cardinal_direction.w': 'W',
|
"ui.card.weather.cardinal_direction.w": "W",
|
||||||
'ui.card.weather.cardinal_direction.wnw': 'WNW',
|
"ui.card.weather.cardinal_direction.wnw": "WNW",
|
||||||
'ui.card.weather.cardinal_direction.wsw': 'WSW',
|
"ui.card.weather.cardinal_direction.wsw": "WSW",
|
||||||
'ui.card.weather.forecast': 'Forecast',
|
"ui.card.weather.forecast": "Forecast",
|
||||||
'ui.common.loading': 'Loading',
|
"ui.common.loading": "Loading",
|
||||||
'ui.common.cancel': 'Cancel',
|
"ui.common.cancel": "Cancel",
|
||||||
'ui.components.entity.entity-picker.entity': 'Entity',
|
"ui.components.entity.entity-picker.entity": "Entity",
|
||||||
'ui.components.relative_time.past': '{time} ago',
|
"ui.components.relative_time.past": "{time} ago",
|
||||||
'ui.components.relative_time.future': 'In {time}',
|
"ui.components.relative_time.future": "In {time}",
|
||||||
'ui.components.relative_time.never': 'Never',
|
"ui.components.relative_time.never": "Never",
|
||||||
'ui.components.relative_time.duration.second': '{count} {count, plural,\n one {second}\n other {seconds}\n}',
|
"ui.components.relative_time.duration.second":
|
||||||
'ui.components.relative_time.duration.minute': '{count} {count, plural,\n one {minute}\n other {minutes}\n}',
|
"{count} {count, plural,\n one {second}\n other {seconds}\n}",
|
||||||
'ui.components.relative_time.duration.hour': '{count} {count, plural,\n one {hour}\n other {hours}\n}',
|
"ui.components.relative_time.duration.minute":
|
||||||
'ui.components.relative_time.duration.day': '{count} {count, plural,\n one {day}\n other {days}\n}',
|
"{count} {count, plural,\n one {minute}\n other {minutes}\n}",
|
||||||
'ui.components.relative_time.duration.week': '{count} {count, plural,\n one {week}\n other {weeks}\n}',
|
"ui.components.relative_time.duration.hour":
|
||||||
'ui.components.history_charts.loading_history': 'Loading state history...',
|
"{count} {count, plural,\n one {hour}\n other {hours}\n}",
|
||||||
'ui.components.history_charts.no_history_found': 'No state history found.',
|
"ui.components.relative_time.duration.day":
|
||||||
'ui.components.service-picker.service': 'Service',
|
"{count} {count, plural,\n one {day}\n other {days}\n}",
|
||||||
'ui.dialogs.more_info_settings.save': 'Save',
|
"ui.components.relative_time.duration.week":
|
||||||
'ui.dialogs.more_info_settings.name': 'Name',
|
"{count} {count, plural,\n one {week}\n other {weeks}\n}",
|
||||||
'ui.duration.second': '{count} {count, plural,\n one {second}\n other {seconds}\n}',
|
"ui.components.history_charts.loading_history": "Loading state history...",
|
||||||
'ui.duration.minute': '{count} {count, plural,\n one {minute}\n other {minutes}\n}',
|
"ui.components.history_charts.no_history_found": "No state history found.",
|
||||||
'ui.duration.hour': '{count} {count, plural,\n one {hour}\n other {hours}\n}',
|
"ui.components.service-picker.service": "Service",
|
||||||
'ui.duration.day': '{count} {count, plural,\n one {day}\n other {days}\n}',
|
"ui.dialogs.more_info_settings.save": "Save",
|
||||||
'ui.duration.week': '{count} {count, plural,\n one {week}\n other {weeks}\n}',
|
"ui.dialogs.more_info_settings.name": "Name",
|
||||||
'ui.login-form.password': 'Password',
|
"ui.duration.second":
|
||||||
'ui.login-form.remember': 'Remember',
|
"{count} {count, plural,\n one {second}\n other {seconds}\n}",
|
||||||
'ui.login-form.log_in': 'Log in',
|
"ui.duration.minute":
|
||||||
'ui.notification_toast.entity_turned_on': 'Turned on {entity}.',
|
"{count} {count, plural,\n one {minute}\n other {minutes}\n}",
|
||||||
'ui.notification_toast.entity_turned_off': 'Turned off {entity}.',
|
"ui.duration.hour":
|
||||||
'ui.notification_toast.service_called': 'Service {service} called.',
|
"{count} {count, plural,\n one {hour}\n other {hours}\n}",
|
||||||
'ui.notification_toast.service_call_failed': 'Failed to call service {service}.',
|
"ui.duration.day":
|
||||||
'ui.notification_toast.connection_lost': 'Connection lost. Reconnecting…',
|
"{count} {count, plural,\n one {day}\n other {days}\n}",
|
||||||
'ui.sidebar.developer_tools': 'Developer tools',
|
"ui.duration.week":
|
||||||
'ui.sidebar.log_out': 'Log out',
|
"{count} {count, plural,\n one {week}\n other {weeks}\n}",
|
||||||
'attribute.weather.humidity': 'Humidity',
|
"ui.login-form.password": "Password",
|
||||||
'attribute.weather.visibility': 'Visibility',
|
"ui.login-form.remember": "Remember",
|
||||||
'attribute.weather.wind_speed': 'Wind speed',
|
"ui.login-form.log_in": "Log in",
|
||||||
}
|
"ui.notification_toast.entity_turned_on": "Turned on {entity}.",
|
||||||
|
"ui.notification_toast.entity_turned_off": "Turned off {entity}.",
|
||||||
|
"ui.notification_toast.service_called": "Service {service} called.",
|
||||||
|
"ui.notification_toast.service_call_failed":
|
||||||
|
"Failed to call service {service}.",
|
||||||
|
"ui.notification_toast.connection_lost": "Connection lost. Reconnecting…",
|
||||||
|
"ui.sidebar.developer_tools": "Developer tools",
|
||||||
|
"ui.sidebar.log_out": "Log out",
|
||||||
|
"attribute.weather.humidity": "Humidity",
|
||||||
|
"attribute.weather.visibility": "Visibility",
|
||||||
|
"attribute.weather.wind_speed": "Wind speed",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
const now = () => new Date().toISOString();
|
const now = () => new Date().toISOString();
|
||||||
const randomTime = () =>
|
const randomTime = () =>
|
||||||
new Date(new Date().getTime() - (Math.random() * 80 * 60 * 1000)).toISOString();
|
new Date(new Date().getTime() - Math.random() * 80 * 60 * 1000).toISOString();
|
||||||
|
|
||||||
/* eslint-disable no-unused-vars */
|
/* eslint-disable no-unused-vars */
|
||||||
|
|
||||||
@@ -18,19 +18,23 @@ export class Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async handleService(domain, service, data) {
|
async handleService(domain, service, data) {
|
||||||
console.log(`Unmocked service for ${this.entityId}: ${domain}/${service}`, data);
|
console.log(
|
||||||
|
`Unmocked service for ${this.entityId}: ${domain}/${service}`,
|
||||||
|
data
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
update(state, attributes = {}) {
|
update(state, attributes = {}) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.lastUpdated = now();
|
this.lastUpdated = now();
|
||||||
this.lastChanged = state === this.state ? this.lastChanged : this.lastUpdated;
|
this.lastChanged =
|
||||||
|
state === this.state ? this.lastChanged : this.lastUpdated;
|
||||||
this.attributes = Object.assign({}, this.baseAttributes, attributes);
|
this.attributes = Object.assign({}, this.baseAttributes, attributes);
|
||||||
|
|
||||||
console.log('update', this.entityId, this);
|
console.log("update", this.entityId, this);
|
||||||
|
|
||||||
this.hass.updateStates({
|
this.hass.updateStates({
|
||||||
[this.entityId]: this.toState()
|
[this.entityId]: this.toState(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,22 +51,25 @@ export class Entity {
|
|||||||
|
|
||||||
export class LightEntity extends Entity {
|
export class LightEntity extends Entity {
|
||||||
async handleService(domain, service, data) {
|
async handleService(domain, service, data) {
|
||||||
if (!['homeassistant', this.domain].includes(domain)) return;
|
if (!["homeassistant", this.domain].includes(domain)) return;
|
||||||
|
|
||||||
if (service === 'turn_on') {
|
if (service === "turn_on") {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
const { brightness, hs_color } = data;
|
const { brightness, hs_color } = data;
|
||||||
this.update('on', Object.assign(this.attributes, {
|
this.update(
|
||||||
|
"on",
|
||||||
|
Object.assign(this.attributes, {
|
||||||
brightness,
|
brightness,
|
||||||
hs_color,
|
hs_color,
|
||||||
}));
|
})
|
||||||
} else if (service === 'turn_off') {
|
);
|
||||||
this.update('off');
|
} else if (service === "turn_off") {
|
||||||
} else if (service === 'toggle') {
|
this.update("off");
|
||||||
if (this.state === 'on') {
|
} else if (service === "toggle") {
|
||||||
this.handleService(domain, 'turn_off', data);
|
if (this.state === "on") {
|
||||||
|
this.handleService(domain, "turn_off", data);
|
||||||
} else {
|
} else {
|
||||||
this.handleService(domain, 'turn_on', data);
|
this.handleService(domain, "turn_on", data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,10 +79,10 @@ export class LockEntity extends Entity {
|
|||||||
async handleService(domain, service, data) {
|
async handleService(domain, service, data) {
|
||||||
if (domain !== this.domain) return;
|
if (domain !== this.domain) return;
|
||||||
|
|
||||||
if (service === 'lock') {
|
if (service === "lock") {
|
||||||
this.update('locked');
|
this.update("locked");
|
||||||
} else if (service === 'unlock') {
|
} else if (service === "unlock") {
|
||||||
this.update('unlocked');
|
this.update("unlocked");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,24 +91,26 @@ export class CoverEntity extends Entity {
|
|||||||
async handleService(domain, service, data) {
|
async handleService(domain, service, data) {
|
||||||
if (domain !== this.domain) return;
|
if (domain !== this.domain) return;
|
||||||
|
|
||||||
if (service === 'open_cover') {
|
if (service === "open_cover") {
|
||||||
this.update('open');
|
this.update("open");
|
||||||
} else if (service === 'close_cover') {
|
} else if (service === "close_cover") {
|
||||||
this.update('closing');
|
this.update("closing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GroupEntity extends Entity {
|
export class GroupEntity extends Entity {
|
||||||
async handleService(domain, service, data) {
|
async handleService(domain, service, data) {
|
||||||
if (!['homeassistant', this.domain].includes(domain)) return;
|
if (!["homeassistant", this.domain].includes(domain)) return;
|
||||||
|
|
||||||
await Promise.all(this.attributes.entity_id.map((ent) => {
|
await Promise.all(
|
||||||
|
this.attributes.entity_id.map((ent) => {
|
||||||
const entity = this.hass.mockEntities[ent];
|
const entity = this.hass.mockEntities[ent];
|
||||||
return entity.handleService(entity.domain, service, data);
|
return entity.handleService(entity.domain, service, data);
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
this.update(service === 'turn_on' ? 'on' : 'off');
|
this.update(service === "turn_on" ? "on" : "off");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,15 +9,17 @@ export default class FakeHass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async callService(domain, service, serviceData) {
|
async callService(domain, service, serviceData) {
|
||||||
console.log('callService', { domain, service, serviceData });
|
console.log("callService", { domain, service, serviceData });
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
async callWS(msg) {
|
async callWS(msg) {
|
||||||
const callback = this._wsCommands[msg.type];
|
const callback = this._wsCommands[msg.type];
|
||||||
return callback ? callback(msg) : Promise.reject({
|
return callback
|
||||||
code: 'command_not_mocked',
|
? callback(msg)
|
||||||
message: 'This command is not implemented in the gallery.',
|
: Promise.reject({
|
||||||
|
code: "command_not_mocked",
|
||||||
|
message: "This command is not implemented in the gallery.",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,6 +31,6 @@ export default class FakeHass {
|
|||||||
} else {
|
} else {
|
||||||
console.error(`Unknown command: ${msg.type}`);
|
console.error(`Unknown command: ${msg.type}`);
|
||||||
}
|
}
|
||||||
console.log('sendWS', msg);
|
console.log("sendWS", msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import fireEvent from '../../../src/common/dom/fire_event.js';
|
import fireEvent from "../../../src/common/dom/fire_event.js";
|
||||||
|
|
||||||
import demoConfig from './demo_config.js';
|
import demoConfig from "./demo_config.js";
|
||||||
import demoResources from './demo_resources.js';
|
import demoResources from "./demo_resources.js";
|
||||||
|
|
||||||
const ensureArray = val => (Array.isArray(val) ? val : [val]);
|
const ensureArray = (val) => (Array.isArray(val) ? val : [val]);
|
||||||
|
|
||||||
export default (elements, { initialStates = {} } = {}) => {
|
export default (elements, { initialStates = {} } = {}) => {
|
||||||
elements = ensureArray(elements);
|
elements = ensureArray(elements);
|
||||||
@@ -14,13 +14,15 @@ export default (elements, { initialStates = {} } = {}) => {
|
|||||||
|
|
||||||
function updateHass(obj) {
|
function updateHass(obj) {
|
||||||
hass = Object.assign({}, hass, obj);
|
hass = Object.assign({}, hass, obj);
|
||||||
elements.forEach((el) => { el.hass = hass; });
|
elements.forEach((el) => {
|
||||||
|
el.hass = hass;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateHass({
|
updateHass({
|
||||||
// Home Assistant properties
|
// Home Assistant properties
|
||||||
config: demoConfig,
|
config: demoConfig,
|
||||||
language: 'en',
|
language: "en",
|
||||||
resources: demoResources,
|
resources: demoResources,
|
||||||
states: initialStates,
|
states: initialStates,
|
||||||
|
|
||||||
@@ -29,20 +31,27 @@ export default (elements, { initialStates = {} } = {}) => {
|
|||||||
|
|
||||||
// Home Assistant functions
|
// Home Assistant functions
|
||||||
async callService(domain, service, data) {
|
async callService(domain, service, data) {
|
||||||
fireEvent(elements[0], 'show-notification', { message: `Called service ${domain}/${service}` });
|
fireEvent(elements[0], "show-notification", {
|
||||||
|
message: `Called service ${domain}/${service}`,
|
||||||
|
});
|
||||||
if (data.entity_id) {
|
if (data.entity_id) {
|
||||||
await Promise.all(ensureArray(data.entity_id).map(ent =>
|
await Promise.all(
|
||||||
entities[ent].handleService(domain, service, data)));
|
ensureArray(data.entity_id).map((ent) =>
|
||||||
|
entities[ent].handleService(domain, service, data)
|
||||||
|
)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
console.log('unmocked callService', domain, service, data);
|
console.log("unmocked callService", domain, service, data);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async callWS(msg) {
|
async callWS(msg) {
|
||||||
const callback = wsCommands[msg.type];
|
const callback = wsCommands[msg.type];
|
||||||
return callback ? callback(msg) : Promise.reject({
|
return callback
|
||||||
code: 'command_not_mocked',
|
? callback(msg)
|
||||||
message: 'This command is not implemented in the gallery.',
|
: Promise.reject({
|
||||||
|
code: "command_not_mocked",
|
||||||
|
message: "This command is not implemented in the gallery.",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -54,7 +63,7 @@ export default (elements, { initialStates = {} } = {}) => {
|
|||||||
} else {
|
} else {
|
||||||
console.error(`Unknown command: ${msg.type}`);
|
console.error(`Unknown command: ${msg.type}`);
|
||||||
}
|
}
|
||||||
console.log('sendWS', msg);
|
console.log("sendWS", msg);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Mock functions
|
// Mock functions
|
||||||
@@ -72,7 +81,7 @@ export default (elements, { initialStates = {} } = {}) => {
|
|||||||
states[ent.entityId] = ent.toState();
|
states[ent.entityId] = ent.toState();
|
||||||
});
|
});
|
||||||
this.updateStates(states);
|
this.updateStates(states);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return hass;
|
return hass;
|
||||||
|
|||||||
@@ -1,28 +1,28 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import getEntity from '../data/entity.js';
|
import getEntity from "../data/entity.js";
|
||||||
import provideHass from '../data/provide_hass.js';
|
import provideHass from "../data/provide_hass.js";
|
||||||
import '../components/demo-cards.js';
|
import "../components/demo-cards.js";
|
||||||
|
|
||||||
const ENTITIES = [
|
const ENTITIES = [
|
||||||
getEntity('light', 'controller_1', 'on', {
|
getEntity("light", "controller_1", "on", {
|
||||||
friendly_name: 'Controller 1'
|
friendly_name: "Controller 1",
|
||||||
}),
|
}),
|
||||||
getEntity('light', 'controller_2', 'on', {
|
getEntity("light", "controller_2", "on", {
|
||||||
friendly_name: 'Controller 2'
|
friendly_name: "Controller 2",
|
||||||
}),
|
}),
|
||||||
getEntity('light', 'floor', 'off', {
|
getEntity("light", "floor", "off", {
|
||||||
friendly_name: 'Floor light'
|
friendly_name: "Floor light",
|
||||||
}),
|
}),
|
||||||
getEntity('light', 'kitchen', 'on', {
|
getEntity("light", "kitchen", "on", {
|
||||||
friendly_name: 'Kitchen light'
|
friendly_name: "Kitchen light",
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
{
|
{
|
||||||
heading: 'Controller',
|
heading: "Controller",
|
||||||
config: `
|
config: `
|
||||||
- type: entities
|
- type: entities
|
||||||
entities:
|
entities:
|
||||||
@@ -31,10 +31,10 @@ const CONFIGS = [
|
|||||||
- type: divider
|
- type: divider
|
||||||
- light.floor
|
- light.floor
|
||||||
- light.kitchen
|
- light.kitchen
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Demo',
|
heading: "Demo",
|
||||||
config: `
|
config: `
|
||||||
- type: conditional
|
- type: conditional
|
||||||
conditions:
|
conditions:
|
||||||
@@ -49,7 +49,7 @@ const CONFIGS = [
|
|||||||
- light.controller_2
|
- light.controller_2
|
||||||
- light.floor
|
- light.floor
|
||||||
- light.kitchen
|
- light.kitchen
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ class DemoConditional extends PolymerElement {
|
|||||||
return {
|
return {
|
||||||
_configs: {
|
_configs: {
|
||||||
type: Object,
|
type: Object,
|
||||||
value: CONFIGS
|
value: CONFIGS,
|
||||||
},
|
},
|
||||||
hass: Object,
|
hass: Object,
|
||||||
};
|
};
|
||||||
@@ -81,4 +81,4 @@ class DemoConditional extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-hui-conditional-card', DemoConditional);
|
customElements.define("demo-hui-conditional-card", DemoConditional);
|
||||||
|
|||||||
@@ -1,75 +1,70 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import getEntity from '../data/entity.js';
|
import getEntity from "../data/entity.js";
|
||||||
import provideHass from '../data/provide_hass.js';
|
import provideHass from "../data/provide_hass.js";
|
||||||
import '../components/demo-cards.js';
|
import "../components/demo-cards.js";
|
||||||
|
|
||||||
const ENTITIES = [
|
const ENTITIES = [
|
||||||
getEntity('light', 'bed_light', 'on', {
|
getEntity("light", "bed_light", "on", {
|
||||||
friendly_name: 'Bed Light'
|
friendly_name: "Bed Light",
|
||||||
}),
|
}),
|
||||||
getEntity('group', 'kitchen', 'on', {
|
getEntity("group", "kitchen", "on", {
|
||||||
entity_id: [
|
entity_id: ["light.bed_light"],
|
||||||
'light.bed_light',
|
|
||||||
],
|
|
||||||
order: 8,
|
order: 8,
|
||||||
friendly_name: 'Kitchen'
|
friendly_name: "Kitchen",
|
||||||
}),
|
}),
|
||||||
getEntity('lock', 'kitchen_door', 'locked', {
|
getEntity("lock", "kitchen_door", "locked", {
|
||||||
friendly_name: 'Kitchen Door'
|
friendly_name: "Kitchen Door",
|
||||||
}),
|
}),
|
||||||
getEntity('cover', 'kitchen_window', 'open', {
|
getEntity("cover", "kitchen_window", "open", {
|
||||||
friendly_name: 'Kitchen Window',
|
friendly_name: "Kitchen Window",
|
||||||
supported_features: 11
|
supported_features: 11,
|
||||||
}),
|
}),
|
||||||
getEntity('scene', 'romantic_lights', 'scening', {
|
getEntity("scene", "romantic_lights", "scening", {
|
||||||
entity_id: [
|
entity_id: ["light.bed_light", "light.ceiling_lights"],
|
||||||
'light.bed_light',
|
friendly_name: "Romantic lights",
|
||||||
'light.ceiling_lights'
|
|
||||||
],
|
|
||||||
friendly_name: 'Romantic lights'
|
|
||||||
}),
|
}),
|
||||||
getEntity('device_tracker', 'demo_paulus', 'home', {
|
getEntity("device_tracker", "demo_paulus", "home", {
|
||||||
source_type: 'gps',
|
source_type: "gps",
|
||||||
latitude: 32.877105,
|
latitude: 32.877105,
|
||||||
longitude: 117.232185,
|
longitude: 117.232185,
|
||||||
gps_accuracy: 91,
|
gps_accuracy: 91,
|
||||||
battery: 71,
|
battery: 71,
|
||||||
friendly_name: 'Paulus'
|
friendly_name: "Paulus",
|
||||||
}),
|
}),
|
||||||
getEntity('climate', 'ecobee', 'auto', {
|
getEntity("climate", "ecobee", "auto", {
|
||||||
current_temperature: 73,
|
current_temperature: 73,
|
||||||
min_temp: 45,
|
min_temp: 45,
|
||||||
max_temp: 95,
|
max_temp: 95,
|
||||||
temperature: null,
|
temperature: null,
|
||||||
target_temp_high: 75,
|
target_temp_high: 75,
|
||||||
target_temp_low: 70,
|
target_temp_low: 70,
|
||||||
fan_mode: 'Auto Low',
|
fan_mode: "Auto Low",
|
||||||
fan_list: ['On Low', 'On High', 'Auto Low', 'Auto High', 'Off'],
|
fan_list: ["On Low", "On High", "Auto Low", "Auto High", "Off"],
|
||||||
operation_mode: 'auto',
|
operation_mode: "auto",
|
||||||
operation_list: ['heat', 'cool', 'auto', 'off'],
|
operation_list: ["heat", "cool", "auto", "off"],
|
||||||
hold_mode: 'home',
|
hold_mode: "home",
|
||||||
swing_mode: 'Auto',
|
swing_mode: "Auto",
|
||||||
swing_list: ['Auto', '1', '2', '3', 'Off'],
|
swing_list: ["Auto", "1", "2", "3", "Off"],
|
||||||
unit_of_measurement: '°F',
|
unit_of_measurement: "°F",
|
||||||
friendly_name: 'Ecobee',
|
friendly_name: "Ecobee",
|
||||||
supported_features: 1014
|
supported_features: 1014,
|
||||||
}),
|
}),
|
||||||
getEntity('input_number', 'noise_allowance', 5, {
|
getEntity("input_number", "noise_allowance", 5, {
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 10,
|
max: 10,
|
||||||
step: 1,
|
step: 1,
|
||||||
mode: 'slider',
|
mode: "slider",
|
||||||
unit_of_measurement: 'dB',
|
unit_of_measurement: "dB",
|
||||||
friendly_name: 'Allowed Noise',
|
friendly_name: "Allowed Noise",
|
||||||
icon: 'mdi:bell-ring'
|
icon: "mdi:bell-ring",
|
||||||
})
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
{
|
{
|
||||||
heading: 'Basic',
|
heading: "Basic",
|
||||||
config: `
|
config: `
|
||||||
- type: entities
|
- type: entities
|
||||||
entities:
|
entities:
|
||||||
@@ -82,10 +77,10 @@ const CONFIGS = [
|
|||||||
- light.non_existing
|
- light.non_existing
|
||||||
- climate.ecobee
|
- climate.ecobee
|
||||||
- input_number.noise_allowance
|
- input_number.noise_allowance
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'With title, toggle-able',
|
heading: "With title, toggle-able",
|
||||||
config: `
|
config: `
|
||||||
- type: entities
|
- type: entities
|
||||||
entities:
|
entities:
|
||||||
@@ -98,10 +93,10 @@ const CONFIGS = [
|
|||||||
- climate.ecobee
|
- climate.ecobee
|
||||||
- input_number.noise_allowance
|
- input_number.noise_allowance
|
||||||
title: Random group
|
title: Random group
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'With title, toggle = false',
|
heading: "With title, toggle = false",
|
||||||
config: `
|
config: `
|
||||||
- type: entities
|
- type: entities
|
||||||
entities:
|
entities:
|
||||||
@@ -115,19 +110,19 @@ const CONFIGS = [
|
|||||||
- input_number.noise_allowance
|
- input_number.noise_allowance
|
||||||
title: Random group
|
title: Random group
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'With title, can\'t toggle',
|
heading: "With title, can't toggle",
|
||||||
config: `
|
config: `
|
||||||
- type: entities
|
- type: entities
|
||||||
entities:
|
entities:
|
||||||
- device_tracker.demo_paulus
|
- device_tracker.demo_paulus
|
||||||
title: Random group
|
title: Random group
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Custom name, secondary info, custom icon',
|
heading: "Custom name, secondary info, custom icon",
|
||||||
config: `
|
config: `
|
||||||
- type: entities
|
- type: entities
|
||||||
entities:
|
entities:
|
||||||
@@ -147,10 +142,10 @@ const CONFIGS = [
|
|||||||
- input_number.noise_allowance
|
- input_number.noise_allowance
|
||||||
title: Random group
|
title: Random group
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Special rows',
|
heading: "Special rows",
|
||||||
config: `
|
config: `
|
||||||
- type: entities
|
- type: entities
|
||||||
entities:
|
entities:
|
||||||
@@ -171,7 +166,7 @@ const CONFIGS = [
|
|||||||
height: 30px
|
height: 30px
|
||||||
margin: 4px 0
|
margin: 4px 0
|
||||||
background: center / contain url("/images/divider.png") no-repeat
|
background: center / contain url("/images/divider.png") no-repeat
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -190,7 +185,7 @@ class DemoEntities extends PolymerElement {
|
|||||||
return {
|
return {
|
||||||
_configs: {
|
_configs: {
|
||||||
type: Object,
|
type: Object,
|
||||||
value: CONFIGS
|
value: CONFIGS,
|
||||||
},
|
},
|
||||||
hass: Object,
|
hass: Object,
|
||||||
};
|
};
|
||||||
@@ -203,4 +198,4 @@ class DemoEntities extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-hui-entities-card', DemoEntities);
|
customElements.define("demo-hui-entities-card", DemoEntities);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/demo-cards.js';
|
import "../components/demo-cards.js";
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
{
|
{
|
||||||
heading: 'Basic',
|
heading: "Basic",
|
||||||
config: `
|
config: `
|
||||||
- type: entity-filter
|
- type: entity-filter
|
||||||
entities:
|
entities:
|
||||||
@@ -18,10 +18,10 @@ const CONFIGS = [
|
|||||||
state_filter:
|
state_filter:
|
||||||
- "on"
|
- "on"
|
||||||
- not_home
|
- not_home
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'With card config',
|
heading: "With card config",
|
||||||
config: `
|
config: `
|
||||||
- type: entity-filter
|
- type: entity-filter
|
||||||
entities:
|
entities:
|
||||||
@@ -37,10 +37,10 @@ const CONFIGS = [
|
|||||||
card:
|
card:
|
||||||
type: glance
|
type: glance
|
||||||
show_state: false
|
show_state: false
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Showing single entity conditionally',
|
heading: "Showing single entity conditionally",
|
||||||
config: `
|
config: `
|
||||||
- type: entity-filter
|
- type: entity-filter
|
||||||
entities:
|
entities:
|
||||||
@@ -50,8 +50,8 @@ const CONFIGS = [
|
|||||||
card:
|
card:
|
||||||
type: media-control
|
type: media-control
|
||||||
entity: media_player.lounge_room
|
entity: media_player.lounge_room
|
||||||
`
|
`,
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoFilter extends PolymerElement {
|
class DemoFilter extends PolymerElement {
|
||||||
@@ -65,10 +65,10 @@ class DemoFilter extends PolymerElement {
|
|||||||
return {
|
return {
|
||||||
_configs: {
|
_configs: {
|
||||||
type: Object,
|
type: Object,
|
||||||
value: CONFIGS
|
value: CONFIGS,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-hui-entity-filter-card', DemoFilter);
|
customElements.define("demo-hui-entity-filter-card", DemoFilter);
|
||||||
|
|||||||
@@ -1,34 +1,34 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/demo-cards.js';
|
import "../components/demo-cards.js";
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
{
|
{
|
||||||
heading: 'Basic example',
|
heading: "Basic example",
|
||||||
config: `
|
config: `
|
||||||
- type: gauge
|
- type: gauge
|
||||||
entity: sensor.brightness
|
entity: sensor.brightness
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'With title',
|
heading: "With title",
|
||||||
config: `
|
config: `
|
||||||
- type: gauge
|
- type: gauge
|
||||||
title: Humidity
|
title: Humidity
|
||||||
entity: sensor.outside_humidity
|
entity: sensor.outside_humidity
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Custom Unit of Measurement',
|
heading: "Custom Unit of Measurement",
|
||||||
config: `
|
config: `
|
||||||
- type: gauge
|
- type: gauge
|
||||||
entity: sensor.outside_temperature
|
entity: sensor.outside_temperature
|
||||||
unit_of_measurement: C
|
unit_of_measurement: C
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Setting Severity Levels',
|
heading: "Setting Severity Levels",
|
||||||
config: `
|
config: `
|
||||||
- type: gauge
|
- type: gauge
|
||||||
entity: sensor.brightness
|
entity: sensor.brightness
|
||||||
@@ -36,30 +36,30 @@ const CONFIGS = [
|
|||||||
red: 32
|
red: 32
|
||||||
green: 0
|
green: 0
|
||||||
yellow: 23
|
yellow: 23
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Setting Min and Max Values',
|
heading: "Setting Min and Max Values",
|
||||||
config: `
|
config: `
|
||||||
- type: gauge
|
- type: gauge
|
||||||
entity: sensor.brightness
|
entity: sensor.brightness
|
||||||
min: 0
|
min: 0
|
||||||
max: 38
|
max: 38
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Invalid Entity',
|
heading: "Invalid Entity",
|
||||||
config: `
|
config: `
|
||||||
- type: gauge
|
- type: gauge
|
||||||
entity: sensor.invalid_entity
|
entity: sensor.invalid_entity
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Non-Numeric Value',
|
heading: "Non-Numeric Value",
|
||||||
config: `
|
config: `
|
||||||
- type: gauge
|
- type: gauge
|
||||||
entity: plant.bonsai
|
entity: plant.bonsai
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -74,10 +74,10 @@ class DemoGaugeEntity extends PolymerElement {
|
|||||||
return {
|
return {
|
||||||
_configs: {
|
_configs: {
|
||||||
type: Object,
|
type: Object,
|
||||||
value: CONFIGS
|
value: CONFIGS,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-hui-gauge-card', DemoGaugeEntity);
|
customElements.define("demo-hui-gauge-card", DemoGaugeEntity);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/demo-cards.js';
|
import "../components/demo-cards.js";
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
{
|
{
|
||||||
heading: 'Basic example',
|
heading: "Basic example",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
entities:
|
entities:
|
||||||
@@ -16,10 +16,10 @@ const CONFIGS = [
|
|||||||
- light.kitchen_lights
|
- light.kitchen_lights
|
||||||
- lock.kitchen_door
|
- lock.kitchen_door
|
||||||
- light.ceiling_lights
|
- light.ceiling_lights
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'With title',
|
heading: "With title",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
title: This is glance
|
title: This is glance
|
||||||
@@ -31,10 +31,10 @@ const CONFIGS = [
|
|||||||
- light.kitchen_lights
|
- light.kitchen_lights
|
||||||
- lock.kitchen_door
|
- lock.kitchen_door
|
||||||
- light.ceiling_lights
|
- light.ceiling_lights
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Custom column width',
|
heading: "Custom column width",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
column_width: calc(100% / 7)
|
column_width: calc(100% / 7)
|
||||||
@@ -46,10 +46,10 @@ const CONFIGS = [
|
|||||||
- light.kitchen_lights
|
- light.kitchen_lights
|
||||||
- lock.kitchen_door
|
- lock.kitchen_door
|
||||||
- light.ceiling_lights
|
- light.ceiling_lights
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'No name',
|
heading: "No name",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
show_name: false
|
show_name: false
|
||||||
@@ -61,10 +61,10 @@ const CONFIGS = [
|
|||||||
- light.kitchen_lights
|
- light.kitchen_lights
|
||||||
- lock.kitchen_door
|
- lock.kitchen_door
|
||||||
- light.ceiling_lights
|
- light.ceiling_lights
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'No state',
|
heading: "No state",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
show_state: false
|
show_state: false
|
||||||
@@ -76,10 +76,10 @@ const CONFIGS = [
|
|||||||
- light.kitchen_lights
|
- light.kitchen_lights
|
||||||
- lock.kitchen_door
|
- lock.kitchen_door
|
||||||
- light.ceiling_lights
|
- light.ceiling_lights
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'No name and no state',
|
heading: "No name and no state",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
show_name: false
|
show_name: false
|
||||||
@@ -92,10 +92,10 @@ const CONFIGS = [
|
|||||||
- light.kitchen_lights
|
- light.kitchen_lights
|
||||||
- lock.kitchen_door
|
- lock.kitchen_door
|
||||||
- light.ceiling_lights
|
- light.ceiling_lights
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Custom name, custom icon',
|
heading: "Custom name, custom icon",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
entities:
|
entities:
|
||||||
@@ -109,10 +109,10 @@ const CONFIGS = [
|
|||||||
icon: mdi:alarm-light
|
icon: mdi:alarm-light
|
||||||
- lock.kitchen_door
|
- lock.kitchen_door
|
||||||
- light.ceiling_lights
|
- light.ceiling_lights
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Custom tap action',
|
heading: "Custom tap action",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
entities:
|
entities:
|
||||||
@@ -126,10 +126,10 @@ const CONFIGS = [
|
|||||||
- sun.sun
|
- sun.sun
|
||||||
- cover.kitchen_window
|
- cover.kitchen_window
|
||||||
- light.kitchen_lights
|
- light.kitchen_lights
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Selectively hidden name',
|
heading: "Selectively hidden name",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
entities:
|
entities:
|
||||||
@@ -140,10 +140,10 @@ const CONFIGS = [
|
|||||||
- entity: cover.kitchen_window
|
- entity: cover.kitchen_window
|
||||||
name:
|
name:
|
||||||
- light.kitchen_lights
|
- light.kitchen_lights
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Primary theme',
|
heading: "Primary theme",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
theming: primary
|
theming: primary
|
||||||
@@ -155,7 +155,7 @@ const CONFIGS = [
|
|||||||
- light.kitchen_lights
|
- light.kitchen_lights
|
||||||
- lock.kitchen_door
|
- lock.kitchen_door
|
||||||
- light.ceiling_lights
|
- light.ceiling_lights
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -170,10 +170,10 @@ class DemoPicEntity extends PolymerElement {
|
|||||||
return {
|
return {
|
||||||
_configs: {
|
_configs: {
|
||||||
type: Object,
|
type: Object,
|
||||||
value: CONFIGS
|
value: CONFIGS,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-hui-glance-card', DemoPicEntity);
|
customElements.define("demo-hui-glance-card", DemoPicEntity);
|
||||||
|
|||||||
@@ -1,39 +1,39 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/demo-cards.js';
|
import "../components/demo-cards.js";
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
{
|
{
|
||||||
heading: 'Without title',
|
heading: "Without title",
|
||||||
config: `
|
config: `
|
||||||
- type: iframe
|
- type: iframe
|
||||||
url: https://embed.windy.com/embed2.html
|
url: https://embed.windy.com/embed2.html
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'With title',
|
heading: "With title",
|
||||||
config: `
|
config: `
|
||||||
- type: iframe
|
- type: iframe
|
||||||
url: https://embed.windy.com/embed2.html
|
url: https://embed.windy.com/embed2.html
|
||||||
title: Weather radar
|
title: Weather radar
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Height-Width 3:4',
|
heading: "Height-Width 3:4",
|
||||||
config: `
|
config: `
|
||||||
- type: iframe
|
- type: iframe
|
||||||
url: https://embed.windy.com/embed2.html
|
url: https://embed.windy.com/embed2.html
|
||||||
aspect_ratio: 75%
|
aspect_ratio: 75%
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Height-Width 1:1',
|
heading: "Height-Width 1:1",
|
||||||
config: `
|
config: `
|
||||||
- type: iframe
|
- type: iframe
|
||||||
url: https://embed.windy.com/embed2.html
|
url: https://embed.windy.com/embed2.html
|
||||||
aspect_ratio: 100%
|
aspect_ratio: 100%
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -48,10 +48,10 @@ class DemoIframe extends PolymerElement {
|
|||||||
return {
|
return {
|
||||||
_configs: {
|
_configs: {
|
||||||
type: Object,
|
type: Object,
|
||||||
value: CONFIGS
|
value: CONFIGS,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-hui-iframe-card', DemoIframe);
|
customElements.define("demo-hui-iframe-card", DemoIframe);
|
||||||
|
|||||||
@@ -1,120 +1,120 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import getEntity from '../data/entity.js';
|
import getEntity from "../data/entity.js";
|
||||||
import provideHass from '../data/provide_hass.js';
|
import provideHass from "../data/provide_hass.js";
|
||||||
import '../components/demo-cards.js';
|
import "../components/demo-cards.js";
|
||||||
|
|
||||||
const ENTITIES = [
|
const ENTITIES = [
|
||||||
getEntity('device_tracker', 'demo_paulus', 'not_home', {
|
getEntity("device_tracker", "demo_paulus", "not_home", {
|
||||||
source_type: 'gps',
|
source_type: "gps",
|
||||||
latitude: 32.877105,
|
latitude: 32.877105,
|
||||||
longitude: 117.232185,
|
longitude: 117.232185,
|
||||||
gps_accuracy: 91,
|
gps_accuracy: 91,
|
||||||
battery: 71,
|
battery: 71,
|
||||||
friendly_name: 'Paulus'
|
friendly_name: "Paulus",
|
||||||
}),
|
}),
|
||||||
getEntity('device_tracker', 'demo_home_boy', 'home', {
|
getEntity("device_tracker", "demo_home_boy", "home", {
|
||||||
source_type: 'gps',
|
source_type: "gps",
|
||||||
latitude: 32.87334,
|
latitude: 32.87334,
|
||||||
longitude: 117.22745,
|
longitude: 117.22745,
|
||||||
gps_accuracy: 20,
|
gps_accuracy: 20,
|
||||||
battery: 53,
|
battery: 53,
|
||||||
friendly_name: 'Home Boy'
|
friendly_name: "Home Boy",
|
||||||
}),
|
}),
|
||||||
getEntity('zone', 'home', 'zoning', {
|
getEntity("zone", "home", "zoning", {
|
||||||
latitude: 32.87354,
|
latitude: 32.87354,
|
||||||
longitude: 117.22765,
|
longitude: 117.22765,
|
||||||
radius: 100,
|
radius: 100,
|
||||||
friendly_name: 'Home',
|
friendly_name: "Home",
|
||||||
icon: 'mdi:home'
|
icon: "mdi:home",
|
||||||
})
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
{
|
{
|
||||||
heading: 'Without title',
|
heading: "Without title",
|
||||||
config: `
|
config: `
|
||||||
- type: map
|
- type: map
|
||||||
entities:
|
entities:
|
||||||
- entity: device_tracker.demo_paulus
|
- entity: device_tracker.demo_paulus
|
||||||
- device_tracker.demo_home_boy
|
- device_tracker.demo_home_boy
|
||||||
- zone.home
|
- zone.home
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'With title',
|
heading: "With title",
|
||||||
config: `
|
config: `
|
||||||
- type: map
|
- type: map
|
||||||
entities:
|
entities:
|
||||||
- entity: device_tracker.demo_paulus
|
- entity: device_tracker.demo_paulus
|
||||||
- zone.home
|
- zone.home
|
||||||
title: Where is Paulus?
|
title: Where is Paulus?
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Height-Width 1:2',
|
heading: "Height-Width 1:2",
|
||||||
config: `
|
config: `
|
||||||
- type: map
|
- type: map
|
||||||
entities:
|
entities:
|
||||||
- entity: device_tracker.demo_paulus
|
- entity: device_tracker.demo_paulus
|
||||||
- zone.home
|
- zone.home
|
||||||
aspect_ratio: 50%
|
aspect_ratio: 50%
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Default Zoom',
|
heading: "Default Zoom",
|
||||||
config: `
|
config: `
|
||||||
- type: map
|
- type: map
|
||||||
default_zoom: 12
|
default_zoom: 12
|
||||||
entities:
|
entities:
|
||||||
- entity: device_tracker.demo_paulus
|
- entity: device_tracker.demo_paulus
|
||||||
- zone.home
|
- zone.home
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Default Zoom too High',
|
heading: "Default Zoom too High",
|
||||||
config: `
|
config: `
|
||||||
- type: map
|
- type: map
|
||||||
default_zoom: 20
|
default_zoom: 20
|
||||||
entities:
|
entities:
|
||||||
- entity: device_tracker.demo_paulus
|
- entity: device_tracker.demo_paulus
|
||||||
- zone.home
|
- zone.home
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Single Marker',
|
heading: "Single Marker",
|
||||||
config: `
|
config: `
|
||||||
- type: map
|
- type: map
|
||||||
entities:
|
entities:
|
||||||
- device_tracker.demo_paulus
|
- device_tracker.demo_paulus
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Single Marker Default Zoom',
|
heading: "Single Marker Default Zoom",
|
||||||
config: `
|
config: `
|
||||||
- type: map
|
- type: map
|
||||||
default_zoom: 8
|
default_zoom: 8
|
||||||
entities:
|
entities:
|
||||||
- device_tracker.demo_paulus
|
- device_tracker.demo_paulus
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'No Entities',
|
heading: "No Entities",
|
||||||
config: `
|
config: `
|
||||||
- type: map
|
- type: map
|
||||||
entities:
|
entities:
|
||||||
- light.bed_light
|
- light.bed_light
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'No Entities, Default Zoom',
|
heading: "No Entities, Default Zoom",
|
||||||
config: `
|
config: `
|
||||||
- type: map
|
- type: map
|
||||||
default_zoom: 8
|
default_zoom: 8
|
||||||
entities:
|
entities:
|
||||||
- light.bed_light
|
- light.bed_light
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -133,9 +133,9 @@ class DemoMap extends PolymerElement {
|
|||||||
return {
|
return {
|
||||||
_configs: {
|
_configs: {
|
||||||
type: Object,
|
type: Object,
|
||||||
value: CONFIGS
|
value: CONFIGS,
|
||||||
},
|
},
|
||||||
hass: Object
|
hass: Object,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,4 +146,4 @@ class DemoMap extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-hui-map-card', DemoMap);
|
customElements.define("demo-hui-map-card", DemoMap);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/demo-cards.js';
|
import "../components/demo-cards.js";
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
{
|
{
|
||||||
heading: 'markdown-it demo',
|
heading: "markdown-it demo",
|
||||||
config: `
|
config: `
|
||||||
- type: markdown
|
- type: markdown
|
||||||
content: >
|
content: >
|
||||||
@@ -248,7 +248,7 @@ const CONFIGS = [
|
|||||||
::: warning
|
::: warning
|
||||||
*here be dragons*
|
*here be dragons*
|
||||||
:::
|
:::
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -263,10 +263,10 @@ class DemoMarkdown extends PolymerElement {
|
|||||||
return {
|
return {
|
||||||
_configs: {
|
_configs: {
|
||||||
type: Object,
|
type: Object,
|
||||||
value: CONFIGS
|
value: CONFIGS,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-hui-markdown-card', DemoMarkdown);
|
customElements.define("demo-hui-markdown-card", DemoMarkdown);
|
||||||
|
|||||||
@@ -1,58 +1,58 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import getEntity from '../data/entity.js';
|
import getEntity from "../data/entity.js";
|
||||||
import provideHass from '../data/provide_hass.js';
|
import provideHass from "../data/provide_hass.js";
|
||||||
import '../components/demo-cards.js';
|
import "../components/demo-cards.js";
|
||||||
|
|
||||||
const ENTITIES = [
|
const ENTITIES = [
|
||||||
getEntity('media_player', 'bedroom', 'playing', {
|
getEntity("media_player", "bedroom", "playing", {
|
||||||
media_content_type: 'movie',
|
media_content_type: "movie",
|
||||||
media_title: 'Epic sax guy 10 hours',
|
media_title: "Epic sax guy 10 hours",
|
||||||
app_name: 'YouTube',
|
app_name: "YouTube",
|
||||||
supported_features: 32
|
supported_features: 32,
|
||||||
}),
|
}),
|
||||||
getEntity('media_player', 'family_room', 'paused', {
|
getEntity("media_player", "family_room", "paused", {
|
||||||
media_content_type: 'music',
|
media_content_type: "music",
|
||||||
media_title: 'I Wanna Be A Hippy (Flamman & Abraxas Radio Mix)',
|
media_title: "I Wanna Be A Hippy (Flamman & Abraxas Radio Mix)",
|
||||||
media_artist: 'Technohead',
|
media_artist: "Technohead",
|
||||||
supported_features: 16417
|
supported_features: 16417,
|
||||||
}),
|
}),
|
||||||
getEntity('media_player', 'family_room_no_play', 'paused', {
|
getEntity("media_player", "family_room_no_play", "paused", {
|
||||||
media_content_type: 'movie',
|
media_content_type: "movie",
|
||||||
media_title: 'Epic sax guy 10 hours',
|
media_title: "Epic sax guy 10 hours",
|
||||||
app_name: 'YouTube',
|
app_name: "YouTube",
|
||||||
supported_features: 33
|
supported_features: 33,
|
||||||
}),
|
}),
|
||||||
getEntity('media_player', 'living_room', 'playing', {
|
getEntity("media_player", "living_room", "playing", {
|
||||||
media_content_type: 'tvshow',
|
media_content_type: "tvshow",
|
||||||
media_title: 'Chapter 1',
|
media_title: "Chapter 1",
|
||||||
media_series_title: 'House of Cards',
|
media_series_title: "House of Cards",
|
||||||
app_name: 'Netflix',
|
app_name: "Netflix",
|
||||||
supported_features: 1
|
|
||||||
}),
|
|
||||||
getEntity('media_player', 'lounge_room', 'idle', {
|
|
||||||
media_content_type: 'music',
|
|
||||||
media_title: 'I Wanna Be A Hippy (Flamman & Abraxas Radio Mix)',
|
|
||||||
media_artist: 'Technohead',
|
|
||||||
supported_features: 1,
|
supported_features: 1,
|
||||||
}),
|
}),
|
||||||
getEntity('media_player', 'theater', 'off', {
|
getEntity("media_player", "lounge_room", "idle", {
|
||||||
media_content_type: 'movie',
|
media_content_type: "music",
|
||||||
media_title: 'Epic sax guy 10 hours',
|
media_title: "I Wanna Be A Hippy (Flamman & Abraxas Radio Mix)",
|
||||||
app_name: 'YouTube',
|
media_artist: "Technohead",
|
||||||
supported_features: 33
|
supported_features: 1,
|
||||||
}),
|
}),
|
||||||
getEntity('media_player', 'android_cast', 'playing', {
|
getEntity("media_player", "theater", "off", {
|
||||||
media_title: 'Android Screen Casting',
|
media_content_type: "movie",
|
||||||
app_name: 'Screen Mirroring',
|
media_title: "Epic sax guy 10 hours",
|
||||||
supported_features: 21437
|
app_name: "YouTube",
|
||||||
|
supported_features: 33,
|
||||||
|
}),
|
||||||
|
getEntity("media_player", "android_cast", "playing", {
|
||||||
|
media_title: "Android Screen Casting",
|
||||||
|
app_name: "Screen Mirroring",
|
||||||
|
supported_features: 21437,
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
{
|
{
|
||||||
heading: 'Media Players',
|
heading: "Media Players",
|
||||||
config: `
|
config: `
|
||||||
- type: entities
|
- type: entities
|
||||||
entities:
|
entities:
|
||||||
@@ -70,8 +70,8 @@ const CONFIGS = [
|
|||||||
name: Chromcast Idle
|
name: Chromcast Idle
|
||||||
- entity: media_player.theater
|
- entity: media_player.theater
|
||||||
name: 'Player Off'
|
name: 'Player Off'
|
||||||
`
|
`,
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoHuiMediaPlayerRows extends PolymerElement {
|
class DemoHuiMediaPlayerRows extends PolymerElement {
|
||||||
@@ -89,7 +89,7 @@ class DemoHuiMediaPlayerRows extends PolymerElement {
|
|||||||
return {
|
return {
|
||||||
_configs: {
|
_configs: {
|
||||||
type: Object,
|
type: Object,
|
||||||
value: CONFIGS
|
value: CONFIGS,
|
||||||
},
|
},
|
||||||
hass: Object,
|
hass: Object,
|
||||||
};
|
};
|
||||||
@@ -102,4 +102,4 @@ class DemoHuiMediaPlayerRows extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-hui-media-player-rows', DemoHuiMediaPlayerRows);
|
customElements.define("demo-hui-media-player-rows", DemoHuiMediaPlayerRows);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/demo-cards.js';
|
import "../components/demo-cards.js";
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
{
|
{
|
||||||
heading: 'Card with few elements',
|
heading: "Card with few elements",
|
||||||
config: `
|
config: `
|
||||||
- type: picture-elements
|
- type: picture-elements
|
||||||
image: /images/floorplan.png
|
image: /images/floorplan.png
|
||||||
@@ -49,7 +49,7 @@ const CONFIGS = [
|
|||||||
style:
|
style:
|
||||||
top: 8%
|
top: 8%
|
||||||
left: 35%
|
left: 35%
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -64,10 +64,10 @@ class DemoPicElements extends PolymerElement {
|
|||||||
return {
|
return {
|
||||||
_configs: {
|
_configs: {
|
||||||
type: Object,
|
type: Object,
|
||||||
value: CONFIGS
|
value: CONFIGS,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-hui-picture-elements-card', DemoPicElements);
|
customElements.define("demo-hui-picture-elements-card", DemoPicElements);
|
||||||
|
|||||||
@@ -1,67 +1,67 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/demo-cards.js';
|
import "../components/demo-cards.js";
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
{
|
{
|
||||||
heading: 'State on',
|
heading: "State on",
|
||||||
config: `
|
config: `
|
||||||
- type: picture-entity
|
- type: picture-entity
|
||||||
image: /images/kitchen.png
|
image: /images/kitchen.png
|
||||||
entity: light.kitchen_lights
|
entity: light.kitchen_lights
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'State off',
|
heading: "State off",
|
||||||
config: `
|
config: `
|
||||||
- type: picture-entity
|
- type: picture-entity
|
||||||
image: /images/bed.png
|
image: /images/bed.png
|
||||||
entity: light.bed_light
|
entity: light.bed_light
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Entity unavailable',
|
heading: "Entity unavailable",
|
||||||
config: `
|
config: `
|
||||||
- type: picture-entity
|
- type: picture-entity
|
||||||
image: /images/living_room.png
|
image: /images/living_room.png
|
||||||
entity: light.non_existing
|
entity: light.non_existing
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Camera entity',
|
heading: "Camera entity",
|
||||||
config: `
|
config: `
|
||||||
- type: picture-entity
|
- type: picture-entity
|
||||||
entity: camera.demo_camera
|
entity: camera.demo_camera
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Hidden name',
|
heading: "Hidden name",
|
||||||
config: `
|
config: `
|
||||||
- type: picture-entity
|
- type: picture-entity
|
||||||
image: /images/kitchen.png
|
image: /images/kitchen.png
|
||||||
entity: light.kitchen_lights
|
entity: light.kitchen_lights
|
||||||
show_name: false
|
show_name: false
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Hidden state',
|
heading: "Hidden state",
|
||||||
config: `
|
config: `
|
||||||
- type: picture-entity
|
- type: picture-entity
|
||||||
image: /images/kitchen.png
|
image: /images/kitchen.png
|
||||||
entity: light.kitchen_lights
|
entity: light.kitchen_lights
|
||||||
show_state: false
|
show_state: false
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Both hidden',
|
heading: "Both hidden",
|
||||||
config: `
|
config: `
|
||||||
- type: picture-entity
|
- type: picture-entity
|
||||||
image: /images/kitchen.png
|
image: /images/kitchen.png
|
||||||
entity: light.kitchen_lights
|
entity: light.kitchen_lights
|
||||||
show_name: false
|
show_name: false
|
||||||
show_state: false
|
show_state: false
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -76,10 +76,10 @@ class DemoPicEntity extends PolymerElement {
|
|||||||
return {
|
return {
|
||||||
_configs: {
|
_configs: {
|
||||||
type: Object,
|
type: Object,
|
||||||
value: CONFIGS
|
value: CONFIGS,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-hui-picture-entity-card', DemoPicEntity);
|
customElements.define("demo-hui-picture-entity-card", DemoPicEntity);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/demo-cards.js';
|
import "../components/demo-cards.js";
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
{
|
{
|
||||||
heading: 'Title, dialog, toggle',
|
heading: "Title, dialog, toggle",
|
||||||
config: `
|
config: `
|
||||||
- type: picture-glance
|
- type: picture-glance
|
||||||
image: /images/living_room.png
|
image: /images/living_room.png
|
||||||
@@ -15,10 +15,10 @@ const CONFIGS = [
|
|||||||
- light.ceiling_lights
|
- light.ceiling_lights
|
||||||
- binary_sensor.movement_backyard
|
- binary_sensor.movement_backyard
|
||||||
- binary_sensor.basement_floor_wet
|
- binary_sensor.basement_floor_wet
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Title, dialog, no toggle',
|
heading: "Title, dialog, no toggle",
|
||||||
config: `
|
config: `
|
||||||
- type: picture-glance
|
- type: picture-glance
|
||||||
image: /images/living_room.png
|
image: /images/living_room.png
|
||||||
@@ -26,10 +26,10 @@ const CONFIGS = [
|
|||||||
entities:
|
entities:
|
||||||
- binary_sensor.movement_backyard
|
- binary_sensor.movement_backyard
|
||||||
- binary_sensor.basement_floor_wet
|
- binary_sensor.basement_floor_wet
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Title, no dialog, toggle',
|
heading: "Title, no dialog, toggle",
|
||||||
config: `
|
config: `
|
||||||
- type: picture-glance
|
- type: picture-glance
|
||||||
image: /images/living_room.png
|
image: /images/living_room.png
|
||||||
@@ -37,10 +37,10 @@ const CONFIGS = [
|
|||||||
entities:
|
entities:
|
||||||
- switch.decorative_lights
|
- switch.decorative_lights
|
||||||
- light.ceiling_lights
|
- light.ceiling_lights
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'No title, dialog, toggle',
|
heading: "No title, dialog, toggle",
|
||||||
config: `
|
config: `
|
||||||
- type: picture-glance
|
- type: picture-glance
|
||||||
image: /images/living_room.png
|
image: /images/living_room.png
|
||||||
@@ -49,30 +49,30 @@ const CONFIGS = [
|
|||||||
- light.ceiling_lights
|
- light.ceiling_lights
|
||||||
- binary_sensor.movement_backyard
|
- binary_sensor.movement_backyard
|
||||||
- binary_sensor.basement_floor_wet
|
- binary_sensor.basement_floor_wet
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'No title, dialog, no toggle',
|
heading: "No title, dialog, no toggle",
|
||||||
config: `
|
config: `
|
||||||
- type: picture-glance
|
- type: picture-glance
|
||||||
image: /images/living_room.png
|
image: /images/living_room.png
|
||||||
entities:
|
entities:
|
||||||
- binary_sensor.movement_backyard
|
- binary_sensor.movement_backyard
|
||||||
- binary_sensor.basement_floor_wet
|
- binary_sensor.basement_floor_wet
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'No title, no dialog, toggle',
|
heading: "No title, no dialog, toggle",
|
||||||
config: `
|
config: `
|
||||||
- type: picture-glance
|
- type: picture-glance
|
||||||
image: /images/living_room.png
|
image: /images/living_room.png
|
||||||
entities:
|
entities:
|
||||||
- switch.decorative_lights
|
- switch.decorative_lights
|
||||||
- light.ceiling_lights
|
- light.ceiling_lights
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Custom icon',
|
heading: "Custom icon",
|
||||||
config: `
|
config: `
|
||||||
- type: picture-glance
|
- type: picture-glance
|
||||||
image: /images/living_room.png
|
image: /images/living_room.png
|
||||||
@@ -81,7 +81,7 @@ const CONFIGS = [
|
|||||||
- entity: switch.decorative_lights
|
- entity: switch.decorative_lights
|
||||||
icon: mdi:power
|
icon: mdi:power
|
||||||
- binary_sensor.basement_floor_wet
|
- binary_sensor.basement_floor_wet
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -96,10 +96,10 @@ class DemoPicGlance extends PolymerElement {
|
|||||||
return {
|
return {
|
||||||
_configs: {
|
_configs: {
|
||||||
type: Object,
|
type: Object,
|
||||||
value: CONFIGS
|
value: CONFIGS,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-hui-picture-glance-card', DemoPicGlance);
|
customElements.define("demo-hui-picture-glance-card", DemoPicGlance);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/demo-cards.js';
|
import "../components/demo-cards.js";
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
{
|
{
|
||||||
heading: 'Vertical Stack',
|
heading: "Vertical Stack",
|
||||||
config: `
|
config: `
|
||||||
- type: vertical-stack
|
- type: vertical-stack
|
||||||
cards:
|
cards:
|
||||||
@@ -17,10 +17,10 @@ const CONFIGS = [
|
|||||||
- device_tracker.demo_anne_therese
|
- device_tracker.demo_anne_therese
|
||||||
- device_tracker.demo_home_boy
|
- device_tracker.demo_home_boy
|
||||||
- device_tracker.demo_paulus
|
- device_tracker.demo_paulus
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Horizontal Stack',
|
heading: "Horizontal Stack",
|
||||||
config: `
|
config: `
|
||||||
- type: horizontal-stack
|
- type: horizontal-stack
|
||||||
cards:
|
cards:
|
||||||
@@ -32,10 +32,10 @@ const CONFIGS = [
|
|||||||
- device_tracker.demo_anne_therese
|
- device_tracker.demo_anne_therese
|
||||||
- device_tracker.demo_home_boy
|
- device_tracker.demo_home_boy
|
||||||
- device_tracker.demo_paulus
|
- device_tracker.demo_paulus
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'Combination of both',
|
heading: "Combination of both",
|
||||||
config: `
|
config: `
|
||||||
- type: vertical-stack
|
- type: vertical-stack
|
||||||
cards:
|
cards:
|
||||||
@@ -52,7 +52,7 @@ const CONFIGS = [
|
|||||||
- type: picture-entity
|
- type: picture-entity
|
||||||
image: /images/bed.png
|
image: /images/bed.png
|
||||||
entity: light.bed_light
|
entity: light.bed_light
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -67,10 +67,10 @@ class DemoStack extends PolymerElement {
|
|||||||
return {
|
return {
|
||||||
_configs: {
|
_configs: {
|
||||||
type: Object,
|
type: Object,
|
||||||
value: CONFIGS
|
value: CONFIGS,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-hui-stack-card', DemoStack);
|
customElements.define("demo-hui-stack-card", DemoStack);
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../../src/dialogs/more-info/controls/more-info-content.js';
|
import "../../../src/dialogs/more-info/controls/more-info-content.js";
|
||||||
import '../../../src/components/ha-card.js';
|
import "../../../src/components/ha-card.js";
|
||||||
|
|
||||||
import getEntity from '../data/entity.js';
|
import getEntity from "../data/entity.js";
|
||||||
import provideHass from '../data/provide_hass.js';
|
import provideHass from "../data/provide_hass.js";
|
||||||
|
|
||||||
import '../components/demo-more-infos.js';
|
import "../components/demo-more-infos.js";
|
||||||
|
|
||||||
/* eslint-disable no-unused-vars */
|
/* eslint-disable no-unused-vars */
|
||||||
|
|
||||||
@@ -20,17 +20,16 @@ const SUPPORT_TRANSITION = 32;
|
|||||||
const SUPPORT_WHITE_VALUE = 128;
|
const SUPPORT_WHITE_VALUE = 128;
|
||||||
|
|
||||||
const ENTITIES = [
|
const ENTITIES = [
|
||||||
getEntity('light', 'bed_light', 'on', {
|
getEntity("light", "bed_light", "on", {
|
||||||
friendly_name: 'Basic Light'
|
friendly_name: "Basic Light",
|
||||||
}),
|
}),
|
||||||
getEntity('light', 'kitchen_light', 'on', {
|
getEntity("light", "kitchen_light", "on", {
|
||||||
friendly_name: 'Brightness Light',
|
friendly_name: "Brightness Light",
|
||||||
brightness: 80,
|
brightness: 80,
|
||||||
supported_features: SUPPORT_BRIGHTNESS,
|
supported_features: SUPPORT_BRIGHTNESS,
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
class DemoMoreInfoLight extends PolymerElement {
|
class DemoMoreInfoLight extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
return html`
|
return html`
|
||||||
@@ -45,7 +44,7 @@ class DemoMoreInfoLight extends PolymerElement {
|
|||||||
return {
|
return {
|
||||||
_entities: {
|
_entities: {
|
||||||
type: Array,
|
type: Array,
|
||||||
value: ENTITIES.map(ent => ent.entityId),
|
value: ENTITIES.map((ent) => ent.entityId),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -57,4 +56,4 @@ class DemoMoreInfoLight extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('demo-more-info-light', DemoMoreInfoLight);
|
customElements.define("demo-more-info-light", DemoMoreInfoLight);
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import '@polymer/paper-styles/typography.js';
|
import "@polymer/paper-styles/typography.js";
|
||||||
import '@polymer/polymer/lib/elements/dom-if.js';
|
import "@polymer/polymer/lib/elements/dom-if.js";
|
||||||
import '@polymer/polymer/lib/elements/dom-repeat.js';
|
import "@polymer/polymer/lib/elements/dom-repeat.js";
|
||||||
|
|
||||||
import '../../src/resources/hass-icons.js';
|
import "../../src/resources/hass-icons.js";
|
||||||
import '../../src/resources/ha-style.js';
|
import "../../src/resources/ha-style.js";
|
||||||
import '../../src/resources/roboto.js';
|
import "../../src/resources/roboto.js";
|
||||||
import '../../src/components/ha-iconset-svg.js';
|
import "../../src/components/ha-iconset-svg.js";
|
||||||
|
|
||||||
import './ha-gallery.js';
|
import "./ha-gallery.js";
|
||||||
|
|
||||||
document.body.appendChild(document.createElement('ha-gallery'));
|
document.body.appendChild(document.createElement("ha-gallery"));
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
import '@polymer/app-layout/app-header-layout/app-header-layout.js';
|
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-header/app-header.js";
|
||||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
import "@polymer/app-layout/app-toolbar/app-toolbar.js";
|
||||||
import '@polymer/iron-icon/iron-icon.js';
|
import "@polymer/iron-icon/iron-icon.js";
|
||||||
import '@polymer/paper-card/paper-card.js';
|
import "@polymer/paper-card/paper-card.js";
|
||||||
import '@polymer/paper-item/paper-item.js';
|
import "@polymer/paper-item/paper-item.js";
|
||||||
import '@polymer/paper-item/paper-item-body.js';
|
import "@polymer/paper-item/paper-item-body.js";
|
||||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
import "@polymer/paper-icon-button/paper-icon-button.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../src/managers/notification-manager.js';
|
import "../../src/managers/notification-manager.js";
|
||||||
|
|
||||||
const DEMOS = require.context('./demos', true, /^(.*\.(js$))[^.]*$/im);
|
const DEMOS = require.context("./demos", true, /^(.*\.(js$))[^.]*$/im);
|
||||||
|
|
||||||
const fixPath = path => path.substr(2, path.length - 5);
|
const fixPath = (path) => path.substr(2, path.length - 5);
|
||||||
|
|
||||||
class HaGallery extends PolymerElement {
|
class HaGallery extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -131,19 +131,19 @@ class HaGallery extends PolymerElement {
|
|||||||
_demo: {
|
_demo: {
|
||||||
type: String,
|
type: String,
|
||||||
value: document.location.hash.substr(1),
|
value: document.location.hash.substr(1),
|
||||||
observer: '_demoChanged',
|
observer: "_demoChanged",
|
||||||
},
|
},
|
||||||
_demos: {
|
_demos: {
|
||||||
type: Array,
|
type: Array,
|
||||||
value: DEMOS.keys().map(fixPath)
|
value: DEMOS.keys().map(fixPath),
|
||||||
},
|
},
|
||||||
_lovelaceDemos: {
|
_lovelaceDemos: {
|
||||||
type: Array,
|
type: Array,
|
||||||
computed: '_computeLovelace(_demos)',
|
computed: "_computeLovelace(_demos)",
|
||||||
},
|
},
|
||||||
_moreInfoDemos: {
|
_moreInfoDemos: {
|
||||||
type: Array,
|
type: Array,
|
||||||
computed: '_computeMoreInfos(_demos)',
|
computed: "_computeMoreInfos(_demos)",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -151,18 +151,21 @@ class HaGallery extends PolymerElement {
|
|||||||
ready() {
|
ready() {
|
||||||
super.ready();
|
super.ready();
|
||||||
|
|
||||||
this.addEventListener(
|
this.addEventListener("show-notification", (ev) =>
|
||||||
'show-notification',
|
this.$.notifications.showNotification(ev.detail.message)
|
||||||
ev => this.$.notifications.showNotification(ev.detail.message)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
this.addEventListener('hass-more-info', (ev) => {
|
this.addEventListener("hass-more-info", (ev) => {
|
||||||
if (ev.detail.entityId) {
|
if (ev.detail.entityId) {
|
||||||
this.$.notifications.showNotification(`Showing more info for ${ev.detail.entityId}`);
|
this.$.notifications.showNotification(
|
||||||
|
`Showing more info for ${ev.detail.entityId}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('hashchange', () => { this._demo = document.location.hash.substr(1); });
|
window.addEventListener("hashchange", () => {
|
||||||
|
this._demo = document.location.hash.substr(1);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_withDefault(value, def) {
|
_withDefault(value, def) {
|
||||||
@@ -182,20 +185,20 @@ class HaGallery extends PolymerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_computeHeaderButtonClass(demo) {
|
_computeHeaderButtonClass(demo) {
|
||||||
return demo ? '' : 'invisible';
|
return demo ? "" : "invisible";
|
||||||
}
|
}
|
||||||
|
|
||||||
_backTapped() {
|
_backTapped() {
|
||||||
document.location.hash = '';
|
document.location.hash = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
_computeLovelace(demos) {
|
_computeLovelace(demos) {
|
||||||
return demos.filter(demo => demo.includes('hui'));
|
return demos.filter((demo) => demo.includes("hui"));
|
||||||
}
|
}
|
||||||
|
|
||||||
_computeMoreInfos(demos) {
|
_computeMoreInfos(demos) {
|
||||||
return demos.filter(demo => demo.includes('more-info'));
|
return demos.filter((demo) => demo.includes("more-info"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('ha-gallery', HaGallery);
|
customElements.define("ha-gallery", HaGallery);
|
||||||
|
|||||||
@@ -1,36 +1,34 @@
|
|||||||
const path = require('path');
|
const path = require("path");
|
||||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
|
||||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||||
|
|
||||||
const isProd = process.env.NODE_ENV === 'production';
|
const isProd = process.env.NODE_ENV === "production";
|
||||||
const chunkFilename = isProd ?
|
const chunkFilename = isProd ? "chunk.[chunkhash].js" : "[name].chunk.js";
|
||||||
'chunk.[chunkhash].js' : '[name].chunk.js';
|
const buildPath = path.resolve(__dirname, "dist");
|
||||||
const buildPath = path.resolve(__dirname, 'dist');
|
const publicPath = isProd ? "./" : "http://localhost:8080/";
|
||||||
const publicPath = isProd ? './' : 'http://localhost:8080/';
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: isProd ? 'production' : 'development',
|
mode: isProd ? "production" : "development",
|
||||||
// Disabled in prod while we make Home Assistant able to serve the right files.
|
// Disabled in prod while we make Home Assistant able to serve the right files.
|
||||||
// Was source-map
|
// Was source-map
|
||||||
devtool: isProd ? 'none' : 'inline-source-map',
|
devtool: isProd ? "none" : "inline-source-map",
|
||||||
entry: './src/entrypoint.js',
|
entry: "./src/entrypoint.js",
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.js$/,
|
test: /\.js$/,
|
||||||
use: {
|
use: {
|
||||||
loader: 'babel-loader',
|
loader: "babel-loader",
|
||||||
options: {
|
options: {
|
||||||
plugins: [
|
plugins: [
|
||||||
// Only support the syntax, Webpack will handle it.
|
// Only support the syntax, Webpack will handle it.
|
||||||
'syntax-dynamic-import',
|
"syntax-dynamic-import",
|
||||||
[
|
[
|
||||||
'transform-react-jsx',
|
"transform-react-jsx",
|
||||||
{
|
{
|
||||||
pragma: 'h'
|
pragma: "h",
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -38,39 +36,49 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
test: /\.(html)$/,
|
test: /\.(html)$/,
|
||||||
use: {
|
use: {
|
||||||
loader: 'html-loader',
|
loader: "html-loader",
|
||||||
options: {
|
options: {
|
||||||
exportAsEs6Default: true,
|
exportAsEs6Default: true,
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
]
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new CopyWebpackPlugin([
|
new CopyWebpackPlugin([
|
||||||
'public',
|
"public",
|
||||||
{ from: '../public', to: 'static' },
|
{ from: "../public", to: "static" },
|
||||||
{ from: '../build-translations/output', to: 'static/translations' },
|
{ from: "../build-translations/output", to: "static/translations" },
|
||||||
{ from: '../node_modules/leaflet/dist/leaflet.css', to: 'static/images/leaflet/' },
|
{
|
||||||
{ from: '../node_modules/@polymer/font-roboto-local/fonts', to: 'static/fonts' },
|
from: "../node_modules/leaflet/dist/leaflet.css",
|
||||||
{ from: '../node_modules/leaflet/dist/images', to: 'static/images/leaflet/' },
|
to: "static/images/leaflet/",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "../node_modules/@polymer/font-roboto-local/fonts",
|
||||||
|
to: "static/fonts",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "../node_modules/leaflet/dist/images",
|
||||||
|
to: "static/images/leaflet/",
|
||||||
|
},
|
||||||
]),
|
]),
|
||||||
isProd && new UglifyJsPlugin({
|
isProd &&
|
||||||
|
new UglifyJsPlugin({
|
||||||
extractComments: true,
|
extractComments: true,
|
||||||
sourceMap: true,
|
sourceMap: true,
|
||||||
uglifyOptions: {
|
uglifyOptions: {
|
||||||
// Disabling because it broke output
|
// Disabling because it broke output
|
||||||
mangle: false,
|
mangle: false,
|
||||||
}
|
},
|
||||||
}),
|
}),
|
||||||
].filter(Boolean),
|
].filter(Boolean),
|
||||||
output: {
|
output: {
|
||||||
filename: '[name].js',
|
filename: "[name].js",
|
||||||
chunkFilename: chunkFilename,
|
chunkFilename: chunkFilename,
|
||||||
path: buildPath,
|
path: buildPath,
|
||||||
publicPath,
|
publicPath,
|
||||||
},
|
},
|
||||||
devServer: {
|
devServer: {
|
||||||
contentBase: './public',
|
contentBase: "./public",
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
var path = require('path');
|
var path = require("path");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
polymer_dir: path.resolve(__dirname, '..'),
|
polymer_dir: path.resolve(__dirname, ".."),
|
||||||
build_dir: path.resolve(__dirname, '../build'),
|
build_dir: path.resolve(__dirname, "../build"),
|
||||||
output: path.resolve(__dirname, '../hass_frontend'),
|
output: path.resolve(__dirname, "../hass_frontend"),
|
||||||
output_es5: path.resolve(__dirname, '../hass_frontend_es5'),
|
output_es5: path.resolve(__dirname, "../hass_frontend_es5"),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,31 +1,34 @@
|
|||||||
const gulp = require('gulp');
|
const gulp = require("gulp");
|
||||||
const path = require('path');
|
const path = require("path");
|
||||||
const fs = require('fs');
|
const fs = require("fs");
|
||||||
const config = require('../config');
|
const config = require("../config");
|
||||||
|
|
||||||
const ICON_PACKAGE_PATH = path.resolve(__dirname, '../../node_modules/@mdi/svg/');
|
const ICON_PACKAGE_PATH = path.resolve(
|
||||||
const META_PATH = path.resolve(ICON_PACKAGE_PATH, 'meta.json');
|
__dirname,
|
||||||
const ICON_PATH = path.resolve(ICON_PACKAGE_PATH, 'svg');
|
"../../node_modules/@mdi/svg/"
|
||||||
const OUTPUT_DIR = path.resolve(__dirname, '../../build');
|
);
|
||||||
const MDI_OUTPUT_PATH = path.resolve(OUTPUT_DIR, 'mdi.html');
|
const META_PATH = path.resolve(ICON_PACKAGE_PATH, "meta.json");
|
||||||
const HASS_OUTPUT_PATH = path.resolve(OUTPUT_DIR, 'hass-icons.html');
|
const ICON_PATH = path.resolve(ICON_PACKAGE_PATH, "svg");
|
||||||
|
const OUTPUT_DIR = path.resolve(__dirname, "../../build");
|
||||||
|
const MDI_OUTPUT_PATH = path.resolve(OUTPUT_DIR, "mdi.html");
|
||||||
|
const HASS_OUTPUT_PATH = path.resolve(OUTPUT_DIR, "hass-icons.html");
|
||||||
|
|
||||||
const BUILT_IN_PANEL_ICONS = [
|
const BUILT_IN_PANEL_ICONS = [
|
||||||
'calendar', // Calendar
|
"calendar", // Calendar
|
||||||
'settings', // Config
|
"settings", // Config
|
||||||
'home-assistant', // Hass.io
|
"home-assistant", // Hass.io
|
||||||
'poll-box', // History panel
|
"poll-box", // History panel
|
||||||
'format-list-bulleted-type', // Logbook
|
"format-list-bulleted-type", // Logbook
|
||||||
'mailbox', // Mailbox
|
"mailbox", // Mailbox
|
||||||
'account-location', // Map
|
"account-location", // Map
|
||||||
'cart', // Shopping List
|
"cart", // Shopping List
|
||||||
];
|
];
|
||||||
|
|
||||||
// Given an icon name, load the SVG file
|
// Given an icon name, load the SVG file
|
||||||
function loadIcon(name) {
|
function loadIcon(name) {
|
||||||
const iconPath = path.resolve(ICON_PATH, `${name}.svg`);
|
const iconPath = path.resolve(ICON_PATH, `${name}.svg`);
|
||||||
try {
|
try {
|
||||||
return fs.readFileSync(iconPath, 'utf-8');
|
return fs.readFileSync(iconPath, "utf-8");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -33,7 +36,7 @@ function loadIcon(name) {
|
|||||||
|
|
||||||
// Given an SVG file, convert it to an iron-iconset-svg definition
|
// Given an SVG file, convert it to an iron-iconset-svg definition
|
||||||
function transformXMLtoPolymer(name, xml) {
|
function transformXMLtoPolymer(name, xml) {
|
||||||
const start = xml.indexOf('><path') + 1;
|
const start = xml.indexOf("><path") + 1;
|
||||||
const end = xml.length - start - 6;
|
const end = xml.length - start - 6;
|
||||||
const path = xml.substr(start, end);
|
const path = xml.substr(start, end);
|
||||||
return `<g id="${name}">${path}</g>`;
|
return `<g id="${name}">${path}</g>`;
|
||||||
@@ -41,22 +44,26 @@ function transformXMLtoPolymer(name, xml) {
|
|||||||
|
|
||||||
// Given an iconset name and icon names, generate a polymer iconset
|
// Given an iconset name and icon names, generate a polymer iconset
|
||||||
function generateIconset(name, iconNames) {
|
function generateIconset(name, iconNames) {
|
||||||
const iconDefs = iconNames.map(name => {
|
const iconDefs = iconNames
|
||||||
|
.map((name) => {
|
||||||
const iconDef = loadIcon(name);
|
const iconDef = loadIcon(name);
|
||||||
if (!iconDef) {
|
if (!iconDef) {
|
||||||
throw new Error(`Unknown icon referenced: ${name}`);
|
throw new Error(`Unknown icon referenced: ${name}`);
|
||||||
}
|
}
|
||||||
return transformXMLtoPolymer(name, iconDef)
|
return transformXMLtoPolymer(name, iconDef);
|
||||||
}).join('');
|
})
|
||||||
|
.join("");
|
||||||
return `<ha-iconset-svg name="${name}" size="24"><svg><defs>${iconDefs}</defs></svg></ha-iconset-svg>`;
|
return `<ha-iconset-svg name="${name}" size="24"><svg><defs>${iconDefs}</defs></svg></ha-iconset-svg>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the full MDI iconset
|
// Generate the full MDI iconset
|
||||||
function genMDIIcons() {
|
function genMDIIcons() {
|
||||||
const meta = JSON.parse(fs.readFileSync(path.resolve(ICON_PACKAGE_PATH, META_PATH), 'UTF-8'));
|
const meta = JSON.parse(
|
||||||
const iconNames = meta.map(iconInfo => iconInfo.name);
|
fs.readFileSync(path.resolve(ICON_PACKAGE_PATH, META_PATH), "UTF-8")
|
||||||
|
);
|
||||||
|
const iconNames = meta.map((iconInfo) => iconInfo.name);
|
||||||
fs.existsSync(OUTPUT_DIR) || fs.mkdirSync(OUTPUT_DIR);
|
fs.existsSync(OUTPUT_DIR) || fs.mkdirSync(OUTPUT_DIR);
|
||||||
fs.writeFileSync(MDI_OUTPUT_PATH, generateIconset('mdi', iconNames));
|
fs.writeFileSync(MDI_OUTPUT_PATH, generateIconset("mdi", iconNames));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to map recursively over files in a folder and it's subfolders
|
// Helper function to map recursively over files in a folder and it's subfolders
|
||||||
@@ -75,30 +82,30 @@ function mapFiles(startPath, filter, mapFunc) {
|
|||||||
|
|
||||||
// Find all icons used by the project.
|
// Find all icons used by the project.
|
||||||
function findIcons(path, iconsetName) {
|
function findIcons(path, iconsetName) {
|
||||||
const iconRegex = new RegExp(`${iconsetName}:[\\w-]+`, 'g');
|
const iconRegex = new RegExp(`${iconsetName}:[\\w-]+`, "g");
|
||||||
const icons = new Set();
|
const icons = new Set();
|
||||||
function processFile(filename) {
|
function processFile(filename) {
|
||||||
const content = fs.readFileSync(filename);
|
const content = fs.readFileSync(filename);
|
||||||
let match;
|
let match;
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
while (match = iconRegex.exec(content)) {
|
while ((match = iconRegex.exec(content))) {
|
||||||
// strip off "hass:" and add to set
|
// strip off "hass:" and add to set
|
||||||
icons.add(match[0].substr(iconsetName.length + 1));
|
icons.add(match[0].substr(iconsetName.length + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mapFiles(path, '.js', processFile);
|
mapFiles(path, ".js", processFile);
|
||||||
return Array.from(icons);
|
return Array.from(icons);
|
||||||
}
|
}
|
||||||
|
|
||||||
function genHassIcons() {
|
function genHassIcons() {
|
||||||
const iconNames = findIcons('./src', 'hass').concat(BUILT_IN_PANEL_ICONS);
|
const iconNames = findIcons("./src", "hass").concat(BUILT_IN_PANEL_ICONS);
|
||||||
fs.existsSync(OUTPUT_DIR) || fs.mkdirSync(OUTPUT_DIR);
|
fs.existsSync(OUTPUT_DIR) || fs.mkdirSync(OUTPUT_DIR);
|
||||||
fs.writeFileSync(HASS_OUTPUT_PATH, generateIconset('hass', iconNames));
|
fs.writeFileSync(HASS_OUTPUT_PATH, generateIconset("hass", iconNames));
|
||||||
}
|
}
|
||||||
|
|
||||||
gulp.task('gen-icons-mdi', () => genMDIIcons());
|
gulp.task("gen-icons-mdi", () => genMDIIcons());
|
||||||
gulp.task('gen-icons-hass', () => genHassIcons());
|
gulp.task("gen-icons-hass", () => genHassIcons());
|
||||||
gulp.task('gen-icons', ['gen-icons-hass', 'gen-icons-mdi'], () => {});
|
gulp.task("gen-icons", ["gen-icons-hass", "gen-icons-mdi"], () => {});
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
findIcons,
|
findIcons,
|
||||||
|
|||||||
@@ -1,40 +1,44 @@
|
|||||||
const path = require('path');
|
const path = require("path");
|
||||||
const gulp = require('gulp');
|
const gulp = require("gulp");
|
||||||
const foreach = require('gulp-foreach');
|
const foreach = require("gulp-foreach");
|
||||||
const hash = require('gulp-hash');
|
const hash = require("gulp-hash");
|
||||||
const insert = require('gulp-insert');
|
const insert = require("gulp-insert");
|
||||||
const merge = require('gulp-merge-json');
|
const merge = require("gulp-merge-json");
|
||||||
const minify = require('gulp-jsonminify');
|
const minify = require("gulp-jsonminify");
|
||||||
const rename = require('gulp-rename');
|
const rename = require("gulp-rename");
|
||||||
const transform = require('gulp-json-transform');
|
const transform = require("gulp-json-transform");
|
||||||
|
|
||||||
const inDir = 'translations';
|
const inDir = "translations";
|
||||||
const workDir = 'build-translations';
|
const workDir = "build-translations";
|
||||||
const fullDir = workDir + '/full';
|
const fullDir = workDir + "/full";
|
||||||
const coreDir = workDir + '/core';
|
const coreDir = workDir + "/core";
|
||||||
const outDir = workDir + '/output';
|
const outDir = workDir + "/output";
|
||||||
|
|
||||||
// Panel translations which should be split from the core translations. These
|
// Panel translations which should be split from the core translations. These
|
||||||
// should mirror the fragment definitions in polymer.json, so that we load
|
// should mirror the fragment definitions in polymer.json, so that we load
|
||||||
// additional resources at equivalent points.
|
// additional resources at equivalent points.
|
||||||
const TRANSLATION_FRAGMENTS = [
|
const TRANSLATION_FRAGMENTS = [
|
||||||
'config',
|
"config",
|
||||||
'history',
|
"history",
|
||||||
'logbook',
|
"logbook",
|
||||||
'mailbox',
|
"mailbox",
|
||||||
'profile',
|
"profile",
|
||||||
'shopping-list',
|
"shopping-list",
|
||||||
'page-authorize',
|
"page-authorize",
|
||||||
'page-onboarding',
|
"page-onboarding",
|
||||||
];
|
];
|
||||||
|
|
||||||
const tasks = [];
|
const tasks = [];
|
||||||
|
|
||||||
function recursiveFlatten(prefix, data) {
|
function recursiveFlatten(prefix, data) {
|
||||||
let output = {};
|
let output = {};
|
||||||
Object.keys(data).forEach(function (key) {
|
Object.keys(data).forEach(function(key) {
|
||||||
if (typeof (data[key]) === 'object') {
|
if (typeof data[key] === "object") {
|
||||||
output = Object.assign({}, output, recursiveFlatten(prefix + key + '.', data[key]));
|
output = Object.assign(
|
||||||
|
{},
|
||||||
|
output,
|
||||||
|
recursiveFlatten(prefix + key + ".", data[key])
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
output[prefix + key] = data[key];
|
output[prefix + key] = data[key];
|
||||||
}
|
}
|
||||||
@@ -43,14 +47,14 @@ function recursiveFlatten(prefix, data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function flatten(data) {
|
function flatten(data) {
|
||||||
return recursiveFlatten('', data);
|
return recursiveFlatten("", data);
|
||||||
}
|
}
|
||||||
|
|
||||||
function emptyFilter(data) {
|
function emptyFilter(data) {
|
||||||
const newData = {};
|
const newData = {};
|
||||||
Object.keys(data).forEach((key) => {
|
Object.keys(data).forEach((key) => {
|
||||||
if (data[key]) {
|
if (data[key]) {
|
||||||
if (typeof (data[key]) === 'object') {
|
if (typeof data[key] === "object") {
|
||||||
newData[key] = emptyFilter(data[key]);
|
newData[key] = emptyFilter(data[key]);
|
||||||
} else {
|
} else {
|
||||||
newData[key] = data[key];
|
newData[key] = data[key];
|
||||||
@@ -70,16 +74,18 @@ function emptyFilter(data) {
|
|||||||
* @link https://docs.lokalise.co/article/KO5SZWLLsy-key-referencing
|
* @link https://docs.lokalise.co/article/KO5SZWLLsy-key-referencing
|
||||||
*/
|
*/
|
||||||
const re_key_reference = /\[%key:([^%]+)%\]/;
|
const re_key_reference = /\[%key:([^%]+)%\]/;
|
||||||
function lokalise_transform (data, original) {
|
function lokalise_transform(data, original) {
|
||||||
const output = {};
|
const output = {};
|
||||||
Object.entries(data).forEach(([key, value]) => {
|
Object.entries(data).forEach(([key, value]) => {
|
||||||
if (value instanceof Object) {
|
if (value instanceof Object) {
|
||||||
output[key] = lokalise_transform(value, original);
|
output[key] = lokalise_transform(value, original);
|
||||||
} else {
|
} else {
|
||||||
output[key] = value.replace(re_key_reference, (match, key) => {
|
output[key] = value.replace(re_key_reference, (match, key) => {
|
||||||
const replace = key.split('::').reduce((tr, k) => tr[k], original);
|
const replace = key.split("::").reduce((tr, k) => tr[k], original);
|
||||||
if (typeof replace !== 'string') {
|
if (typeof replace !== "string") {
|
||||||
throw Error(`Invalid key placeholder ${key} in src/translations/en.json`);
|
throw Error(
|
||||||
|
`Invalid key placeholder ${key} in src/translations/en.json`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return replace;
|
return replace;
|
||||||
});
|
});
|
||||||
@@ -97,21 +103,24 @@ function lokalise_transform (data, original) {
|
|||||||
* project is buildable immediately after merging new translation keys, since
|
* project is buildable immediately after merging new translation keys, since
|
||||||
* the Lokalise update to translations/en.json will not happen immediately.
|
* the Lokalise update to translations/en.json will not happen immediately.
|
||||||
*/
|
*/
|
||||||
let taskName = 'build-master-translation';
|
let taskName = "build-master-translation";
|
||||||
gulp.task(taskName, function () {
|
gulp.task(taskName, function() {
|
||||||
return gulp.src('src/translations/en.json')
|
return gulp
|
||||||
.pipe(transform(function(data, file) {
|
.src("src/translations/en.json")
|
||||||
|
.pipe(
|
||||||
|
transform(function(data, file) {
|
||||||
return lokalise_transform(data, data);
|
return lokalise_transform(data, data);
|
||||||
}))
|
})
|
||||||
.pipe(rename('translationMaster.json'))
|
)
|
||||||
|
.pipe(rename("translationMaster.json"))
|
||||||
.pipe(gulp.dest(workDir));
|
.pipe(gulp.dest(workDir));
|
||||||
});
|
});
|
||||||
tasks.push(taskName);
|
tasks.push(taskName);
|
||||||
|
|
||||||
taskName = 'build-merged-translations';
|
taskName = "build-merged-translations";
|
||||||
gulp.task(taskName, ['build-master-translation'], function () {
|
gulp.task(taskName, ["build-master-translation"], function() {
|
||||||
return gulp.src(inDir + '/*.json')
|
return gulp.src(inDir + "/*.json").pipe(
|
||||||
.pipe(foreach(function(stream, file) {
|
foreach(function(stream, file) {
|
||||||
// For each language generate a merged json file. It begins with the master
|
// For each language generate a merged json file. It begins with the master
|
||||||
// translation as a failsafe for untranslated strings, and merges all parent
|
// translation as a failsafe for untranslated strings, and merges all parent
|
||||||
// tags into one file for each specific subtag
|
// tags into one file for each specific subtag
|
||||||
@@ -119,97 +128,119 @@ gulp.task(taskName, ['build-master-translation'], function () {
|
|||||||
// TODO: This is a naive interpretation of BCP47 that should be improved.
|
// TODO: This is a naive interpretation of BCP47 that should be improved.
|
||||||
// Will be OK for now as long as we don't have anything more complicated
|
// Will be OK for now as long as we don't have anything more complicated
|
||||||
// than a base translation + region.
|
// than a base translation + region.
|
||||||
const tr = path.basename(file.history[0], '.json');
|
const tr = path.basename(file.history[0], ".json");
|
||||||
const subtags = tr.split('-');
|
const subtags = tr.split("-");
|
||||||
const src = [workDir + '/translationMaster.json'];
|
const src = [workDir + "/translationMaster.json"];
|
||||||
for (let i = 1; i <= subtags.length; i++) {
|
for (let i = 1; i <= subtags.length; i++) {
|
||||||
const lang = subtags.slice(0, i).join('-');
|
const lang = subtags.slice(0, i).join("-");
|
||||||
src.push(inDir + '/' + lang + '.json');
|
src.push(inDir + "/" + lang + ".json");
|
||||||
}
|
}
|
||||||
return gulp.src(src)
|
return gulp
|
||||||
.pipe(transform(data => emptyFilter(data)))
|
.src(src)
|
||||||
.pipe(merge({
|
.pipe(transform((data) => emptyFilter(data)))
|
||||||
fileName: tr + '.json',
|
.pipe(
|
||||||
}))
|
merge({
|
||||||
|
fileName: tr + ".json",
|
||||||
|
})
|
||||||
|
)
|
||||||
.pipe(gulp.dest(fullDir));
|
.pipe(gulp.dest(fullDir));
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
});
|
});
|
||||||
tasks.push(taskName);
|
tasks.push(taskName);
|
||||||
|
|
||||||
const splitTasks = [];
|
const splitTasks = [];
|
||||||
TRANSLATION_FRAGMENTS.forEach((fragment) => {
|
TRANSLATION_FRAGMENTS.forEach((fragment) => {
|
||||||
taskName = 'build-translation-fragment-' + fragment;
|
taskName = "build-translation-fragment-" + fragment;
|
||||||
gulp.task(taskName, ['build-merged-translations'], function () {
|
gulp.task(taskName, ["build-merged-translations"], function() {
|
||||||
// Return only the translations for this fragment.
|
// Return only the translations for this fragment.
|
||||||
return gulp.src(fullDir + '/*.json')
|
return gulp
|
||||||
.pipe(transform(data => ({
|
.src(fullDir + "/*.json")
|
||||||
|
.pipe(
|
||||||
|
transform((data) => ({
|
||||||
ui: {
|
ui: {
|
||||||
panel: {
|
panel: {
|
||||||
[fragment]: data.ui.panel[fragment],
|
[fragment]: data.ui.panel[fragment],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})))
|
}))
|
||||||
.pipe(gulp.dest(workDir + '/' + fragment));
|
)
|
||||||
|
.pipe(gulp.dest(workDir + "/" + fragment));
|
||||||
});
|
});
|
||||||
tasks.push(taskName);
|
tasks.push(taskName);
|
||||||
splitTasks.push(taskName);
|
splitTasks.push(taskName);
|
||||||
});
|
});
|
||||||
|
|
||||||
taskName = 'build-translation-core';
|
taskName = "build-translation-core";
|
||||||
gulp.task(taskName, ['build-merged-translations'], function () {
|
gulp.task(taskName, ["build-merged-translations"], function() {
|
||||||
// Remove the fragment translations from the core translation.
|
// Remove the fragment translations from the core translation.
|
||||||
return gulp.src(fullDir + '/*.json')
|
return gulp
|
||||||
.pipe(transform((data) => {
|
.src(fullDir + "/*.json")
|
||||||
|
.pipe(
|
||||||
|
transform((data) => {
|
||||||
TRANSLATION_FRAGMENTS.forEach((fragment) => {
|
TRANSLATION_FRAGMENTS.forEach((fragment) => {
|
||||||
delete data.ui.panel[fragment];
|
delete data.ui.panel[fragment];
|
||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
}))
|
})
|
||||||
|
)
|
||||||
.pipe(gulp.dest(coreDir));
|
.pipe(gulp.dest(coreDir));
|
||||||
});
|
});
|
||||||
tasks.push(taskName);
|
tasks.push(taskName);
|
||||||
splitTasks.push(taskName);
|
splitTasks.push(taskName);
|
||||||
|
|
||||||
taskName = 'build-flattened-translations';
|
taskName = "build-flattened-translations";
|
||||||
gulp.task(taskName, splitTasks, function () {
|
gulp.task(taskName, splitTasks, function() {
|
||||||
// Flatten the split versions of our translations, and move them into outDir
|
// Flatten the split versions of our translations, and move them into outDir
|
||||||
return gulp.src(
|
return gulp
|
||||||
TRANSLATION_FRAGMENTS.map(fragment => workDir + '/' + fragment + '/*.json')
|
.src(
|
||||||
.concat(coreDir + '/*.json'),
|
TRANSLATION_FRAGMENTS.map(
|
||||||
{ base: workDir },
|
(fragment) => workDir + "/" + fragment + "/*.json"
|
||||||
|
).concat(coreDir + "/*.json"),
|
||||||
|
{ base: workDir }
|
||||||
)
|
)
|
||||||
.pipe(transform(function (data) {
|
.pipe(
|
||||||
|
transform(function(data) {
|
||||||
// Polymer.AppLocalizeBehavior requires flattened json
|
// Polymer.AppLocalizeBehavior requires flattened json
|
||||||
return flatten(data);
|
return flatten(data);
|
||||||
}))
|
})
|
||||||
|
)
|
||||||
.pipe(minify())
|
.pipe(minify())
|
||||||
.pipe(rename((filePath) => {
|
.pipe(
|
||||||
if (filePath.dirname === 'core') {
|
rename((filePath) => {
|
||||||
filePath.dirname = '';
|
if (filePath.dirname === "core") {
|
||||||
|
filePath.dirname = "";
|
||||||
}
|
}
|
||||||
}))
|
})
|
||||||
|
)
|
||||||
.pipe(gulp.dest(outDir));
|
.pipe(gulp.dest(outDir));
|
||||||
});
|
});
|
||||||
tasks.push(taskName);
|
tasks.push(taskName);
|
||||||
|
|
||||||
taskName = 'build-translation-fingerprints';
|
taskName = "build-translation-fingerprints";
|
||||||
gulp.task(taskName, ['build-flattened-translations'], function () {
|
gulp.task(taskName, ["build-flattened-translations"], function() {
|
||||||
return gulp.src(outDir + '/**/*.json')
|
return gulp
|
||||||
.pipe(rename({
|
.src(outDir + "/**/*.json")
|
||||||
extname: '',
|
.pipe(
|
||||||
}))
|
rename({
|
||||||
.pipe(hash({
|
extname: "",
|
||||||
algorithm: 'md5',
|
})
|
||||||
|
)
|
||||||
|
.pipe(
|
||||||
|
hash({
|
||||||
|
algorithm: "md5",
|
||||||
hashLength: 32,
|
hashLength: 32,
|
||||||
template: '<%= name %>-<%= hash %>.json',
|
template: "<%= name %>-<%= hash %>.json",
|
||||||
}))
|
})
|
||||||
.pipe(hash.manifest('translationFingerprints.json'))
|
)
|
||||||
.pipe(transform(function (data) {
|
.pipe(hash.manifest("translationFingerprints.json"))
|
||||||
|
.pipe(
|
||||||
|
transform(function(data) {
|
||||||
// After generating fingerprints of our translation files, consolidate
|
// After generating fingerprints of our translation files, consolidate
|
||||||
// all translation fragment fingerprints under the translation name key
|
// all translation fragment fingerprints under the translation name key
|
||||||
const newData = {};
|
const newData = {};
|
||||||
Object.entries(data).forEach(([key, value]) => {
|
Object.entries(data).forEach(([key, value]) => {
|
||||||
const parts = key.split('/');
|
const parts = key.split("/");
|
||||||
let translation = key;
|
let translation = key;
|
||||||
if (parts.length === 2) {
|
if (parts.length === 2) {
|
||||||
translation = parts[1];
|
translation = parts[1];
|
||||||
@@ -222,36 +253,44 @@ gulp.task(taskName, ['build-flattened-translations'], function () {
|
|||||||
newData[translation].fingerprints[key] = value;
|
newData[translation].fingerprints[key] = value;
|
||||||
});
|
});
|
||||||
return newData;
|
return newData;
|
||||||
}))
|
})
|
||||||
|
)
|
||||||
.pipe(gulp.dest(workDir));
|
.pipe(gulp.dest(workDir));
|
||||||
});
|
});
|
||||||
tasks.push(taskName);
|
tasks.push(taskName);
|
||||||
|
|
||||||
taskName = 'build-translations';
|
taskName = "build-translations";
|
||||||
gulp.task(taskName, ['build-translation-fingerprints'], function () {
|
gulp.task(taskName, ["build-translation-fingerprints"], function() {
|
||||||
return gulp.src([
|
return gulp
|
||||||
'src/translations/translationMetadata.json',
|
.src([
|
||||||
workDir + '/translationFingerprints.json',
|
"src/translations/translationMetadata.json",
|
||||||
|
workDir + "/translationFingerprints.json",
|
||||||
])
|
])
|
||||||
.pipe(merge({}))
|
.pipe(merge({}))
|
||||||
.pipe(transform(function (data) {
|
.pipe(
|
||||||
|
transform(function(data) {
|
||||||
const newData = {};
|
const newData = {};
|
||||||
Object.entries(data).forEach(([key, value]) => {
|
Object.entries(data).forEach(([key, value]) => {
|
||||||
// Filter out translations without native name.
|
// Filter out translations without native name.
|
||||||
if (data[key].nativeName) {
|
if (data[key].nativeName) {
|
||||||
newData[key] = data[key];
|
newData[key] = data[key];
|
||||||
} else {
|
} else {
|
||||||
console.warn(`Skipping language ${key}. Native name was not translated.`);
|
console.warn(
|
||||||
|
`Skipping language ${key}. Native name was not translated.`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (data[key]) newData[key] = value;
|
if (data[key]) newData[key] = value;
|
||||||
});
|
});
|
||||||
return newData;
|
return newData;
|
||||||
}))
|
})
|
||||||
.pipe(transform(data => ({
|
)
|
||||||
|
.pipe(
|
||||||
|
transform((data) => ({
|
||||||
fragments: TRANSLATION_FRAGMENTS,
|
fragments: TRANSLATION_FRAGMENTS,
|
||||||
translations: data,
|
translations: data,
|
||||||
})))
|
}))
|
||||||
.pipe(rename('translationMetadata.json'))
|
)
|
||||||
|
.pipe(rename("translationMetadata.json"))
|
||||||
.pipe(gulp.dest(workDir));
|
.pipe(gulp.dest(workDir));
|
||||||
});
|
});
|
||||||
tasks.push(taskName);
|
tasks.push(taskName);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
const path = require('path');
|
const path = require("path");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// Target directory for the build.
|
// Target directory for the build.
|
||||||
buildDir: path.resolve(__dirname, 'build'),
|
buildDir: path.resolve(__dirname, "build"),
|
||||||
// Path where the Hass.io frontend will be publicly available.
|
// Path where the Hass.io frontend will be publicly available.
|
||||||
publicPath: '/api/hassio/app',
|
publicPath: "/api/hassio/app",
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
const fs = require('fs');
|
const fs = require("fs");
|
||||||
const {
|
const { findIcons, generateIconset } = require("../../gulp/tasks/gen-icons.js");
|
||||||
findIcons,
|
|
||||||
generateIconset,
|
|
||||||
} = require('../../gulp/tasks/gen-icons.js');
|
|
||||||
|
|
||||||
const MENU_BUTTON_ICON = 'menu';
|
const MENU_BUTTON_ICON = "menu";
|
||||||
|
|
||||||
function genHassioIcons() {
|
function genHassioIcons() {
|
||||||
const iconNames = findIcons('./src', 'hassio').concat(MENU_BUTTON_ICON);
|
const iconNames = findIcons("./src", "hassio").concat(MENU_BUTTON_ICON);
|
||||||
fs.writeFileSync('./hassio-icons.html', generateIconset('hassio', iconNames));
|
fs.writeFileSync("./hassio-icons.html", generateIconset("hassio", iconNames));
|
||||||
}
|
}
|
||||||
|
|
||||||
genHassioIcons();
|
genHassioIcons();
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import '@polymer/paper-card/paper-card.js';
|
import "@polymer/paper-card/paper-card.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/hassio-card-content.js';
|
import "../components/hassio-card-content.js";
|
||||||
import '../resources/hassio-style.js';
|
import "../resources/hassio-style.js";
|
||||||
import NavigateMixin from '../../../src/mixins/navigate-mixin.js';
|
import NavigateMixin from "../../../src/mixins/navigate-mixin.js";
|
||||||
|
|
||||||
class HassioAddonRepository extends NavigateMixin(PolymerElement) {
|
class HassioAddonRepository extends NavigateMixin(PolymerElement) {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -52,17 +52,23 @@ class HassioAddonRepository extends NavigateMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
computeIcon(addon) {
|
computeIcon(addon) {
|
||||||
return addon.installed && addon.installed !== addon.version ? 'hassio:arrow-up-bold-circle' : 'hassio:puzzle';
|
return addon.installed && addon.installed !== addon.version
|
||||||
|
? "hassio:arrow-up-bold-circle"
|
||||||
|
: "hassio:puzzle";
|
||||||
}
|
}
|
||||||
|
|
||||||
computeIconTitle(addon) {
|
computeIconTitle(addon) {
|
||||||
if (addon.installed) return addon.installed !== addon.version ? 'New version available' : 'Add-on is installed';
|
if (addon.installed)
|
||||||
return 'Add-on is not installed';
|
return addon.installed !== addon.version
|
||||||
|
? "New version available"
|
||||||
|
: "Add-on is installed";
|
||||||
|
return "Add-on is not installed";
|
||||||
}
|
}
|
||||||
|
|
||||||
computeIconClass(addon) {
|
computeIconClass(addon) {
|
||||||
if (addon.installed) return addon.installed !== addon.version ? 'update' : 'installed';
|
if (addon.installed)
|
||||||
return '';
|
return addon.installed !== addon.version ? "update" : "installed";
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
addonTapped(ev) {
|
addonTapped(ev) {
|
||||||
@@ -70,4 +76,4 @@ class HassioAddonRepository extends NavigateMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-addon-repository', HassioAddonRepository);
|
customElements.define("hassio-addon-repository", HassioAddonRepository);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import './hassio-addon-repository.js';
|
import "./hassio-addon-repository.js";
|
||||||
import './hassio-repositories-editor.js';
|
import "./hassio-repositories-editor.js";
|
||||||
|
|
||||||
class HassioAddonStore extends PolymerElement {
|
class HassioAddonStore extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -30,7 +30,7 @@ class HassioAddonStore extends PolymerElement {
|
|||||||
|
|
||||||
ready() {
|
ready() {
|
||||||
super.ready();
|
super.ready();
|
||||||
this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
|
this.addEventListener("hass-api-called", (ev) => this.apiCalled(ev));
|
||||||
this.loadData();
|
this.loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,42 +41,45 @@ class HassioAddonStore extends PolymerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sortRepos(a, b) {
|
sortRepos(a, b) {
|
||||||
if (a.slug === 'local') {
|
if (a.slug === "local") {
|
||||||
return -1;
|
return -1;
|
||||||
} if (b.slug === 'local') {
|
}
|
||||||
|
if (b.slug === "local") {
|
||||||
return 1;
|
return 1;
|
||||||
} if (a.slug === 'core') {
|
}
|
||||||
|
if (a.slug === "core") {
|
||||||
return -1;
|
return -1;
|
||||||
} if (b.slug === 'core') {
|
}
|
||||||
|
if (b.slug === "core") {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return a.name < b.name ? -1 : 1;
|
return a.name < b.name ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
computeAddons(repo) {
|
computeAddons(repo) {
|
||||||
return this.addons.filter(function (addon) {
|
return this.addons.filter(function(addon) {
|
||||||
return addon.repository === repo;
|
return addon.repository === repo;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadData() {
|
loadData() {
|
||||||
this.hass.callApi('get', 'hassio/addons')
|
this.hass.callApi("get", "hassio/addons").then(
|
||||||
.then((info) => {
|
(info) => {
|
||||||
this.addons = info.data.addons;
|
this.addons = info.data.addons;
|
||||||
this.repos = info.data.repositories;
|
this.repos = info.data.repositories;
|
||||||
}, () => {
|
},
|
||||||
|
() => {
|
||||||
this.addons = [];
|
this.addons = [];
|
||||||
this.repos = [];
|
this.repos = [];
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
refreshData() {
|
refreshData() {
|
||||||
this.hass.callApi('post', 'hassio/addons/reload')
|
this.hass.callApi("post", "hassio/addons/reload").then(() => {
|
||||||
.then(() => {
|
|
||||||
this.loadData();
|
this.loadData();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-addon-store', HassioAddonStore);
|
customElements.define("hassio-addon-store", HassioAddonStore);
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import '@polymer/iron-icon/iron-icon.js';
|
import "@polymer/iron-icon/iron-icon.js";
|
||||||
import '@polymer/paper-card/paper-card.js';
|
import "@polymer/paper-card/paper-card.js";
|
||||||
import '@polymer/paper-input/paper-input.js';
|
import "@polymer/paper-input/paper-input.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../../src/components/buttons/ha-call-api-button.js';
|
import "../../../src/components/buttons/ha-call-api-button.js";
|
||||||
import '../components/hassio-card-content.js';
|
import "../components/hassio-card-content.js";
|
||||||
import '../resources/hassio-style.js';
|
import "../resources/hassio-style.js";
|
||||||
|
|
||||||
class HassioRepositoriesEditor extends PolymerElement {
|
class HassioRepositoriesEditor extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -60,7 +60,7 @@ class HassioRepositoriesEditor extends PolymerElement {
|
|||||||
hass: Object,
|
hass: Object,
|
||||||
repos: {
|
repos: {
|
||||||
type: Array,
|
type: Array,
|
||||||
observer: 'reposChanged',
|
observer: "reposChanged",
|
||||||
},
|
},
|
||||||
repoList: Array,
|
repoList: Array,
|
||||||
repoUrl: String,
|
repoUrl: String,
|
||||||
@@ -68,8 +68,10 @@ class HassioRepositoriesEditor extends PolymerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reposChanged(repos) {
|
reposChanged(repos) {
|
||||||
this.repoList = repos.filter(repo => repo.slug !== 'core' && repo.slug !== 'local');
|
this.repoList = repos.filter(
|
||||||
this.repoUrl = '';
|
(repo) => repo.slug !== "core" && repo.slug !== "local"
|
||||||
|
);
|
||||||
|
this.repoUrl = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
sortRepos(a, b) {
|
sortRepos(a, b) {
|
||||||
@@ -77,15 +79,17 @@ class HassioRepositoriesEditor extends PolymerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
computeRemoveRepoData(repoList, url) {
|
computeRemoveRepoData(repoList, url) {
|
||||||
const list = repoList.filter(repo => repo.url !== url).map(repo => repo.url);
|
const list = repoList
|
||||||
|
.filter((repo) => repo.url !== url)
|
||||||
|
.map((repo) => repo.url);
|
||||||
return { addons_repositories: list };
|
return { addons_repositories: list };
|
||||||
}
|
}
|
||||||
|
|
||||||
computeAddRepoData(repoList, url) {
|
computeAddRepoData(repoList, url) {
|
||||||
const list = repoList ? repoList.map(repo => repo.url) : [];
|
const list = repoList ? repoList.map((repo) => repo.url) : [];
|
||||||
list.push(url);
|
list.push(url);
|
||||||
return { addons_repositories: list };
|
return { addons_repositories: list };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-repositories-editor', HassioRepositoriesEditor);
|
customElements.define("hassio-repositories-editor", HassioRepositoriesEditor);
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import 'web-animations-js/web-animations-next-lite.min.js';
|
import "web-animations-js/web-animations-next-lite.min.js";
|
||||||
|
|
||||||
import '@polymer/paper-button/paper-button.js';
|
import "@polymer/paper-button/paper-button.js";
|
||||||
import '@polymer/paper-card/paper-card.js';
|
import "@polymer/paper-card/paper-card.js";
|
||||||
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
import "@polymer/paper-dropdown-menu/paper-dropdown-menu.js";
|
||||||
import '@polymer/paper-item/paper-item.js';
|
import "@polymer/paper-item/paper-item.js";
|
||||||
import '@polymer/paper-listbox/paper-listbox.js';
|
import "@polymer/paper-listbox/paper-listbox.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../../src/resources/ha-style.js';
|
import "../../../src/resources/ha-style.js";
|
||||||
import EventsMixin from '../../../src/mixins/events-mixin.js';
|
import EventsMixin from "../../../src/mixins/events-mixin.js";
|
||||||
|
|
||||||
class HassioAddonAudio extends EventsMixin(PolymerElement) {
|
class HassioAddonAudio extends EventsMixin(PolymerElement) {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -64,7 +64,7 @@ class HassioAddonAudio extends EventsMixin(PolymerElement) {
|
|||||||
hass: Object,
|
hass: Object,
|
||||||
addon: {
|
addon: {
|
||||||
type: Object,
|
type: Object,
|
||||||
observer: 'addonChanged'
|
observer: "addonChanged",
|
||||||
},
|
},
|
||||||
inputDevices: Array,
|
inputDevices: Array,
|
||||||
outputDevices: Array,
|
outputDevices: Array,
|
||||||
@@ -76,40 +76,55 @@ class HassioAddonAudio extends EventsMixin(PolymerElement) {
|
|||||||
|
|
||||||
addonChanged(addon) {
|
addonChanged(addon) {
|
||||||
this.setProperties({
|
this.setProperties({
|
||||||
selectedInput: addon.audio_input || 'null',
|
selectedInput: addon.audio_input || "null",
|
||||||
selectedOutput: addon.audio_output || 'null'
|
selectedOutput: addon.audio_output || "null",
|
||||||
});
|
});
|
||||||
if (this.outputDevices) return;
|
if (this.outputDevices) return;
|
||||||
|
|
||||||
const noDevice = [{ device: 'null', name: '-' }];
|
const noDevice = [{ device: "null", name: "-" }];
|
||||||
this.hass.callApi('get', 'hassio/hardware/audio').then((resp) => {
|
this.hass.callApi("get", "hassio/hardware/audio").then(
|
||||||
|
(resp) => {
|
||||||
const dev = resp.data.audio;
|
const dev = resp.data.audio;
|
||||||
const input = Object.keys(dev.input).map(key => ({ device: key, name: dev.input[key] }));
|
const input = Object.keys(dev.input).map((key) => ({
|
||||||
const output = Object.keys(dev.output).map(key => ({ device: key, name: dev.output[key] }));
|
device: key,
|
||||||
|
name: dev.input[key],
|
||||||
|
}));
|
||||||
|
const output = Object.keys(dev.output).map((key) => ({
|
||||||
|
device: key,
|
||||||
|
name: dev.output[key],
|
||||||
|
}));
|
||||||
this.setProperties({
|
this.setProperties({
|
||||||
inputDevices: noDevice.concat(input),
|
inputDevices: noDevice.concat(input),
|
||||||
outputDevices: noDevice.concat(output)
|
outputDevices: noDevice.concat(output),
|
||||||
});
|
});
|
||||||
}, () => {
|
},
|
||||||
|
() => {
|
||||||
this.setProperties({
|
this.setProperties({
|
||||||
inputDevices: noDevice,
|
inputDevices: noDevice,
|
||||||
outputDevices: noDevice
|
outputDevices: noDevice,
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
_saveSettings() {
|
_saveSettings() {
|
||||||
this.error = null;
|
this.error = null;
|
||||||
const path = `hassio/addons/${this.addon.slug}/options`;
|
const path = `hassio/addons/${this.addon.slug}/options`;
|
||||||
this.hass.callApi('post', path, {
|
this.hass
|
||||||
audio_input: this.selectedInput === 'null' ? null : this.selectedInput,
|
.callApi("post", path, {
|
||||||
audio_output: this.selectedOutput === 'null' ? null : this.selectedOutput
|
audio_input: this.selectedInput === "null" ? null : this.selectedInput,
|
||||||
}).then(() => {
|
audio_output:
|
||||||
this.fire('hass-api-called', { success: true, path: path });
|
this.selectedOutput === "null" ? null : this.selectedOutput,
|
||||||
}, (resp) => {
|
})
|
||||||
|
.then(
|
||||||
|
() => {
|
||||||
|
this.fire("hass-api-called", { success: true, path: path });
|
||||||
|
},
|
||||||
|
(resp) => {
|
||||||
this.error = resp.body.message;
|
this.error = resp.body.message;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-addon-audio', HassioAddonAudio);
|
customElements.define("hassio-addon-audio", HassioAddonAudio);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import '@polymer/iron-autogrow-textarea/iron-autogrow-textarea.js';
|
import "@polymer/iron-autogrow-textarea/iron-autogrow-textarea.js";
|
||||||
import '@polymer/paper-button/paper-button.js';
|
import "@polymer/paper-button/paper-button.js";
|
||||||
import '@polymer/paper-card/paper-card.js';
|
import "@polymer/paper-card/paper-card.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../../src/components/buttons/ha-call-api-button.js';
|
import "../../../src/components/buttons/ha-call-api-button.js";
|
||||||
|
|
||||||
class HassioAddonConfig extends PolymerElement {
|
class HassioAddonConfig extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -52,12 +52,12 @@ class HassioAddonConfig extends PolymerElement {
|
|||||||
hass: Object,
|
hass: Object,
|
||||||
addon: {
|
addon: {
|
||||||
type: Object,
|
type: Object,
|
||||||
observer: 'addonChanged',
|
observer: "addonChanged",
|
||||||
},
|
},
|
||||||
addonSlug: String,
|
addonSlug: String,
|
||||||
config: {
|
config: {
|
||||||
type: String,
|
type: String,
|
||||||
observer: 'configChanged',
|
observer: "configChanged",
|
||||||
},
|
},
|
||||||
configParsed: Object,
|
configParsed: Object,
|
||||||
error: String,
|
error: String,
|
||||||
@@ -71,15 +71,15 @@ class HassioAddonConfig extends PolymerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addonChanged(addon) {
|
addonChanged(addon) {
|
||||||
this.config = addon ? JSON.stringify(addon.options, null, 2) : '';
|
this.config = addon ? JSON.stringify(addon.options, null, 2) : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
configChanged(config) {
|
configChanged(config) {
|
||||||
try {
|
try {
|
||||||
this.$.config.classList.remove('syntaxerror');
|
this.$.config.classList.remove("syntaxerror");
|
||||||
this.configParsed = JSON.parse(config);
|
this.configParsed = JSON.parse(config);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.$.config.classList.add('syntaxerror');
|
this.$.config.classList.add("syntaxerror");
|
||||||
this.configParsed = null;
|
this.configParsed = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,12 +87,14 @@ class HassioAddonConfig extends PolymerElement {
|
|||||||
saveTapped() {
|
saveTapped() {
|
||||||
this.error = null;
|
this.error = null;
|
||||||
|
|
||||||
this.hass.callApi('post', `hassio/addons/${this.addonSlug}/options`, {
|
this.hass
|
||||||
options: this.configParsed
|
.callApi("post", `hassio/addons/${this.addonSlug}/options`, {
|
||||||
}).catch((resp) => {
|
options: this.configParsed,
|
||||||
|
})
|
||||||
|
.catch((resp) => {
|
||||||
this.error = resp.body.message;
|
this.error = resp.body.message;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-addon-config', HassioAddonConfig);
|
customElements.define("hassio-addon-config", HassioAddonConfig);
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import '@polymer/iron-icon/iron-icon.js';
|
import "@polymer/iron-icon/iron-icon.js";
|
||||||
import '@polymer/paper-button/paper-button.js';
|
import "@polymer/paper-button/paper-button.js";
|
||||||
import '@polymer/paper-card/paper-card.js';
|
import "@polymer/paper-card/paper-card.js";
|
||||||
import '@polymer/paper-toggle-button/paper-toggle-button.js';
|
import "@polymer/paper-toggle-button/paper-toggle-button.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../../src/components/buttons/ha-call-api-button.js';
|
import "../../../src/components/buttons/ha-call-api-button.js";
|
||||||
import '../../../src/components/ha-markdown.js';
|
import "../../../src/components/ha-markdown.js";
|
||||||
import '../../../src/resources/ha-style.js';
|
import "../../../src/resources/ha-style.js";
|
||||||
import EventsMixin from '../../../src/mixins/events-mixin.js';
|
import EventsMixin from "../../../src/mixins/events-mixin.js";
|
||||||
|
|
||||||
import '../components/hassio-card-content.js';
|
import "../components/hassio-card-content.js";
|
||||||
|
|
||||||
class HassioAddonInfo extends EventsMixin(PolymerElement) {
|
class HassioAddonInfo extends EventsMixin(PolymerElement) {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -157,21 +157,26 @@ class HassioAddonInfo extends EventsMixin(PolymerElement) {
|
|||||||
addonSlug: String,
|
addonSlug: String,
|
||||||
isRunning: {
|
isRunning: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
computed: 'computeIsRunning(addon)',
|
computed: "computeIsRunning(addon)",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
computeIsRunning(addon) {
|
computeIsRunning(addon) {
|
||||||
return addon && addon.state === 'started';
|
return addon && addon.state === "started";
|
||||||
}
|
}
|
||||||
|
|
||||||
computeUpdateAvailable(addon) {
|
computeUpdateAvailable(addon) {
|
||||||
return addon && !addon.detached && addon.version && addon.version !== addon.last_version;
|
return (
|
||||||
|
addon &&
|
||||||
|
!addon.detached &&
|
||||||
|
addon.version &&
|
||||||
|
addon.version !== addon.last_version
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pathWebui(webui) {
|
pathWebui(webui) {
|
||||||
return webui && webui.replace('[HOST]', document.location.hostname);
|
return webui && webui.replace("[HOST]", document.location.hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
computeShowWebUI(webui, isRunning) {
|
computeShowWebUI(webui, isRunning) {
|
||||||
@@ -179,49 +184,54 @@ class HassioAddonInfo extends EventsMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
computeStartOnBoot(state) {
|
computeStartOnBoot(state) {
|
||||||
return state === 'auto';
|
return state === "auto";
|
||||||
}
|
}
|
||||||
|
|
||||||
startOnBootToggled() {
|
startOnBootToggled() {
|
||||||
const data = { boot: this.addon.boot === 'auto' ? 'manual' : 'auto' };
|
const data = { boot: this.addon.boot === "auto" ? "manual" : "auto" };
|
||||||
this.hass.callApi('POST', `hassio/addons/${this.addonSlug}/options`, data);
|
this.hass.callApi("POST", `hassio/addons/${this.addonSlug}/options`, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
autoUpdateToggled() {
|
autoUpdateToggled() {
|
||||||
const data = { auto_update: !this.addon.auto_update };
|
const data = { auto_update: !this.addon.auto_update };
|
||||||
this.hass.callApi('POST', `hassio/addons/${this.addonSlug}/options`, data);
|
this.hass.callApi("POST", `hassio/addons/${this.addonSlug}/options`, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
openChangelog() {
|
openChangelog() {
|
||||||
this.hass.callApi('get', `hassio/addons/${this.addonSlug}/changelog`)
|
this.hass
|
||||||
.then(
|
.callApi("get", `hassio/addons/${this.addonSlug}/changelog`)
|
||||||
resp => resp,
|
.then((resp) => resp, () => "Error getting changelog")
|
||||||
() => 'Error getting changelog'
|
.then((content) => {
|
||||||
).then((content) => {
|
this.fire("hassio-markdown-dialog", {
|
||||||
this.fire('hassio-markdown-dialog', {
|
title: "Changelog",
|
||||||
title: 'Changelog',
|
|
||||||
content: content,
|
content: content,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_unistallClicked() {
|
_unistallClicked() {
|
||||||
if (!confirm('Are you sure you want to uninstall this add-on?')) {
|
if (!confirm("Are you sure you want to uninstall this add-on?")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const path = `hassio/addons/${this.addonSlug}/uninstall`;
|
const path = `hassio/addons/${this.addonSlug}/uninstall`;
|
||||||
const eventData = {
|
const eventData = {
|
||||||
path: path,
|
path: path,
|
||||||
};
|
};
|
||||||
this.hass.callApi('post', path).then((resp) => {
|
this.hass
|
||||||
|
.callApi("post", path)
|
||||||
|
.then(
|
||||||
|
(resp) => {
|
||||||
eventData.success = true;
|
eventData.success = true;
|
||||||
eventData.response = resp;
|
eventData.response = resp;
|
||||||
}, (resp) => {
|
},
|
||||||
|
(resp) => {
|
||||||
eventData.success = false;
|
eventData.success = false;
|
||||||
eventData.response = resp;
|
eventData.response = resp;
|
||||||
}).then(() => {
|
}
|
||||||
this.fire('hass-api-called', eventData);
|
)
|
||||||
|
.then(() => {
|
||||||
|
this.fire("hass-api-called", eventData);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define('hassio-addon-info', HassioAddonInfo);
|
customElements.define("hassio-addon-info", HassioAddonInfo);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import '@polymer/paper-button/paper-button.js';
|
import "@polymer/paper-button/paper-button.js";
|
||||||
import '@polymer/paper-card/paper-card.js';
|
import "@polymer/paper-card/paper-card.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../../src/resources/ha-style.js';
|
import "../../../src/resources/ha-style.js";
|
||||||
|
|
||||||
class HassioAddonLogs extends PolymerElement {
|
class HassioAddonLogs extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -33,7 +33,7 @@ class HassioAddonLogs extends PolymerElement {
|
|||||||
hass: Object,
|
hass: Object,
|
||||||
addonSlug: {
|
addonSlug: {
|
||||||
type: String,
|
type: String,
|
||||||
observer: 'addonSlugChanged',
|
observer: "addonSlugChanged",
|
||||||
},
|
},
|
||||||
log: String,
|
log: String,
|
||||||
};
|
};
|
||||||
@@ -41,7 +41,9 @@ class HassioAddonLogs extends PolymerElement {
|
|||||||
|
|
||||||
addonSlugChanged(slug) {
|
addonSlugChanged(slug) {
|
||||||
if (!this.hass) {
|
if (!this.hass) {
|
||||||
setTimeout(() => { this.addonChanged(slug); }, 0);
|
setTimeout(() => {
|
||||||
|
this.addonChanged(slug);
|
||||||
|
}, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,11 +51,12 @@ class HassioAddonLogs extends PolymerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
this.hass.callApi('get', `hassio/addons/${this.addonSlug}/logs`)
|
this.hass
|
||||||
|
.callApi("get", `hassio/addons/${this.addonSlug}/logs`)
|
||||||
.then((info) => {
|
.then((info) => {
|
||||||
this.log = info;
|
this.log = info;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-addon-logs', HassioAddonLogs);
|
customElements.define("hassio-addon-logs", HassioAddonLogs);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import '@polymer/paper-card/paper-card.js';
|
import "@polymer/paper-card/paper-card.js";
|
||||||
import '@polymer/paper-input/paper-input.js';
|
import "@polymer/paper-input/paper-input.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../../src/components/buttons/ha-call-api-button.js';
|
import "../../../src/components/buttons/ha-call-api-button.js";
|
||||||
import '../../../src/resources/ha-style.js';
|
import "../../../src/resources/ha-style.js";
|
||||||
import EventsMixin from '../../../src/mixins/events-mixin.js';
|
import EventsMixin from "../../../src/mixins/events-mixin.js";
|
||||||
|
|
||||||
class HassioAddonNetwork extends EventsMixin(PolymerElement) {
|
class HassioAddonNetwork extends EventsMixin(PolymerElement) {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -64,7 +64,7 @@ class HassioAddonNetwork extends EventsMixin(PolymerElement) {
|
|||||||
config: Object,
|
config: Object,
|
||||||
addon: {
|
addon: {
|
||||||
type: Object,
|
type: Object,
|
||||||
observer: 'addonChanged',
|
observer: "addonChanged",
|
||||||
},
|
},
|
||||||
error: String,
|
error: String,
|
||||||
resetData: {
|
resetData: {
|
||||||
@@ -80,29 +80,36 @@ class HassioAddonNetwork extends EventsMixin(PolymerElement) {
|
|||||||
if (!addon) return;
|
if (!addon) return;
|
||||||
|
|
||||||
const network = addon.network || {};
|
const network = addon.network || {};
|
||||||
const items = Object.keys(network).map(key => ({
|
const items = Object.keys(network).map((key) => ({
|
||||||
container: key,
|
container: key,
|
||||||
host: network[key]
|
host: network[key],
|
||||||
}));
|
}));
|
||||||
this.config = items.sort(function (el1, el2) { return el1.host - el2.host; });
|
this.config = items.sort(function(el1, el2) {
|
||||||
|
return el1.host - el2.host;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
saveTapped() {
|
saveTapped() {
|
||||||
this.error = null;
|
this.error = null;
|
||||||
const data = {};
|
const data = {};
|
||||||
this.config.forEach(function (item) {
|
this.config.forEach(function(item) {
|
||||||
data[item.container] = parseInt(item.host);
|
data[item.container] = parseInt(item.host);
|
||||||
});
|
});
|
||||||
const path = `hassio/addons/${this.addonSlug}/options`;
|
const path = `hassio/addons/${this.addonSlug}/options`;
|
||||||
|
|
||||||
this.hass.callApi('post', path, {
|
this.hass
|
||||||
network: data
|
.callApi("post", path, {
|
||||||
}).then(() => {
|
network: data,
|
||||||
this.fire('hass-api-called', { success: true, path: path });
|
})
|
||||||
}, (resp) => {
|
.then(
|
||||||
|
() => {
|
||||||
|
this.fire("hass-api-called", { success: true, path: path });
|
||||||
|
},
|
||||||
|
(resp) => {
|
||||||
this.error = resp.body.message;
|
this.error = resp.body.message;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-addon-network', HassioAddonNetwork);
|
customElements.define("hassio-addon-network", HassioAddonNetwork);
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
import '@polymer/app-layout/app-header-layout/app-header-layout.js';
|
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-header/app-header.js";
|
||||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
import "@polymer/app-layout/app-toolbar/app-toolbar.js";
|
||||||
import '@polymer/app-route/app-route.js';
|
import "@polymer/app-route/app-route.js";
|
||||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
import "@polymer/paper-icon-button/paper-icon-button.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../../src/components/ha-menu-button.js';
|
import "../../../src/components/ha-menu-button.js";
|
||||||
import '../../../src/resources/ha-style.js';
|
import "../../../src/resources/ha-style.js";
|
||||||
import '../hassio-markdown-dialog.js';
|
import "../hassio-markdown-dialog.js";
|
||||||
import './hassio-addon-audio.js';
|
import "./hassio-addon-audio.js";
|
||||||
import './hassio-addon-config.js';
|
import "./hassio-addon-config.js";
|
||||||
import './hassio-addon-info.js';
|
import "./hassio-addon-info.js";
|
||||||
import './hassio-addon-logs.js';
|
import "./hassio-addon-logs.js";
|
||||||
import './hassio-addon-network.js';
|
import "./hassio-addon-network.js";
|
||||||
|
|
||||||
class HassioAddonView extends PolymerElement {
|
class HassioAddonView extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -91,7 +91,7 @@ class HassioAddonView extends PolymerElement {
|
|||||||
route: Object,
|
route: Object,
|
||||||
routeData: {
|
routeData: {
|
||||||
type: Object,
|
type: Object,
|
||||||
observer: 'routeDataChanged',
|
observer: "routeDataChanged",
|
||||||
},
|
},
|
||||||
routeMatches: Boolean,
|
routeMatches: Boolean,
|
||||||
addon: Object,
|
addon: Object,
|
||||||
@@ -99,15 +99,17 @@ class HassioAddonView extends PolymerElement {
|
|||||||
markdownTitle: String,
|
markdownTitle: String,
|
||||||
markdownContent: {
|
markdownContent: {
|
||||||
type: String,
|
type: String,
|
||||||
value: '',
|
value: "",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ready() {
|
ready() {
|
||||||
super.ready();
|
super.ready();
|
||||||
this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
|
this.addEventListener("hass-api-called", (ev) => this.apiCalled(ev));
|
||||||
this.addEventListener('hassio-markdown-dialog', ev => this.openMarkdown(ev));
|
this.addEventListener("hassio-markdown-dialog", (ev) =>
|
||||||
|
this.openMarkdown(ev)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
apiCalled(ev) {
|
apiCalled(ev) {
|
||||||
@@ -115,7 +117,7 @@ class HassioAddonView extends PolymerElement {
|
|||||||
|
|
||||||
if (!path) return;
|
if (!path) return;
|
||||||
|
|
||||||
if (path.substr(path.lastIndexOf('/') + 1) === 'uninstall') {
|
if (path.substr(path.lastIndexOf("/") + 1) === "uninstall") {
|
||||||
this.backTapped();
|
this.backTapped();
|
||||||
} else {
|
} else {
|
||||||
this.routeDataChanged(this.routeData);
|
this.routeDataChanged(this.routeData);
|
||||||
@@ -124,12 +126,14 @@ class HassioAddonView extends PolymerElement {
|
|||||||
|
|
||||||
routeDataChanged(routeData) {
|
routeDataChanged(routeData) {
|
||||||
if (!this.routeMatches || !routeData || !routeData.slug) return;
|
if (!this.routeMatches || !routeData || !routeData.slug) return;
|
||||||
this.hass.callApi('get', `hassio/addons/${routeData.slug}/info`)
|
this.hass.callApi("get", `hassio/addons/${routeData.slug}/info`).then(
|
||||||
.then((info) => {
|
(info) => {
|
||||||
this.addon = info.data;
|
this.addon = info.data;
|
||||||
}, () => {
|
},
|
||||||
|
() => {
|
||||||
this.addon = null;
|
this.addon = null;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
backTapped() {
|
backTapped() {
|
||||||
@@ -141,8 +145,8 @@ class HassioAddonView extends PolymerElement {
|
|||||||
markdownTitle: ev.detail.title,
|
markdownTitle: ev.detail.title,
|
||||||
markdownContent: ev.detail.content,
|
markdownContent: ev.detail.content,
|
||||||
});
|
});
|
||||||
this.shadowRoot.querySelector('hassio-markdown-dialog').openDialog();
|
this.shadowRoot.querySelector("hassio-markdown-dialog").openDialog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-addon-view', HassioAddonView);
|
customElements.define("hassio-addon-view", HassioAddonView);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import '@polymer/iron-icon/iron-icon.js';
|
import "@polymer/iron-icon/iron-icon.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../../src/components/ha-relative-time.js';
|
import "../../../src/components/ha-relative-time.js";
|
||||||
|
|
||||||
class HassioCardContent extends PolymerElement {
|
class HassioCardContent extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -65,11 +65,11 @@ class HassioCardContent extends PolymerElement {
|
|||||||
datetime: String,
|
datetime: String,
|
||||||
icon: {
|
icon: {
|
||||||
type: String,
|
type: String,
|
||||||
value: 'hass:help-circle'
|
value: "hass:help-circle",
|
||||||
},
|
},
|
||||||
iconTitle: String,
|
iconTitle: String,
|
||||||
iconClass: String,
|
iconClass: String,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define('hassio-card-content', HassioCardContent);
|
customElements.define("hassio-card-content", HassioCardContent);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import '@polymer/paper-card/paper-card.js';
|
import "@polymer/paper-card/paper-card.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/hassio-card-content.js';
|
import "../components/hassio-card-content.js";
|
||||||
import '../resources/hassio-style.js';
|
import "../resources/hassio-style.js";
|
||||||
import NavigateMixin from '../../../src/mixins/navigate-mixin.js';
|
import NavigateMixin from "../../../src/mixins/navigate-mixin.js";
|
||||||
|
|
||||||
class HassioAddons extends NavigateMixin(PolymerElement) {
|
class HassioAddons extends NavigateMixin(PolymerElement) {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -46,28 +46,32 @@ class HassioAddons extends NavigateMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
computeIcon(addon) {
|
computeIcon(addon) {
|
||||||
return addon.installed !== addon.version ? 'hassio:arrow-up-bold-circle' : 'hassio:puzzle';
|
return addon.installed !== addon.version
|
||||||
|
? "hassio:arrow-up-bold-circle"
|
||||||
|
: "hassio:puzzle";
|
||||||
}
|
}
|
||||||
|
|
||||||
computeIconTitle(addon) {
|
computeIconTitle(addon) {
|
||||||
if (addon.installed !== addon.version) return 'New version available';
|
if (addon.installed !== addon.version) return "New version available";
|
||||||
return addon.state === 'started' ? 'Add-on is running' : 'Add-on is stopped';
|
return addon.state === "started"
|
||||||
|
? "Add-on is running"
|
||||||
|
: "Add-on is stopped";
|
||||||
}
|
}
|
||||||
|
|
||||||
computeIconClass(addon) {
|
computeIconClass(addon) {
|
||||||
if (addon.installed !== addon.version) return 'update';
|
if (addon.installed !== addon.version) return "update";
|
||||||
return addon.state === 'started' ? 'running' : '';
|
return addon.state === "started" ? "running" : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
addonTapped(ev) {
|
addonTapped(ev) {
|
||||||
this.navigate('/hassio/addon/' + ev.model.addon.slug);
|
this.navigate("/hassio/addon/" + ev.model.addon.slug);
|
||||||
ev.target.blur();
|
ev.target.blur();
|
||||||
}
|
}
|
||||||
|
|
||||||
openStore(ev) {
|
openStore(ev) {
|
||||||
this.navigate('/hassio/store');
|
this.navigate("/hassio/store");
|
||||||
ev.target.blur();
|
ev.target.blur();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-addons', HassioAddons);
|
customElements.define("hassio-addons", HassioAddons);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import './hassio-addons.js';
|
import "./hassio-addons.js";
|
||||||
import './hassio-hass-update.js';
|
import "./hassio-hass-update.js";
|
||||||
import EventsMixin from '../../../src/mixins/events-mixin.js';
|
import EventsMixin from "../../../src/mixins/events-mixin.js";
|
||||||
|
|
||||||
class HassioDashboard extends EventsMixin(PolymerElement) {
|
class HassioDashboard extends EventsMixin(PolymerElement) {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -29,4 +29,4 @@ class HassioDashboard extends EventsMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-dashboard', HassioDashboard);
|
customElements.define("hassio-dashboard", HassioDashboard);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import '@polymer/paper-button/paper-button.js';
|
import "@polymer/paper-button/paper-button.js";
|
||||||
import '@polymer/paper-card/paper-card.js';
|
import "@polymer/paper-card/paper-card.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../../src/components/buttons/ha-call-api-button.js';
|
import "../../../src/components/buttons/ha-call-api-button.js";
|
||||||
import '../components/hassio-card-content.js';
|
import "../components/hassio-card-content.js";
|
||||||
import '../resources/hassio-style.js';
|
import "../resources/hassio-style.js";
|
||||||
|
|
||||||
class HassioHassUpdate extends PolymerElement {
|
class HassioHassUpdate extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -56,7 +56,7 @@ class HassioHassUpdate extends PolymerElement {
|
|||||||
|
|
||||||
ready() {
|
ready() {
|
||||||
super.ready();
|
super.ready();
|
||||||
this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
|
this.addEventListener("hass-api-called", (ev) => this.apiCalled(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
apiCalled(ev) {
|
apiCalled(ev) {
|
||||||
@@ -67,8 +67,8 @@ class HassioHassUpdate extends PolymerElement {
|
|||||||
|
|
||||||
const response = ev.detail.response;
|
const response = ev.detail.response;
|
||||||
|
|
||||||
if (typeof response.body === 'object') {
|
if (typeof response.body === "object") {
|
||||||
this.errors = response.body.message || 'Unknown error';
|
this.errors = response.body.message || "Unknown error";
|
||||||
} else {
|
} else {
|
||||||
this.errors = response.body;
|
this.errors = response.body;
|
||||||
}
|
}
|
||||||
@@ -79,4 +79,4 @@ class HassioHassUpdate extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-hass-update', HassioHassUpdate);
|
customElements.define("hassio-hass-update", HassioHassUpdate);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
window.loadES5Adapter().then(() => {
|
window.loadES5Adapter().then(() => {
|
||||||
import(/* webpackChunkName: "hassio-icons" */ './resources/hassio-icons.js');
|
import(/* webpackChunkName: "hassio-icons" */ "./resources/hassio-icons.js");
|
||||||
import(/* webpackChunkName: "hassio-main" */ './hassio-main.js');
|
import(/* webpackChunkName: "hassio-main" */ "./hassio-main.js");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import './hassio-main.js';
|
import "./hassio-main.js";
|
||||||
import './resources/hassio-icons.js';
|
import "./resources/hassio-icons.js";
|
||||||
|
|
||||||
class HassioApp extends PolymerElement {
|
class HassioApp extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -29,13 +29,13 @@ class HassioApp extends PolymerElement {
|
|||||||
ready() {
|
ready() {
|
||||||
super.ready();
|
super.ready();
|
||||||
window.setProperties = this.setProperties.bind(this);
|
window.setProperties = this.setProperties.bind(this);
|
||||||
this.addEventListener('location-changed', () => this._locationChanged());
|
this.addEventListener("location-changed", () => this._locationChanged());
|
||||||
this.addEventListener('hass-open-menu', () => this._menuEvent(true));
|
this.addEventListener("hass-open-menu", () => this._menuEvent(true));
|
||||||
this.addEventListener('hass-close-menu', () => this._menuEvent(false));
|
this.addEventListener("hass-close-menu", () => this._menuEvent(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
_menuEvent(shouldOpen) {
|
_menuEvent(shouldOpen) {
|
||||||
this.hassioPanel.fire(shouldOpen ? 'hass-open-menu' : 'hass-close-menu');
|
this.hassioPanel.fire(shouldOpen ? "hass-open-menu" : "hass-close-menu");
|
||||||
}
|
}
|
||||||
|
|
||||||
_locationChanged() {
|
_locationChanged() {
|
||||||
@@ -43,4 +43,4 @@ class HassioApp extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-app', HassioApp);
|
customElements.define("hassio-app", HassioApp);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
class HassioData extends PolymerElement {
|
class HassioData extends PolymerElement {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
@@ -36,25 +36,24 @@ class HassioData extends PolymerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fetchSupervisorInfo() {
|
fetchSupervisorInfo() {
|
||||||
return this.hass.callApi('get', 'hassio/supervisor/info')
|
return this.hass.callApi("get", "hassio/supervisor/info").then((info) => {
|
||||||
.then((info) => {
|
|
||||||
this.supervisor = info.data;
|
this.supervisor = info.data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchHostInfo() {
|
fetchHostInfo() {
|
||||||
return this.hass.callApi('get', 'hassio/host/info')
|
return this.hass.callApi("get", "hassio/host/info").then((info) => {
|
||||||
.then((info) => {
|
|
||||||
this.host = info.data;
|
this.host = info.data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchHassInfo() {
|
fetchHassInfo() {
|
||||||
return this.hass.callApi('get', 'hassio/homeassistant/info')
|
return this.hass
|
||||||
|
.callApi("get", "hassio/homeassistant/info")
|
||||||
.then((info) => {
|
.then((info) => {
|
||||||
this.homeassistant = info.data;
|
this.homeassistant = info.data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-data', HassioData);
|
customElements.define("hassio-data", HassioData);
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import '@polymer/app-route/app-route.js';
|
import "@polymer/app-route/app-route.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../src/layouts/hass-loading-screen.js';
|
import "../../src/layouts/hass-loading-screen.js";
|
||||||
import './addon-view/hassio-addon-view.js';
|
import "./addon-view/hassio-addon-view.js";
|
||||||
import './hassio-data.js';
|
import "./hassio-data.js";
|
||||||
import './hassio-pages-with-tabs.js';
|
import "./hassio-pages-with-tabs.js";
|
||||||
|
|
||||||
import applyThemesOnElement from '../../src/common/dom/apply_themes_on_element.js';
|
import applyThemesOnElement from "../../src/common/dom/apply_themes_on_element.js";
|
||||||
import EventsMixin from '../../src/mixins/events-mixin.js';
|
import EventsMixin from "../../src/mixins/events-mixin.js";
|
||||||
import NavigateMixin from '../../src/mixins/navigate-mixin.js';
|
import NavigateMixin from "../../src/mixins/navigate-mixin.js";
|
||||||
|
|
||||||
class HassioMain extends EventsMixin(NavigateMixin(PolymerElement)) {
|
class HassioMain extends EventsMixin(NavigateMixin(PolymerElement)) {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -41,11 +41,11 @@ class HassioMain extends EventsMixin(NavigateMixin(PolymerElement)) {
|
|||||||
type: Object,
|
type: Object,
|
||||||
// Fake route object
|
// Fake route object
|
||||||
value: {
|
value: {
|
||||||
prefix: '/hassio',
|
prefix: "/hassio",
|
||||||
path: '/dashboard',
|
path: "/dashboard",
|
||||||
__queryParams: {}
|
__queryParams: {},
|
||||||
},
|
},
|
||||||
observer: 'routeChanged',
|
observer: "routeChanged",
|
||||||
},
|
},
|
||||||
routeData: Object,
|
routeData: Object,
|
||||||
supervisorInfo: Object,
|
supervisorInfo: Object,
|
||||||
@@ -53,7 +53,7 @@ class HassioMain extends EventsMixin(NavigateMixin(PolymerElement)) {
|
|||||||
hassInfo: Object,
|
hassInfo: Object,
|
||||||
loaded: {
|
loaded: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
computed: 'computeIsLoaded(supervisorInfo, hostInfo, hassInfo)',
|
computed: "computeIsLoaded(supervisorInfo, hostInfo, hassInfo)",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -61,7 +61,7 @@ class HassioMain extends EventsMixin(NavigateMixin(PolymerElement)) {
|
|||||||
ready() {
|
ready() {
|
||||||
super.ready();
|
super.ready();
|
||||||
applyThemesOnElement(this, this.hass.themes, this.hass.selectedTheme, true);
|
applyThemesOnElement(this, this.hass.themes, this.hass.selectedTheme, true);
|
||||||
this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
|
this.addEventListener("hass-api-called", (ev) => this.apiCalled(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
@@ -74,7 +74,7 @@ class HassioMain extends EventsMixin(NavigateMixin(PolymerElement)) {
|
|||||||
let tries = 1;
|
let tries = 1;
|
||||||
|
|
||||||
const tryUpdate = () => {
|
const tryUpdate = () => {
|
||||||
this.$.data.refresh().catch(function () {
|
this.$.data.refresh().catch(function() {
|
||||||
tries += 1;
|
tries += 1;
|
||||||
setTimeout(tryUpdate, Math.min(tries, 5) * 1000);
|
setTimeout(tryUpdate, Math.min(tries, 5) * 1000);
|
||||||
});
|
});
|
||||||
@@ -85,21 +85,19 @@ class HassioMain extends EventsMixin(NavigateMixin(PolymerElement)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
computeIsLoaded(supervisorInfo, hostInfo, hassInfo) {
|
computeIsLoaded(supervisorInfo, hostInfo, hassInfo) {
|
||||||
return (supervisorInfo !== null
|
return supervisorInfo !== null && hostInfo !== null && hassInfo !== null;
|
||||||
&& hostInfo !== null
|
|
||||||
&& hassInfo !== null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
routeChanged(route) {
|
routeChanged(route) {
|
||||||
if (route.path === '' && route.prefix === '/hassio') {
|
if (route.path === "" && route.prefix === "/hassio") {
|
||||||
this.navigate('/hassio/dashboard', true);
|
this.navigate("/hassio/dashboard", true);
|
||||||
}
|
}
|
||||||
this.fire('iron-resize');
|
this.fire("iron-resize");
|
||||||
}
|
}
|
||||||
|
|
||||||
equalsAddon(page) {
|
equalsAddon(page) {
|
||||||
return page && page === 'addon';
|
return page && page === "addon";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-main', HassioMain);
|
customElements.define("hassio-main", HassioMain);
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
import "@polymer/app-layout/app-toolbar/app-toolbar.js";
|
||||||
import '@polymer/paper-dialog-scrollable/paper-dialog-scrollable.js';
|
import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable.js";
|
||||||
import '@polymer/paper-dialog/paper-dialog.js';
|
import "@polymer/paper-dialog/paper-dialog.js";
|
||||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
import "@polymer/paper-icon-button/paper-icon-button.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../src/components/ha-markdown.js';
|
import "../../src/components/ha-markdown.js";
|
||||||
import '../../src/resources/ha-style.js';
|
import "../../src/resources/ha-style.js";
|
||||||
|
|
||||||
class HassioMarkdownDialog extends PolymerElement {
|
class HassioMarkdownDialog extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -73,4 +73,4 @@ class HassioMarkdownDialog extends PolymerElement {
|
|||||||
this.$.dialog.open();
|
this.$.dialog.open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define('hassio-markdown-dialog', HassioMarkdownDialog);
|
customElements.define("hassio-markdown-dialog", HassioMarkdownDialog);
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
import '@polymer/app-layout/app-header-layout/app-header-layout.js';
|
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-header/app-header.js";
|
||||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
import "@polymer/app-layout/app-toolbar/app-toolbar.js";
|
||||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
import "@polymer/paper-icon-button/paper-icon-button.js";
|
||||||
import '@polymer/paper-tabs/paper-tab.js';
|
import "@polymer/paper-tabs/paper-tab.js";
|
||||||
import '@polymer/paper-tabs/paper-tabs.js';
|
import "@polymer/paper-tabs/paper-tabs.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../src/components/ha-menu-button.js';
|
import "../../src/components/ha-menu-button.js";
|
||||||
import '../../src/resources/ha-style.js';
|
import "../../src/resources/ha-style.js";
|
||||||
import './addon-store/hassio-addon-store.js';
|
import "./addon-store/hassio-addon-store.js";
|
||||||
import './dashboard/hassio-dashboard.js';
|
import "./dashboard/hassio-dashboard.js";
|
||||||
import './hassio-markdown-dialog.js';
|
import "./hassio-markdown-dialog.js";
|
||||||
import './snapshots/hassio-snapshot.js';
|
import "./snapshots/hassio-snapshot.js";
|
||||||
import './snapshots/hassio-snapshots.js';
|
import "./snapshots/hassio-snapshots.js";
|
||||||
import './system/hassio-system.js';
|
import "./system/hassio-system.js";
|
||||||
|
|
||||||
import scrollToTarget from '../../src/common/dom/scroll-to-target.js';
|
import scrollToTarget from "../../src/common/dom/scroll-to-target.js";
|
||||||
|
|
||||||
import NavigateMixin from '../../src/mixins/navigate-mixin.js';
|
import NavigateMixin from "../../src/mixins/navigate-mixin.js";
|
||||||
|
|
||||||
class HassioPagesWithTabs extends NavigateMixin(PolymerElement) {
|
class HassioPagesWithTabs extends NavigateMixin(PolymerElement) {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -87,18 +87,20 @@ class HassioPagesWithTabs extends NavigateMixin(PolymerElement) {
|
|||||||
markdownTitle: String,
|
markdownTitle: String,
|
||||||
markdownContent: {
|
markdownContent: {
|
||||||
type: String,
|
type: String,
|
||||||
value: '',
|
value: "",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ready() {
|
ready() {
|
||||||
super.ready();
|
super.ready();
|
||||||
this.addEventListener('hassio-markdown-dialog', ev => this.openMarkdown(ev));
|
this.addEventListener("hassio-markdown-dialog", (ev) =>
|
||||||
|
this.openMarkdown(ev)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePageSelected(ev) {
|
handlePageSelected(ev) {
|
||||||
const newPage = ev.detail.item.getAttribute('page-name');
|
const newPage = ev.detail.item.getAttribute("page-name");
|
||||||
if (newPage !== this.page) {
|
if (newPage !== this.page) {
|
||||||
this.navigate(`/hassio/${newPage}`);
|
this.navigate(`/hassio/${newPage}`);
|
||||||
}
|
}
|
||||||
@@ -110,14 +112,14 @@ class HassioPagesWithTabs extends NavigateMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showRefreshButton(page) {
|
showRefreshButton(page) {
|
||||||
return page === 'store' || page === 'snapshots';
|
return page === "store" || page === "snapshots";
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshClicked() {
|
refreshClicked() {
|
||||||
if (this.page === 'snapshots') {
|
if (this.page === "snapshots") {
|
||||||
this.shadowRoot.querySelector('hassio-snapshots').refreshData();
|
this.shadowRoot.querySelector("hassio-snapshots").refreshData();
|
||||||
} else {
|
} else {
|
||||||
this.shadowRoot.querySelector('hassio-addon-store').refreshData();
|
this.shadowRoot.querySelector("hassio-addon-store").refreshData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,8 +128,8 @@ class HassioPagesWithTabs extends NavigateMixin(PolymerElement) {
|
|||||||
markdownTitle: ev.detail.title,
|
markdownTitle: ev.detail.title,
|
||||||
markdownContent: ev.detail.content,
|
markdownContent: ev.detail.content,
|
||||||
});
|
});
|
||||||
this.shadowRoot.querySelector('hassio-markdown-dialog').openDialog();
|
this.shadowRoot.querySelector("hassio-markdown-dialog").openDialog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-pages-with-tabs', HassioPagesWithTabs);
|
customElements.define("hassio-pages-with-tabs", HassioPagesWithTabs);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import '../../../src/components/ha-iconset-svg.js';
|
import "../../../src/components/ha-iconset-svg.js";
|
||||||
import iconSetContent from '../../hassio-icons.html';
|
import iconSetContent from "../../hassio-icons.html";
|
||||||
|
|
||||||
const documentContainer = document.createElement('template');
|
const documentContainer = document.createElement("template");
|
||||||
documentContainer.setAttribute('style', 'display: none;');
|
documentContainer.setAttribute("style", "display: none;");
|
||||||
documentContainer.innerHTML = iconSetContent;
|
documentContainer.innerHTML = iconSetContent;
|
||||||
document.head.appendChild(documentContainer.content);
|
document.head.appendChild(documentContainer.content);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const documentContainer = document.createElement('template');
|
const documentContainer = document.createElement("template");
|
||||||
documentContainer.setAttribute('style', 'display: none;');
|
documentContainer.setAttribute("style", "display: none;");
|
||||||
|
|
||||||
documentContainer.innerHTML = `<dom-module id="hassio-style">
|
documentContainer.innerHTML = `<dom-module id="hassio-style">
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import '@polymer/app-layout/app-toolbar/app-toolbar.js';
|
import "@polymer/app-layout/app-toolbar/app-toolbar.js";
|
||||||
import '@polymer/paper-button/paper-button.js';
|
import "@polymer/paper-button/paper-button.js";
|
||||||
import '@polymer/paper-checkbox/paper-checkbox.js';
|
import "@polymer/paper-checkbox/paper-checkbox.js";
|
||||||
import '@polymer/paper-dialog-scrollable/paper-dialog-scrollable.js';
|
import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable.js";
|
||||||
import '@polymer/paper-dialog/paper-dialog.js';
|
import "@polymer/paper-dialog/paper-dialog.js";
|
||||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
import "@polymer/paper-icon-button/paper-icon-button.js";
|
||||||
import '@polymer/paper-input/paper-input.js';
|
import "@polymer/paper-input/paper-input.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../../src/resources/ha-style.js';
|
import "../../../src/resources/ha-style.js";
|
||||||
|
|
||||||
class HassioSnapshot extends PolymerElement {
|
class HassioSnapshot extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -114,7 +114,7 @@ class HassioSnapshot extends PolymerElement {
|
|||||||
snapshotSlug: {
|
snapshotSlug: {
|
||||||
type: String,
|
type: String,
|
||||||
notify: true,
|
notify: true,
|
||||||
observer: '_snapshotSlugChanged',
|
observer: "_snapshotSlugChanged",
|
||||||
},
|
},
|
||||||
snapshotDeleted: {
|
snapshotDeleted: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@@ -131,85 +131,124 @@ class HassioSnapshot extends PolymerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_snapshotSlugChanged(snapshotSlug) {
|
_snapshotSlugChanged(snapshotSlug) {
|
||||||
if (!snapshotSlug || snapshotSlug === 'update') return;
|
if (!snapshotSlug || snapshotSlug === "update") return;
|
||||||
this.hass.callApi('get', `hassio/snapshots/${snapshotSlug}/info`)
|
this.hass.callApi("get", `hassio/snapshots/${snapshotSlug}/info`).then(
|
||||||
.then((info) => {
|
(info) => {
|
||||||
info.data.folders = this._computeFolders(info.data.folders);
|
info.data.folders = this._computeFolders(info.data.folders);
|
||||||
info.data.addons = this._computeAddons(info.data.addons);
|
info.data.addons = this._computeAddons(info.data.addons);
|
||||||
this.snapshot = info.data;
|
this.snapshot = info.data;
|
||||||
this.$.dialog.open();
|
this.$.dialog.open();
|
||||||
}, () => {
|
},
|
||||||
|
() => {
|
||||||
this.snapshot = null;
|
this.snapshot = null;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_computeFolders(folders) {
|
_computeFolders(folders) {
|
||||||
const list = [];
|
const list = [];
|
||||||
if (folders.includes('homeassistant')) list.push({ slug: 'homeassistant', name: 'Home Assistant configuration', checked: true });
|
if (folders.includes("homeassistant"))
|
||||||
if (folders.includes('ssl')) list.push({ slug: 'ssl', name: 'SSL', checked: true });
|
list.push({
|
||||||
if (folders.includes('share')) list.push({ slug: 'share', name: 'Share', checked: true });
|
slug: "homeassistant",
|
||||||
if (folders.includes('addons/local')) list.push({ slug: 'addons/local', name: 'Local add-ons', checked: true });
|
name: "Home Assistant configuration",
|
||||||
|
checked: true,
|
||||||
|
});
|
||||||
|
if (folders.includes("ssl"))
|
||||||
|
list.push({ slug: "ssl", name: "SSL", checked: true });
|
||||||
|
if (folders.includes("share"))
|
||||||
|
list.push({ slug: "share", name: "Share", checked: true });
|
||||||
|
if (folders.includes("addons/local"))
|
||||||
|
list.push({ slug: "addons/local", name: "Local add-ons", checked: true });
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
_computeAddons(addons) {
|
_computeAddons(addons) {
|
||||||
return addons.map(addon => (
|
return addons.map((addon) => ({
|
||||||
{ slug: addon.slug, name: addon.name, version: addon.version, checked: true }));
|
slug: addon.slug,
|
||||||
|
name: addon.name,
|
||||||
|
version: addon.version,
|
||||||
|
checked: true,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
_isFullSnapshot(type) {
|
_isFullSnapshot(type) {
|
||||||
return type === 'full';
|
return type === "full";
|
||||||
}
|
}
|
||||||
|
|
||||||
_partialRestoreClicked() {
|
_partialRestoreClicked() {
|
||||||
if (!confirm('Are you sure you want to restore this snapshot?')) {
|
if (!confirm("Are you sure you want to restore this snapshot?")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const addons = this.snapshot.addons.filter(addon => addon.checked).map(addon => addon.slug);
|
const addons = this.snapshot.addons
|
||||||
const folders = this.snapshot.folders.filter(
|
.filter((addon) => addon.checked)
|
||||||
folder => folder.checked
|
.map((addon) => addon.slug);
|
||||||
).map(folder => folder.slug);
|
const folders = this.snapshot.folders
|
||||||
|
.filter((folder) => folder.checked)
|
||||||
|
.map((folder) => folder.slug);
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
homeassistant: this.restoreHass,
|
homeassistant: this.restoreHass,
|
||||||
addons: addons,
|
addons: addons,
|
||||||
folders: folders
|
folders: folders,
|
||||||
};
|
};
|
||||||
if (this.snapshot.protected) data.password = this.snapshotPassword;
|
if (this.snapshot.protected) data.password = this.snapshotPassword;
|
||||||
|
|
||||||
this.hass.callApi('post', `hassio/snapshots/${this.snapshotSlug}/restore/partial`, data).then(() => {
|
this.hass
|
||||||
alert('Snapshot restored!');
|
.callApi(
|
||||||
|
"post",
|
||||||
|
`hassio/snapshots/${this.snapshotSlug}/restore/partial`,
|
||||||
|
data
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
() => {
|
||||||
|
alert("Snapshot restored!");
|
||||||
this.$.dialog.close();
|
this.$.dialog.close();
|
||||||
}, (error) => {
|
},
|
||||||
|
(error) => {
|
||||||
this.error = error.body.message;
|
this.error = error.body.message;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_fullRestoreClicked() {
|
_fullRestoreClicked() {
|
||||||
if (!confirm('Are you sure you want to restore this snapshot?')) {
|
if (!confirm("Are you sure you want to restore this snapshot?")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const data = this.snapshot.protected ? { password: this.snapshotPassword } : null;
|
const data = this.snapshot.protected
|
||||||
this.hass.callApi('post', `hassio/snapshots/${this.snapshotSlug}/restore/full`, data)
|
? { password: this.snapshotPassword }
|
||||||
.then(() => {
|
: null;
|
||||||
alert('Snapshot restored!');
|
this.hass
|
||||||
|
.callApi(
|
||||||
|
"post",
|
||||||
|
`hassio/snapshots/${this.snapshotSlug}/restore/full`,
|
||||||
|
data
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
() => {
|
||||||
|
alert("Snapshot restored!");
|
||||||
this.$.dialog.close();
|
this.$.dialog.close();
|
||||||
}, (error) => {
|
},
|
||||||
|
(error) => {
|
||||||
this.error = error.body.message;
|
this.error = error.body.message;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_deleteClicked() {
|
_deleteClicked() {
|
||||||
if (!confirm('Are you sure you want to delete this snapshot?')) {
|
if (!confirm("Are you sure you want to delete this snapshot?")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.hass.callApi('post', `hassio/snapshots/${this.snapshotSlug}/remove`)
|
this.hass
|
||||||
.then(() => {
|
.callApi("post", `hassio/snapshots/${this.snapshotSlug}/remove`)
|
||||||
|
.then(
|
||||||
|
() => {
|
||||||
this.$.dialog.close();
|
this.$.dialog.close();
|
||||||
this.snapshotDeleted = true;
|
this.snapshotDeleted = true;
|
||||||
}, (error) => {
|
},
|
||||||
|
(error) => {
|
||||||
this.error = error.body.message;
|
this.error = error.body.message;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_computeDownloadUrl(snapshotSlug) {
|
_computeDownloadUrl(snapshotSlug) {
|
||||||
@@ -218,7 +257,7 @@ class HassioSnapshot extends PolymerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_computeDownloadName(snapshot) {
|
_computeDownloadName(snapshot) {
|
||||||
const name = this._computeName(snapshot).replace(/[^a-z0-9]+/gi, '_');
|
const name = this._computeName(snapshot).replace(/[^a-z0-9]+/gi, "_");
|
||||||
return `Hass_io_${name}.tar`;
|
return `Hass_io_${name}.tar`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,11 +266,11 @@ class HassioSnapshot extends PolymerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_computeType(type) {
|
_computeType(type) {
|
||||||
return type === 'full' ? 'Full snapshot' : 'Partial snapshot';
|
return type === "full" ? "Full snapshot" : "Partial snapshot";
|
||||||
}
|
}
|
||||||
|
|
||||||
_computeSize(size) {
|
_computeSize(size) {
|
||||||
return (Math.ceil(size * 10) / 10) + ' MB';
|
return Math.ceil(size * 10) / 10 + " MB";
|
||||||
}
|
}
|
||||||
|
|
||||||
_sortAddons(a, b) {
|
_sortAddons(a, b) {
|
||||||
@@ -240,12 +279,12 @@ class HassioSnapshot extends PolymerElement {
|
|||||||
|
|
||||||
_formatDatetime(datetime) {
|
_formatDatetime(datetime) {
|
||||||
return new Date(datetime).toLocaleDateString(navigator.language, {
|
return new Date(datetime).toLocaleDateString(navigator.language, {
|
||||||
weekday: 'long',
|
weekday: "long",
|
||||||
year: 'numeric',
|
year: "numeric",
|
||||||
month: 'short',
|
month: "short",
|
||||||
day: 'numeric',
|
day: "numeric",
|
||||||
hour: 'numeric',
|
hour: "numeric",
|
||||||
minute: '2-digit'
|
minute: "2-digit",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,4 +292,4 @@ class HassioSnapshot extends PolymerElement {
|
|||||||
this.snapshotSlug = null;
|
this.snapshotSlug = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define('hassio-snapshot', HassioSnapshot);
|
customElements.define("hassio-snapshot", HassioSnapshot);
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import '@polymer/paper-button/paper-button.js';
|
import "@polymer/paper-button/paper-button.js";
|
||||||
import '@polymer/paper-card/paper-card.js';
|
import "@polymer/paper-card/paper-card.js";
|
||||||
import '@polymer/paper-checkbox/paper-checkbox.js';
|
import "@polymer/paper-checkbox/paper-checkbox.js";
|
||||||
import '@polymer/paper-input/paper-input.js';
|
import "@polymer/paper-input/paper-input.js";
|
||||||
import '@polymer/paper-radio-button/paper-radio-button.js';
|
import "@polymer/paper-radio-button/paper-radio-button.js";
|
||||||
import '@polymer/paper-radio-group/paper-radio-group.js';
|
import "@polymer/paper-radio-group/paper-radio-group.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/hassio-card-content.js';
|
import "../components/hassio-card-content.js";
|
||||||
import '../resources/hassio-style.js';
|
import "../resources/hassio-style.js";
|
||||||
import EventsMixin from '../../../src/mixins/events-mixin.js';
|
import EventsMixin from "../../../src/mixins/events-mixin.js";
|
||||||
|
|
||||||
class HassioSnapshots extends EventsMixin(PolymerElement) {
|
class HassioSnapshots extends EventsMixin(PolymerElement) {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -105,16 +105,16 @@ class HassioSnapshots extends EventsMixin(PolymerElement) {
|
|||||||
hass: Object,
|
hass: Object,
|
||||||
snapshotName: {
|
snapshotName: {
|
||||||
type: String,
|
type: String,
|
||||||
value: '',
|
value: "",
|
||||||
},
|
},
|
||||||
snapshotPassword: {
|
snapshotPassword: {
|
||||||
type: String,
|
type: String,
|
||||||
value: '',
|
value: "",
|
||||||
},
|
},
|
||||||
snapshotHasPassword: Boolean,
|
snapshotHasPassword: Boolean,
|
||||||
snapshotType: {
|
snapshotType: {
|
||||||
type: String,
|
type: String,
|
||||||
value: 'full',
|
value: "full",
|
||||||
},
|
},
|
||||||
snapshots: {
|
snapshots: {
|
||||||
type: Array,
|
type: Array,
|
||||||
@@ -122,16 +122,20 @@ class HassioSnapshots extends EventsMixin(PolymerElement) {
|
|||||||
},
|
},
|
||||||
installedAddons: {
|
installedAddons: {
|
||||||
type: Array,
|
type: Array,
|
||||||
observer: '_installedAddonsChanged',
|
observer: "_installedAddonsChanged",
|
||||||
},
|
},
|
||||||
addonList: Array,
|
addonList: Array,
|
||||||
folderList: {
|
folderList: {
|
||||||
type: Array,
|
type: Array,
|
||||||
value: [
|
value: [
|
||||||
{ slug: 'homeassistant', name: 'Home Assistant configuration', checked: true },
|
{
|
||||||
{ slug: 'ssl', name: 'SSL', checked: true },
|
slug: "homeassistant",
|
||||||
{ slug: 'share', name: 'Share', checked: true },
|
name: "Home Assistant configuration",
|
||||||
{ slug: 'addons/local', name: 'Local add-ons', checked: true },
|
checked: true,
|
||||||
|
},
|
||||||
|
{ slug: "ssl", name: "SSL", checked: true },
|
||||||
|
{ slug: "share", name: "Share", checked: true },
|
||||||
|
{ slug: "addons/local", name: "Local add-ons", checked: true },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
snapshotSlug: {
|
snapshotSlug: {
|
||||||
@@ -141,7 +145,7 @@ class HassioSnapshots extends EventsMixin(PolymerElement) {
|
|||||||
snapshotDeleted: {
|
snapshotDeleted: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
notify: true,
|
notify: true,
|
||||||
observer: '_snapshotDeletedChanged',
|
observer: "_snapshotDeletedChanged",
|
||||||
},
|
},
|
||||||
creatingSnapshot: Boolean,
|
creatingSnapshot: Boolean,
|
||||||
dialogOpened: Boolean,
|
dialogOpened: Boolean,
|
||||||
@@ -151,7 +155,7 @@ class HassioSnapshots extends EventsMixin(PolymerElement) {
|
|||||||
|
|
||||||
ready() {
|
ready() {
|
||||||
super.ready();
|
super.ready();
|
||||||
this.addEventListener('hass-api-called', ev => this._apiCalled(ev));
|
this.addEventListener("hass-api-called", (ev) => this._apiCalled(ev));
|
||||||
this._updateSnapshots();
|
this._updateSnapshots();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,57 +166,70 @@ class HassioSnapshots extends EventsMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_updateSnapshots() {
|
_updateSnapshots() {
|
||||||
this.hass.callApi('get', 'hassio/snapshots')
|
this.hass.callApi("get", "hassio/snapshots").then(
|
||||||
.then((result) => {
|
(result) => {
|
||||||
this.snapshots = result.data.snapshots;
|
this.snapshots = result.data.snapshots;
|
||||||
}, (error) => {
|
},
|
||||||
|
(error) => {
|
||||||
this.error = error.message;
|
this.error = error.message;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_createSnapshot() {
|
_createSnapshot() {
|
||||||
this.error = '';
|
this.error = "";
|
||||||
if (this.snapshotHasPassword && !this.snapshotPassword.length) {
|
if (this.snapshotHasPassword && !this.snapshotPassword.length) {
|
||||||
this.error = 'Please enter a password.';
|
this.error = "Please enter a password.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.creatingSnapshot = true;
|
this.creatingSnapshot = true;
|
||||||
let name = this.snapshotName;
|
let name = this.snapshotName;
|
||||||
if (!name.length) {
|
if (!name.length) {
|
||||||
name = new Date().toLocaleDateString(navigator.language, {
|
name = new Date().toLocaleDateString(navigator.language, {
|
||||||
weekday: 'long',
|
weekday: "long",
|
||||||
year: 'numeric',
|
year: "numeric",
|
||||||
month: 'short',
|
month: "short",
|
||||||
day: 'numeric' });
|
day: "numeric",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
let data;
|
let data;
|
||||||
let path;
|
let path;
|
||||||
if (this.snapshotType === 'full') {
|
if (this.snapshotType === "full") {
|
||||||
data = { name: name };
|
data = { name: name };
|
||||||
path = 'hassio/snapshots/new/full';
|
path = "hassio/snapshots/new/full";
|
||||||
} else {
|
} else {
|
||||||
const addons = this.addonList.filter(addon => addon.checked).map(addon => addon.slug);
|
const addons = this.addonList
|
||||||
const folders = this.folderList.filter(folder => folder.checked).map(folder => folder.slug);
|
.filter((addon) => addon.checked)
|
||||||
|
.map((addon) => addon.slug);
|
||||||
|
const folders = this.folderList
|
||||||
|
.filter((folder) => folder.checked)
|
||||||
|
.map((folder) => folder.slug);
|
||||||
|
|
||||||
data = { name: name, folders: folders, addons: addons };
|
data = { name: name, folders: folders, addons: addons };
|
||||||
path = 'hassio/snapshots/new/partial';
|
path = "hassio/snapshots/new/partial";
|
||||||
}
|
}
|
||||||
if (this.snapshotHasPassword) {
|
if (this.snapshotHasPassword) {
|
||||||
data.password = this.snapshotPassword;
|
data.password = this.snapshotPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.hass.callApi('post', path, data)
|
this.hass.callApi("post", path, data).then(
|
||||||
.then(() => {
|
() => {
|
||||||
this.creatingSnapshot = false;
|
this.creatingSnapshot = false;
|
||||||
this.fire('hass-api-called', { success: true });
|
this.fire("hass-api-called", { success: true });
|
||||||
}, (error) => {
|
},
|
||||||
|
(error) => {
|
||||||
this.creatingSnapshot = false;
|
this.creatingSnapshot = false;
|
||||||
this.error = error.message;
|
this.error = error.message;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_installedAddonsChanged(addons) {
|
_installedAddonsChanged(addons) {
|
||||||
this.addonList = addons.map(addon => ({ slug: addon.slug, name: addon.name, checked: true }));
|
this.addonList = addons.map((addon) => ({
|
||||||
|
slug: addon.slug,
|
||||||
|
name: addon.name,
|
||||||
|
checked: true,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
_sortAddons(a, b) {
|
_sortAddons(a, b) {
|
||||||
@@ -228,12 +245,15 @@ class HassioSnapshots extends EventsMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_computeDetails(snapshot) {
|
_computeDetails(snapshot) {
|
||||||
const type = snapshot.type === 'full' ? 'Full snapshot' : 'Partial snapshot';
|
const type =
|
||||||
|
snapshot.type === "full" ? "Full snapshot" : "Partial snapshot";
|
||||||
return snapshot.protected ? `${type}, password protected` : type;
|
return snapshot.protected ? `${type}, password protected` : type;
|
||||||
}
|
}
|
||||||
|
|
||||||
_computeIcon(type) {
|
_computeIcon(type) {
|
||||||
return type === 'full' ? 'hassio:package-variant-closed' : 'hassio:package-variant';
|
return type === "full"
|
||||||
|
? "hassio:package-variant-closed"
|
||||||
|
: "hassio:package-variant";
|
||||||
}
|
}
|
||||||
|
|
||||||
_snapshotClicked(ev) {
|
_snapshotClicked(ev) {
|
||||||
@@ -241,7 +261,7 @@ class HassioSnapshots extends EventsMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_fullSelected(type) {
|
_fullSelected(type) {
|
||||||
return type === 'full';
|
return type === "full";
|
||||||
}
|
}
|
||||||
|
|
||||||
_snapshotDeletedChanged(snapshotDeleted) {
|
_snapshotDeletedChanged(snapshotDeleted) {
|
||||||
@@ -252,11 +272,10 @@ class HassioSnapshots extends EventsMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
refreshData() {
|
refreshData() {
|
||||||
this.hass.callApi('post', 'hassio/snapshots/reload')
|
this.hass.callApi("post", "hassio/snapshots/reload").then(() => {
|
||||||
.then(() => {
|
|
||||||
this._updateSnapshots();
|
this._updateSnapshots();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-snapshots', HassioSnapshots);
|
customElements.define("hassio-snapshots", HassioSnapshots);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import '@polymer/paper-button/paper-button.js';
|
import "@polymer/paper-button/paper-button.js";
|
||||||
import '@polymer/paper-card/paper-card.js';
|
import "@polymer/paper-card/paper-card.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../../src/components/buttons/ha-call-api-button.js';
|
import "../../../src/components/buttons/ha-call-api-button.js";
|
||||||
import EventsMixin from '../../../src/mixins/events-mixin.js';
|
import EventsMixin from "../../../src/mixins/events-mixin.js";
|
||||||
|
|
||||||
class HassioHostInfo extends EventsMixin(PolymerElement) {
|
class HassioHostInfo extends EventsMixin(PolymerElement) {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -97,16 +97,16 @@ class HassioHostInfo extends EventsMixin(PolymerElement) {
|
|||||||
hass: Object,
|
hass: Object,
|
||||||
data: {
|
data: {
|
||||||
type: Object,
|
type: Object,
|
||||||
observer: '_dataChanged'
|
observer: "_dataChanged",
|
||||||
},
|
},
|
||||||
errors: String,
|
errors: String,
|
||||||
_hassOs: Object
|
_hassOs: Object,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ready() {
|
ready() {
|
||||||
super.ready();
|
super.ready();
|
||||||
this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
|
this.addEventListener("hass-api-called", (ev) => this.apiCalled(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
apiCalled(ev) {
|
apiCalled(ev) {
|
||||||
@@ -117,17 +117,16 @@ class HassioHostInfo extends EventsMixin(PolymerElement) {
|
|||||||
|
|
||||||
var response = ev.detail.response;
|
var response = ev.detail.response;
|
||||||
|
|
||||||
if (typeof response.body === 'object') {
|
if (typeof response.body === "object") {
|
||||||
this.errors = response.body.message || 'Unknown error';
|
this.errors = response.body.message || "Unknown error";
|
||||||
} else {
|
} else {
|
||||||
this.errors = response.body;
|
this.errors = response.body;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_dataChanged(data) {
|
_dataChanged(data) {
|
||||||
if (data.features && data.features.includes('hassos')) {
|
if (data.features && data.features.includes("hassos")) {
|
||||||
this.hass.callApi('get', 'hassio/hassos/info')
|
this.hass.callApi("get", "hassio/hassos/info").then((resp) => {
|
||||||
.then((resp) => {
|
|
||||||
this._hassOs = resp.data;
|
this._hassOs = resp.data;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -144,28 +143,31 @@ class HassioHostInfo extends EventsMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_showHardware() {
|
_showHardware() {
|
||||||
this.hass.callApi('get', 'hassio/hardware/info')
|
this.hass
|
||||||
|
.callApi("get", "hassio/hardware/info")
|
||||||
.then(
|
.then(
|
||||||
resp => this._objectToMarkdown(resp.data),
|
(resp) => this._objectToMarkdown(resp.data),
|
||||||
() => 'Error getting hardware info'
|
() => "Error getting hardware info"
|
||||||
).then((content) => {
|
)
|
||||||
this.fire('hassio-markdown-dialog', {
|
.then((content) => {
|
||||||
title: 'Hardware',
|
this.fire("hassio-markdown-dialog", {
|
||||||
|
title: "Hardware",
|
||||||
content: content,
|
content: content,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_objectToMarkdown(obj, indent = '') {
|
_objectToMarkdown(obj, indent = "") {
|
||||||
let data = '';
|
let data = "";
|
||||||
Object.keys(obj).forEach((key) => {
|
Object.keys(obj).forEach((key) => {
|
||||||
if (typeof obj[key] !== 'object') {
|
if (typeof obj[key] !== "object") {
|
||||||
data += `${indent}- ${key}: ${obj[key]}\n`;
|
data += `${indent}- ${key}: ${obj[key]}\n`;
|
||||||
} else {
|
} else {
|
||||||
data += `${indent}- ${key}:\n`;
|
data += `${indent}- ${key}:\n`;
|
||||||
if (Array.isArray(obj[key])) {
|
if (Array.isArray(obj[key])) {
|
||||||
if (obj[key].length) {
|
if (obj[key].length) {
|
||||||
data += `${indent} - ` + obj[key].join(`\n${indent} - `) + '\n';
|
data +=
|
||||||
|
`${indent} - ` + obj[key].join(`\n${indent} - `) + "\n";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
data += this._objectToMarkdown(obj[key], ` ${indent}`);
|
data += this._objectToMarkdown(obj[key], ` ${indent}`);
|
||||||
@@ -177,11 +179,11 @@ class HassioHostInfo extends EventsMixin(PolymerElement) {
|
|||||||
|
|
||||||
_changeHostnameClicked() {
|
_changeHostnameClicked() {
|
||||||
const curHostname = this.data.hostname;
|
const curHostname = this.data.hostname;
|
||||||
const hostname = prompt('Please enter a new hostname:', curHostname);
|
const hostname = prompt("Please enter a new hostname:", curHostname);
|
||||||
if (hostname && hostname !== curHostname) {
|
if (hostname && hostname !== curHostname) {
|
||||||
this.hass.callApi('post', 'hassio/host/options', { hostname });
|
this.hass.callApi("post", "hassio/host/options", { hostname });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-host-info', HassioHostInfo);
|
customElements.define("hassio-host-info", HassioHostInfo);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import '@polymer/paper-button/paper-button.js';
|
import "@polymer/paper-button/paper-button.js";
|
||||||
import '@polymer/paper-card/paper-card.js';
|
import "@polymer/paper-card/paper-card.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../../../src/components/buttons/ha-call-api-button.js';
|
import "../../../src/components/buttons/ha-call-api-button.js";
|
||||||
import EventsMixin from '../../../src/mixins/events-mixin.js';
|
import EventsMixin from "../../../src/mixins/events-mixin.js";
|
||||||
|
|
||||||
class HassioSupervisorInfo extends EventsMixin(PolymerElement) {
|
class HassioSupervisorInfo extends EventsMixin(PolymerElement) {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -85,14 +85,14 @@ class HassioSupervisorInfo extends EventsMixin(PolymerElement) {
|
|||||||
errors: String,
|
errors: String,
|
||||||
leaveBeta: {
|
leaveBeta: {
|
||||||
type: Object,
|
type: Object,
|
||||||
value: { channel: 'stable' },
|
value: { channel: "stable" },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ready() {
|
ready() {
|
||||||
super.ready();
|
super.ready();
|
||||||
this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
|
this.addEventListener("hass-api-called", (ev) => this.apiCalled(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
apiCalled(ev) {
|
apiCalled(ev) {
|
||||||
@@ -103,8 +103,8 @@ class HassioSupervisorInfo extends EventsMixin(PolymerElement) {
|
|||||||
|
|
||||||
var response = ev.detail.response;
|
var response = ev.detail.response;
|
||||||
|
|
||||||
if (typeof response.body === 'object') {
|
if (typeof response.body === "object") {
|
||||||
this.errors = response.body.message || 'Unknown error';
|
this.errors = response.body.message || "Unknown error";
|
||||||
} else {
|
} else {
|
||||||
this.errors = response.body;
|
this.errors = response.body;
|
||||||
}
|
}
|
||||||
@@ -119,18 +119,20 @@ class HassioSupervisorInfo extends EventsMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_joinBeta() {
|
_joinBeta() {
|
||||||
if (!confirm(`WARNING:
|
if (
|
||||||
|
!confirm(`WARNING:
|
||||||
Beta releases are for testers and early adopters and can contain unstable code changes. Make sure you have backups of your data before you activate this feature.
|
Beta releases are for testers and early adopters and can contain unstable code changes. Make sure you have backups of your data before you activate this feature.
|
||||||
|
|
||||||
This inludes beta releases for:
|
This inludes beta releases for:
|
||||||
- Home Assistant (Release Candidates)
|
- Home Assistant (Release Candidates)
|
||||||
- Hass.io supervisor
|
- Hass.io supervisor
|
||||||
- Host system`)) {
|
- Host system`)
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const method = 'post';
|
const method = "post";
|
||||||
const path = 'hassio/supervisor/options';
|
const path = "hassio/supervisor/options";
|
||||||
const data = { channel: 'beta' };
|
const data = { channel: "beta" };
|
||||||
|
|
||||||
const eventData = {
|
const eventData = {
|
||||||
method: method,
|
method: method,
|
||||||
@@ -138,17 +140,22 @@ This inludes beta releases for:
|
|||||||
data: data,
|
data: data,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.hass.callApi(method, path, data)
|
this.hass
|
||||||
.then((resp) => {
|
.callApi(method, path, data)
|
||||||
|
.then(
|
||||||
|
(resp) => {
|
||||||
eventData.success = true;
|
eventData.success = true;
|
||||||
eventData.response = resp;
|
eventData.response = resp;
|
||||||
}, (resp) => {
|
},
|
||||||
|
(resp) => {
|
||||||
eventData.success = false;
|
eventData.success = false;
|
||||||
eventData.response = resp;
|
eventData.response = resp;
|
||||||
}).then(() => {
|
}
|
||||||
this.fire('hass-api-called', eventData);
|
)
|
||||||
|
.then(() => {
|
||||||
|
this.fire("hass-api-called", eventData);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-supervisor-info', HassioSupervisorInfo);
|
customElements.define("hassio-supervisor-info", HassioSupervisorInfo);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import '@polymer/paper-button/paper-button.js';
|
import "@polymer/paper-button/paper-button.js";
|
||||||
import '@polymer/paper-card/paper-card.js';
|
import "@polymer/paper-card/paper-card.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
class HassioSupervisorLog extends PolymerElement {
|
class HassioSupervisorLog extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -38,12 +38,14 @@ class HassioSupervisorLog extends PolymerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadData() {
|
loadData() {
|
||||||
this.hass.callApi('get', 'hassio/supervisor/logs')
|
this.hass.callApi("get", "hassio/supervisor/logs").then(
|
||||||
.then((info) => {
|
(info) => {
|
||||||
this.log = info;
|
this.log = info;
|
||||||
}, () => {
|
},
|
||||||
this.log = 'Error fetching logs';
|
() => {
|
||||||
});
|
this.log = "Error fetching logs";
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshTapped() {
|
refreshTapped() {
|
||||||
@@ -51,4 +53,4 @@ class HassioSupervisorLog extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-supervisor-log', HassioSupervisorLog);
|
customElements.define("hassio-supervisor-log", HassioSupervisorLog);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
import "@polymer/iron-flex-layout/iron-flex-layout-classes.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import './hassio-host-info.js';
|
import "./hassio-host-info.js";
|
||||||
import './hassio-supervisor-info.js';
|
import "./hassio-supervisor-info.js";
|
||||||
import './hassio-supervisor-log.js';
|
import "./hassio-supervisor-log.js";
|
||||||
|
|
||||||
class HassioSystem extends PolymerElement {
|
class HassioSystem extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -40,4 +40,4 @@ class HassioSystem extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('hassio-system', HassioSystem);
|
customElements.define("hassio-system", HassioSystem);
|
||||||
|
|||||||
@@ -1,26 +1,25 @@
|
|||||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
|
||||||
const CompressionPlugin = require("compression-webpack-plugin");
|
const CompressionPlugin = require("compression-webpack-plugin");
|
||||||
const config = require('./config.js');
|
const config = require("./config.js");
|
||||||
|
|
||||||
const isProdBuild = process.env.NODE_ENV === 'production'
|
const isProdBuild = process.env.NODE_ENV === "production";
|
||||||
const chunkFilename = isProdBuild ?
|
const chunkFilename = isProdBuild ? "chunk.[chunkhash].js" : "[name].chunk.js";
|
||||||
'chunk.[chunkhash].js' : '[name].chunk.js';
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: isProdBuild ? 'production' : 'development',
|
mode: isProdBuild ? "production" : "development",
|
||||||
devtool: isProdBuild ? 'source-map' : 'inline-source-map',
|
devtool: isProdBuild ? "source-map" : "inline-source-map",
|
||||||
entry: {
|
entry: {
|
||||||
entrypoint: './src/entrypoint.js',
|
entrypoint: "./src/entrypoint.js",
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.m?js$/,
|
test: /\.m?js$/,
|
||||||
use: {
|
use: {
|
||||||
loader: 'babel-loader',
|
loader: "babel-loader",
|
||||||
options: {
|
options: {
|
||||||
presets: [
|
presets: [
|
||||||
[require('babel-preset-env').default, { modules: false }]
|
[require("babel-preset-env").default, { modules: false }],
|
||||||
],
|
],
|
||||||
plugins: [
|
plugins: [
|
||||||
// Only support the syntax, Webpack will handle it.
|
// Only support the syntax, Webpack will handle it.
|
||||||
@@ -32,38 +31,34 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
test: /\.(html)$/,
|
test: /\.(html)$/,
|
||||||
use: {
|
use: {
|
||||||
loader: 'html-loader',
|
loader: "html-loader",
|
||||||
options: {
|
options: {
|
||||||
exportAsEs6Default: true,
|
exportAsEs6Default: true,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
|
],
|
||||||
]
|
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
isProdBuild && new UglifyJsPlugin({
|
isProdBuild &&
|
||||||
|
new UglifyJsPlugin({
|
||||||
extractComments: true,
|
extractComments: true,
|
||||||
sourceMap: true,
|
sourceMap: true,
|
||||||
uglifyOptions: {
|
uglifyOptions: {
|
||||||
// Disabling because it broke output
|
// Disabling because it broke output
|
||||||
mangle: false,
|
mangle: false,
|
||||||
}
|
},
|
||||||
}),
|
}),
|
||||||
isProdBuild && new CompressionPlugin({
|
isProdBuild &&
|
||||||
|
new CompressionPlugin({
|
||||||
cache: true,
|
cache: true,
|
||||||
exclude: [
|
exclude: [/\.js\.map$/, /\.LICENSE$/, /\.py$/, /\.txt$/],
|
||||||
/\.js\.map$/,
|
|
||||||
/\.LICENSE$/,
|
|
||||||
/\.py$/,
|
|
||||||
/\.txt$/,
|
|
||||||
]
|
|
||||||
}),
|
}),
|
||||||
].filter(Boolean),
|
].filter(Boolean),
|
||||||
output: {
|
output: {
|
||||||
filename: '[name].js',
|
filename: "[name].js",
|
||||||
chunkFilename,
|
chunkFilename,
|
||||||
path: config.buildDir,
|
path: config.buildDir,
|
||||||
publicPath: `${config.publicPath}/`,
|
publicPath: `${config.publicPath}/`,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
22
package.json
22
package.json
@@ -104,7 +104,9 @@
|
|||||||
"del": "^3.0.0",
|
"del": "^3.0.0",
|
||||||
"eslint": "^5.6.0",
|
"eslint": "^5.6.0",
|
||||||
"eslint-config-airbnb-base": "^13.1.0",
|
"eslint-config-airbnb-base": "^13.1.0",
|
||||||
|
"eslint-config-prettier": "^3.1.0",
|
||||||
"eslint-plugin-import": "^2.14.0",
|
"eslint-plugin-import": "^2.14.0",
|
||||||
|
"eslint-plugin-prettier": "^3.0.0",
|
||||||
"eslint-plugin-react": "^7.11.1",
|
"eslint-plugin-react": "^7.11.1",
|
||||||
"gulp": "^3.9.1",
|
"gulp": "^3.9.1",
|
||||||
"gulp-foreach": "^0.1.0",
|
"gulp-foreach": "^0.1.0",
|
||||||
@@ -117,12 +119,15 @@
|
|||||||
"html-loader": "^0.5.5",
|
"html-loader": "^0.5.5",
|
||||||
"html-minifier": "^3.5.20",
|
"html-minifier": "^3.5.20",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
|
"husky": "^1.1.0",
|
||||||
|
"lint-staged": "^7.3.0",
|
||||||
"merge-stream": "^1.0.1",
|
"merge-stream": "^1.0.1",
|
||||||
"mocha": "^5.2.0",
|
"mocha": "^5.2.0",
|
||||||
"parse5": "^5.1.0",
|
"parse5": "^5.1.0",
|
||||||
"polymer-analyzer": "^3.1.2",
|
"polymer-analyzer": "^3.1.2",
|
||||||
"polymer-bundler": "^4.0.2",
|
"polymer-bundler": "^4.0.2",
|
||||||
"polymer-cli": "^1.8.0",
|
"polymer-cli": "^1.8.0",
|
||||||
|
"prettier": "^1.14.3",
|
||||||
"raw-loader": "^0.5.1",
|
"raw-loader": "^0.5.1",
|
||||||
"reify": "^0.17.3",
|
"reify": "^0.17.3",
|
||||||
"require-dir": "^1.0.0",
|
"require-dir": "^1.0.0",
|
||||||
@@ -146,5 +151,20 @@
|
|||||||
"@vaadin/vaadin-lumo-styles": "1.2.0",
|
"@vaadin/vaadin-lumo-styles": "1.2.0",
|
||||||
"fecha": "https://github.com/balloob/fecha/archive/51d14fd0eb4781e2ecf265d1c3080706259133b5.tar.gz"
|
"fecha": "https://github.com/balloob/fecha/archive/51d14fd0eb4781e2ecf265d1c3080706259133b5.tar.gz"
|
||||||
},
|
},
|
||||||
"main": "src/home-assistant.js"
|
"main": "src/home-assistant.js",
|
||||||
|
"husky": {
|
||||||
|
"hooks": {
|
||||||
|
"pre-commit": "lint-staged"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"*.{js,json,css,md}": [
|
||||||
|
"prettier --write",
|
||||||
|
"git add"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"prettier": {
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"arrowParens": "always"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
import '@polymer/paper-button/paper-button.js';
|
import "@polymer/paper-button/paper-button.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import '../components/ha-form.js';
|
import "../components/ha-form.js";
|
||||||
import LocalizeLiteMixin from '../mixins/localize-lite-mixin.js';
|
import LocalizeLiteMixin from "../mixins/localize-lite-mixin.js";
|
||||||
|
|
||||||
class HaAuthFlow extends LocalizeLiteMixin(PolymerElement) {
|
class HaAuthFlow extends LocalizeLiteMixin(PolymerElement) {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -61,14 +61,14 @@ class HaAuthFlow extends LocalizeLiteMixin(PolymerElement) {
|
|||||||
return {
|
return {
|
||||||
authProvider: {
|
authProvider: {
|
||||||
type: Object,
|
type: Object,
|
||||||
observer: '_providerChanged',
|
observer: "_providerChanged",
|
||||||
},
|
},
|
||||||
clientId: String,
|
clientId: String,
|
||||||
redirectUri: String,
|
redirectUri: String,
|
||||||
oauth2State: String,
|
oauth2State: String,
|
||||||
_state: {
|
_state: {
|
||||||
type: String,
|
type: String,
|
||||||
value: 'loading'
|
value: "loading",
|
||||||
},
|
},
|
||||||
_stepData: {
|
_stepData: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -85,7 +85,7 @@ class HaAuthFlow extends LocalizeLiteMixin(PolymerElement) {
|
|||||||
ready() {
|
ready() {
|
||||||
super.ready();
|
super.ready();
|
||||||
|
|
||||||
this.addEventListener('keypress', (ev) => {
|
this.addEventListener("keypress", (ev) => {
|
||||||
if (ev.keyCode === 13) {
|
if (ev.keyCode === 13) {
|
||||||
this._handleSubmit();
|
this._handleSubmit();
|
||||||
}
|
}
|
||||||
@@ -93,22 +93,22 @@ class HaAuthFlow extends LocalizeLiteMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async _providerChanged(newProvider, oldProvider) {
|
async _providerChanged(newProvider, oldProvider) {
|
||||||
if (oldProvider && this._step && this._step.type === 'form') {
|
if (oldProvider && this._step && this._step.type === "form") {
|
||||||
fetch(`/auth/login_flow/${this._step.flow_id}`, {
|
fetch(`/auth/login_flow/${this._step.flow_id}`, {
|
||||||
method: 'DELETE',
|
method: "DELETE",
|
||||||
credentials: 'same-origin',
|
credentials: "same-origin",
|
||||||
}).catch(() => {});
|
}).catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/auth/login_flow', {
|
const response = await fetch("/auth/login_flow", {
|
||||||
method: 'POST',
|
method: "POST",
|
||||||
credentials: 'same-origin',
|
credentials: "same-origin",
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
client_id: this.clientId,
|
client_id: this.clientId,
|
||||||
handler: [newProvider.type, newProvider.id],
|
handler: [newProvider.type, newProvider.id],
|
||||||
redirect_uri: this.redirectUri,
|
redirect_uri: this.redirectUri,
|
||||||
})
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
@@ -117,16 +117,16 @@ class HaAuthFlow extends LocalizeLiteMixin(PolymerElement) {
|
|||||||
this._updateStep(data);
|
this._updateStep(data);
|
||||||
} else {
|
} else {
|
||||||
this.setProperties({
|
this.setProperties({
|
||||||
_state: 'error',
|
_state: "error",
|
||||||
_errorMsg: data.message,
|
_errorMsg: data.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
console.error('Error starting auth flow', err);
|
console.error("Error starting auth flow", err);
|
||||||
this.setProperties({
|
this.setProperties({
|
||||||
_state: 'error',
|
_state: "error",
|
||||||
_errorMsg: this.localize('ui.panel.page-authorize.form.unknown_error'),
|
_errorMsg: this.localize("ui.panel.page-authorize.form.unknown_error"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,11 +134,14 @@ class HaAuthFlow extends LocalizeLiteMixin(PolymerElement) {
|
|||||||
_updateStep(step) {
|
_updateStep(step) {
|
||||||
const props = {
|
const props = {
|
||||||
_step: step,
|
_step: step,
|
||||||
_state: 'step',
|
_state: "step",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this._step
|
if (
|
||||||
&& (step.flow_id !== this._step.flow_id || step.step_id !== this._step.step_id)) {
|
this._step &&
|
||||||
|
(step.flow_id !== this._step.flow_id ||
|
||||||
|
step.step_id !== this._step.step_id)
|
||||||
|
) {
|
||||||
props._stepData = {};
|
props._stepData = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,15 +153,23 @@ class HaAuthFlow extends LocalizeLiteMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_computeSubmitCaption(stepType) {
|
_computeSubmitCaption(stepType) {
|
||||||
return stepType === 'form' ? 'Next' : 'Start over';
|
return stepType === "form" ? "Next" : "Start over";
|
||||||
}
|
}
|
||||||
|
|
||||||
_computeStepAbortedReason(localize, step) {
|
_computeStepAbortedReason(localize, step) {
|
||||||
return localize(`ui.panel.page-authorize.form.providers.${step.handler[0]}.abort.${step.reason}`);
|
return localize(
|
||||||
|
`ui.panel.page-authorize.form.providers.${step.handler[0]}.abort.${
|
||||||
|
step.reason
|
||||||
|
}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_computeStepDescription(localize, step) {
|
_computeStepDescription(localize, step) {
|
||||||
const args = [`ui.panel.page-authorize.form.providers.${step.handler[0]}.step.${step.step_id}.description`];
|
const args = [
|
||||||
|
`ui.panel.page-authorize.form.providers.${step.handler[0]}.step.${
|
||||||
|
step.step_id
|
||||||
|
}.description`,
|
||||||
|
];
|
||||||
const placeholders = step.description_placeholders || {};
|
const placeholders = step.description_placeholders || {};
|
||||||
Object.keys(placeholders).forEach((key) => {
|
Object.keys(placeholders).forEach((key) => {
|
||||||
args.push(key);
|
args.push(key);
|
||||||
@@ -169,22 +180,32 @@ class HaAuthFlow extends LocalizeLiteMixin(PolymerElement) {
|
|||||||
|
|
||||||
_computeLabelCallback(localize, step) {
|
_computeLabelCallback(localize, step) {
|
||||||
// Returns a callback for ha-form to calculate labels per schema object
|
// Returns a callback for ha-form to calculate labels per schema object
|
||||||
return schema => localize(`ui.panel.page-authorize.form.providers.${step.handler[0]}.step.${step.step_id}.data.${schema.name}`);
|
return (schema) =>
|
||||||
|
localize(
|
||||||
|
`ui.panel.page-authorize.form.providers.${step.handler[0]}.step.${
|
||||||
|
step.step_id
|
||||||
|
}.data.${schema.name}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_computeErrorCallback(localize, step) {
|
_computeErrorCallback(localize, step) {
|
||||||
// Returns a callback for ha-form to calculate error messages
|
// Returns a callback for ha-form to calculate error messages
|
||||||
return error => localize(`ui.panel.page-authorize.form.providers.${step.handler[0]}.error.${error}`);
|
return (error) =>
|
||||||
|
localize(
|
||||||
|
`ui.panel.page-authorize.form.providers.${
|
||||||
|
step.handler[0]
|
||||||
|
}.error.${error}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _handleSubmit() {
|
async _handleSubmit() {
|
||||||
if (this._step.type !== 'form') {
|
if (this._step.type !== "form") {
|
||||||
this._providerChanged(this.authProvider, null);
|
this._providerChanged(this.authProvider, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._state = 'loading';
|
this._state = "loading";
|
||||||
// To avoid a jumping UI.
|
// To avoid a jumping UI.
|
||||||
this.style.setProperty('min-height', `${this.offsetHeight}px`);
|
this.style.setProperty("min-height", `${this.offsetHeight}px`);
|
||||||
|
|
||||||
const postData = Object.assign({}, this._stepData, {
|
const postData = Object.assign({}, this._stepData, {
|
||||||
client_id: this.clientId,
|
client_id: this.clientId,
|
||||||
@@ -192,20 +213,20 @@ class HaAuthFlow extends LocalizeLiteMixin(PolymerElement) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/auth/login_flow/${this._step.flow_id}`, {
|
const response = await fetch(`/auth/login_flow/${this._step.flow_id}`, {
|
||||||
method: 'POST',
|
method: "POST",
|
||||||
credentials: 'same-origin',
|
credentials: "same-origin",
|
||||||
body: JSON.stringify(postData)
|
body: JSON.stringify(postData),
|
||||||
});
|
});
|
||||||
|
|
||||||
const newStep = await response.json();
|
const newStep = await response.json();
|
||||||
|
|
||||||
if (newStep.type === 'create_entry') {
|
if (newStep.type === "create_entry") {
|
||||||
// OAuth 2: 3.1.2 we need to retain query component of a redirect URI
|
// OAuth 2: 3.1.2 we need to retain query component of a redirect URI
|
||||||
let url = this.redirectUri;
|
let url = this.redirectUri;
|
||||||
if (!url.includes('?')) {
|
if (!url.includes("?")) {
|
||||||
url += '?';
|
url += "?";
|
||||||
} else if (!url.endsWith('&')) {
|
} else if (!url.endsWith("&")) {
|
||||||
url += '&';
|
url += "&";
|
||||||
}
|
}
|
||||||
|
|
||||||
url += `code=${encodeURIComponent(newStep.result)}`;
|
url += `code=${encodeURIComponent(newStep.result)}`;
|
||||||
@@ -220,11 +241,11 @@ class HaAuthFlow extends LocalizeLiteMixin(PolymerElement) {
|
|||||||
this._updateStep(newStep);
|
this._updateStep(newStep);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
console.error('Error submitting step', err);
|
console.error("Error submitting step", err);
|
||||||
this._state = 'error-loading';
|
this._state = "error-loading";
|
||||||
} finally {
|
} finally {
|
||||||
this.style.setProperty('min-height', '');
|
this.style.setProperty("min-height", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define('ha-auth-flow', HaAuthFlow);
|
customElements.define("ha-auth-flow", HaAuthFlow);
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import '@polymer/polymer/lib/elements/dom-if.js';
|
import "@polymer/polymer/lib/elements/dom-if.js";
|
||||||
import '@polymer/polymer/lib/elements/dom-repeat.js';
|
import "@polymer/polymer/lib/elements/dom-repeat.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/ha-markdown.js';
|
import "../components/ha-markdown.js";
|
||||||
|
|
||||||
import LocalizeLiteMixin from '../mixins/localize-lite-mixin.js';
|
import LocalizeLiteMixin from "../mixins/localize-lite-mixin.js";
|
||||||
|
|
||||||
import './ha-auth-flow.js';
|
import "./ha-auth-flow.js";
|
||||||
|
|
||||||
class HaAuthorize extends LocalizeLiteMixin(PolymerElement) {
|
class HaAuthorize extends LocalizeLiteMixin(PolymerElement) {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -66,17 +66,17 @@ class HaAuthorize extends LocalizeLiteMixin(PolymerElement) {
|
|||||||
oauth2State: String,
|
oauth2State: String,
|
||||||
translationFragment: {
|
translationFragment: {
|
||||||
type: String,
|
type: String,
|
||||||
value: 'page-authorize',
|
value: "page-authorize",
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async ready() {
|
async ready() {
|
||||||
super.ready();
|
super.ready();
|
||||||
const query = {};
|
const query = {};
|
||||||
const values = location.search.substr(1).split('&');
|
const values = location.search.substr(1).split("&");
|
||||||
for (let i = 0; i < values.length; i++) {
|
for (let i = 0; i < values.length; i++) {
|
||||||
const value = values[i].split('=');
|
const value = values[i].split("=");
|
||||||
if (value.length > 1) {
|
if (value.length > 1) {
|
||||||
query[decodeURIComponent(value[0])] = decodeURIComponent(value[1]);
|
query[decodeURIComponent(value[0])] = decodeURIComponent(value[1]);
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ class HaAuthorize extends LocalizeLiteMixin(PolymerElement) {
|
|||||||
if (query.state) props.oauth2State = query.state;
|
if (query.state) props.oauth2State = query.state;
|
||||||
this.setProperties(props);
|
this.setProperties(props);
|
||||||
|
|
||||||
import(/* webpackChunkName: "pick-auth-provider" */ '../auth/ha-pick-auth-provider.js');
|
import(/* webpackChunkName: "pick-auth-provider" */ "../auth/ha-pick-auth-provider.js");
|
||||||
|
|
||||||
// Fetch auth providers
|
// Fetch auth providers
|
||||||
try {
|
try {
|
||||||
@@ -95,13 +95,16 @@ class HaAuthorize extends LocalizeLiteMixin(PolymerElement) {
|
|||||||
const authProviders = await response.json();
|
const authProviders = await response.json();
|
||||||
|
|
||||||
// Forward to main screen which will redirect to right onboarding page.
|
// Forward to main screen which will redirect to right onboarding page.
|
||||||
if (response.status === 400 && authProviders.code === 'onboarding_required') {
|
if (
|
||||||
location.href = '/';
|
response.status === 400 &&
|
||||||
|
authProviders.code === "onboarding_required"
|
||||||
|
) {
|
||||||
|
location.href = "/";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (authProviders.length === 0) {
|
if (authProviders.length === 0) {
|
||||||
alert('No auth providers returned. Unable to finish login.');
|
alert("No auth providers returned. Unable to finish login.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,8 +114,8 @@ class HaAuthorize extends LocalizeLiteMixin(PolymerElement) {
|
|||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
console.error('Error loading auth providers', err);
|
console.error("Error loading auth providers", err);
|
||||||
this._state = 'error-loading';
|
this._state = "error-loading";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,15 +128,25 @@ class HaAuthorize extends LocalizeLiteMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_computeInactiveProvders(curProvider, providers) {
|
_computeInactiveProvders(curProvider, providers) {
|
||||||
return providers.filter(prv => prv.type !== curProvider.type || prv.id !== curProvider.id);
|
return providers.filter(
|
||||||
|
(prv) => prv.type !== curProvider.type || prv.id !== curProvider.id
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_computeIntro(localize, clientId, authProvider) {
|
_computeIntro(localize, clientId, authProvider) {
|
||||||
return (
|
return (
|
||||||
localize('ui.panel.page-authorize.authorizing_client', 'clientId', clientId)
|
localize(
|
||||||
+ '\n\n'
|
"ui.panel.page-authorize.authorizing_client",
|
||||||
+ localize('ui.panel.page-authorize.logging_in_with', 'authProviderName', authProvider.name)
|
"clientId",
|
||||||
|
clientId
|
||||||
|
) +
|
||||||
|
"\n\n" +
|
||||||
|
localize(
|
||||||
|
"ui.panel.page-authorize.logging_in_with",
|
||||||
|
"authProviderName",
|
||||||
|
authProvider.name
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define('ha-authorize', HaAuthorize);
|
customElements.define("ha-authorize", HaAuthorize);
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
import '@polymer/paper-item/paper-item.js';
|
import "@polymer/paper-item/paper-item.js";
|
||||||
import '@polymer/paper-item/paper-item-body.js';
|
import "@polymer/paper-item/paper-item-body.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import EventsMixin from '../mixins/events-mixin.js';
|
import EventsMixin from "../mixins/events-mixin.js";
|
||||||
import LocalizeLiteMixin from '../mixins/localize-lite-mixin.js';
|
import LocalizeLiteMixin from "../mixins/localize-lite-mixin.js";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @appliesMixin EventsMixin
|
* @appliesMixin EventsMixin
|
||||||
*/
|
*/
|
||||||
class HaPickAuthProvider extends EventsMixin(LocalizeLiteMixin(PolymerElement)) {
|
class HaPickAuthProvider extends EventsMixin(
|
||||||
|
LocalizeLiteMixin(PolymerElement)
|
||||||
|
) {
|
||||||
static get template() {
|
static get template() {
|
||||||
return html`
|
return html`
|
||||||
<style>
|
<style>
|
||||||
@@ -34,18 +36,18 @@ class HaPickAuthProvider extends EventsMixin(LocalizeLiteMixin(PolymerElement))
|
|||||||
return {
|
return {
|
||||||
_state: {
|
_state: {
|
||||||
type: String,
|
type: String,
|
||||||
value: 'loading'
|
value: "loading",
|
||||||
},
|
},
|
||||||
authProviders: Array,
|
authProviders: Array,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_handlePick(ev) {
|
_handlePick(ev) {
|
||||||
this.fire('pick', ev.model.item);
|
this.fire("pick", ev.model.item);
|
||||||
}
|
}
|
||||||
|
|
||||||
_equal(a, b) {
|
_equal(a, b) {
|
||||||
return a === b;
|
return a === b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define('ha-pick-auth-provider', HaPickAuthProvider);
|
customElements.define("ha-pick-auth-provider", HaPickAuthProvider);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/entity/ha-state-label-badge.js';
|
import "../components/entity/ha-state-label-badge.js";
|
||||||
|
|
||||||
class HaBadgesCard extends PolymerElement {
|
class HaBadgesCard extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -25,4 +25,4 @@ class HaBadgesCard extends PolymerElement {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define('ha-badges-card', HaBadgesCard);
|
customElements.define("ha-badges-card", HaBadgesCard);
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import '@polymer/paper-styles/element-styles/paper-material-styles.js';
|
import "@polymer/paper-styles/element-styles/paper-material-styles.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
|
import computeStateName from "../common/entity/compute_state_name.js";
|
||||||
import computeStateName from '../common/entity/compute_state_name.js';
|
import EventsMixin from "../mixins/events-mixin.js";
|
||||||
import EventsMixin from '../mixins/events-mixin.js';
|
import LocalizeMixin from "../mixins/localize-mixin.js";
|
||||||
import LocalizeMixin from '../mixins/localize-mixin.js';
|
|
||||||
|
|
||||||
const UPDATE_INTERVAL = 10000; // ms
|
const UPDATE_INTERVAL = 10000; // ms
|
||||||
/*
|
/*
|
||||||
@@ -67,11 +66,11 @@ class HaCameraCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
hass: Object,
|
hass: Object,
|
||||||
stateObj: {
|
stateObj: {
|
||||||
type: Object,
|
type: Object,
|
||||||
observer: 'updateCameraFeedSrc',
|
observer: "updateCameraFeedSrc",
|
||||||
},
|
},
|
||||||
cameraFeedSrc: {
|
cameraFeedSrc: {
|
||||||
type: String,
|
type: String,
|
||||||
value: '',
|
value: "",
|
||||||
},
|
},
|
||||||
imageLoaded: {
|
imageLoaded: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@@ -82,7 +81,7 @@ class HaCameraCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
|
|
||||||
ready() {
|
ready() {
|
||||||
super.ready();
|
super.ready();
|
||||||
this.addEventListener('click', () => this.cardTapped());
|
this.addEventListener("click", () => this.cardTapped());
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
@@ -96,13 +95,13 @@ class HaCameraCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cardTapped() {
|
cardTapped() {
|
||||||
this.fire('hass-more-info', { entityId: this.stateObj.entity_id });
|
this.fire("hass-more-info", { entityId: this.stateObj.entity_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateCameraFeedSrc() {
|
async updateCameraFeedSrc() {
|
||||||
try {
|
try {
|
||||||
const { content_type: contentType, content } = await this.hass.callWS({
|
const { content_type: contentType, content } = await this.hass.callWS({
|
||||||
type: 'camera_thumbnail',
|
type: "camera_thumbnail",
|
||||||
entity_id: this.stateObj.entity_id,
|
entity_id: this.stateObj.entity_id,
|
||||||
});
|
});
|
||||||
this.setProperties({
|
this.setProperties({
|
||||||
@@ -118,4 +117,4 @@ class HaCameraCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
return computeStateName(stateObj);
|
return computeStateName(stateObj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define('ha-camera-card', HaCameraCard);
|
customElements.define("ha-camera-card", HaCameraCard);
|
||||||
|
|||||||
@@ -1,28 +1,29 @@
|
|||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import './ha-camera-card.js';
|
import "./ha-camera-card.js";
|
||||||
import './ha-entities-card.js';
|
import "./ha-entities-card.js";
|
||||||
import './ha-history_graph-card.js';
|
import "./ha-history_graph-card.js";
|
||||||
import './ha-media_player-card.js';
|
import "./ha-media_player-card.js";
|
||||||
import './ha-persistent_notification-card.js';
|
import "./ha-persistent_notification-card.js";
|
||||||
import './ha-plant-card.js';
|
import "./ha-plant-card.js";
|
||||||
import './ha-weather-card.js';
|
import "./ha-weather-card.js";
|
||||||
|
|
||||||
import dynamicContentUpdater from '../common/dom/dynamic_content_updater.js';
|
import dynamicContentUpdater from "../common/dom/dynamic_content_updater.js";
|
||||||
|
|
||||||
class HaCardChooser extends PolymerElement {
|
class HaCardChooser extends PolymerElement {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
cardData: {
|
cardData: {
|
||||||
type: Object,
|
type: Object,
|
||||||
observer: 'cardDataChanged',
|
observer: "cardDataChanged",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateCard(newData) {
|
_updateCard(newData) {
|
||||||
dynamicContentUpdater(
|
dynamicContentUpdater(
|
||||||
this, 'HA-' + newData.cardType.toUpperCase() + '-CARD',
|
this,
|
||||||
|
"HA-" + newData.cardType.toUpperCase() + "-CARD",
|
||||||
newData
|
newData
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -32,7 +33,7 @@ class HaCardChooser extends PolymerElement {
|
|||||||
this.observer = new IntersectionObserver((entries) => {
|
this.observer = new IntersectionObserver((entries) => {
|
||||||
if (!entries.length) return;
|
if (!entries.length) return;
|
||||||
if (entries[0].isIntersecting) {
|
if (entries[0].isIntersecting) {
|
||||||
this.style.height = '';
|
this.style.height = "";
|
||||||
if (this._detachedChild) {
|
if (this._detachedChild) {
|
||||||
this.appendChild(this._detachedChild);
|
this.appendChild(this._detachedChild);
|
||||||
this._detachedChild = null;
|
this._detachedChild = null;
|
||||||
@@ -58,13 +59,14 @@ class HaCardChooser extends PolymerElement {
|
|||||||
if (!newData) return;
|
if (!newData) return;
|
||||||
// ha-entities-card is exempt from observer as it doesn't load heavy resources.
|
// ha-entities-card is exempt from observer as it doesn't load heavy resources.
|
||||||
// and usually doesn't load external resources (except for entity_picture).
|
// and usually doesn't load external resources (except for entity_picture).
|
||||||
const eligibleToObserver = (window.IntersectionObserver && newData.cardType !== 'entities');
|
const eligibleToObserver =
|
||||||
|
window.IntersectionObserver && newData.cardType !== "entities";
|
||||||
if (!eligibleToObserver) {
|
if (!eligibleToObserver) {
|
||||||
if (this.observer) {
|
if (this.observer) {
|
||||||
this.observer.unobserve(this);
|
this.observer.unobserve(this);
|
||||||
this.observer = null;
|
this.observer = null;
|
||||||
}
|
}
|
||||||
this.style.height = '';
|
this.style.height = "";
|
||||||
this._updateCard(newData);
|
this._updateCard(newData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -76,4 +78,4 @@ class HaCardChooser extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define('ha-card-chooser', HaCardChooser);
|
customElements.define("ha-card-chooser", HaCardChooser);
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
import "@polymer/iron-flex-layout/iron-flex-layout-classes.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/entity/ha-entity-toggle.js';
|
import "../components/entity/ha-entity-toggle.js";
|
||||||
import '../components/ha-card.js';
|
import "../components/ha-card.js";
|
||||||
import '../state-summary/state-card-content.js';
|
import "../state-summary/state-card-content.js";
|
||||||
|
|
||||||
|
import computeStateDomain from "../common/entity/compute_state_domain.js";
|
||||||
import computeStateDomain from '../common/entity/compute_state_domain.js';
|
import computeStateName from "../common/entity/compute_state_name.js";
|
||||||
import computeStateName from '../common/entity/compute_state_name.js';
|
import stateMoreInfoType from "../common/entity/state_more_info_type.js";
|
||||||
import stateMoreInfoType from '../common/entity/state_more_info_type.js';
|
import canToggleState from "../common/entity/can_toggle_state.js";
|
||||||
import canToggleState from '../common/entity/can_toggle_state.js';
|
import EventsMixin from "../mixins/events-mixin.js";
|
||||||
import EventsMixin from '../mixins/events-mixin.js';
|
import LocalizeMixin from "../mixins/localize-mixin.js";
|
||||||
import LocalizeMixin from '../mixins/localize-mixin.js';
|
|
||||||
|
|
||||||
class HaEntitiesCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
class HaEntitiesCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -74,7 +73,7 @@ class HaEntitiesCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
groupEntity: Object,
|
groupEntity: Object,
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
computed: 'computeTitle(states, groupEntity, localize)',
|
computed: "computeTitle(states, groupEntity, localize)",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -91,34 +90,40 @@ class HaEntitiesCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
return computeStateName(groupEntity).trim();
|
return computeStateName(groupEntity).trim();
|
||||||
}
|
}
|
||||||
const domain = computeStateDomain(states[0]);
|
const domain = computeStateDomain(states[0]);
|
||||||
return (localize && localize(`domain.${domain}`)) || domain.replace(/_/g, ' ');
|
return (
|
||||||
|
(localize && localize(`domain.${domain}`)) || domain.replace(/_/g, " ")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
computeTitleClass(groupEntity) {
|
computeTitleClass(groupEntity) {
|
||||||
let classes = 'header horizontal layout center ';
|
let classes = "header horizontal layout center ";
|
||||||
if (groupEntity) {
|
if (groupEntity) {
|
||||||
classes += 'more-info';
|
classes += "more-info";
|
||||||
}
|
}
|
||||||
return classes;
|
return classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
computeStateClass(stateObj) {
|
computeStateClass(stateObj) {
|
||||||
return stateMoreInfoType(stateObj) !== 'hidden' ? 'state more-info' : 'state';
|
return stateMoreInfoType(stateObj) !== "hidden"
|
||||||
|
? "state more-info"
|
||||||
|
: "state";
|
||||||
}
|
}
|
||||||
|
|
||||||
addTapEvents() {
|
addTapEvents() {
|
||||||
const cards = this.root.querySelectorAll('.state');
|
const cards = this.root.querySelectorAll(".state");
|
||||||
cards.forEach((card) => {
|
cards.forEach((card) => {
|
||||||
if (card.classList.contains('more-info')) {
|
if (card.classList.contains("more-info")) {
|
||||||
card.addEventListener('click', this.entityTapped);
|
card.addEventListener("click", this.entityTapped);
|
||||||
} else {
|
} else {
|
||||||
card.removeEventListener('click', this.entityTapped);
|
card.removeEventListener("click", this.entityTapped);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
entityTapped(ev) {
|
entityTapped(ev) {
|
||||||
const item = this.root.querySelector('dom-repeat').itemForElement(ev.target);
|
const item = this.root
|
||||||
|
.querySelector("dom-repeat")
|
||||||
|
.itemForElement(ev.target);
|
||||||
let entityId;
|
let entityId;
|
||||||
if (!item && !this.groupEntity) {
|
if (!item && !this.groupEntity) {
|
||||||
return;
|
return;
|
||||||
@@ -130,12 +135,16 @@ class HaEntitiesCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
} else {
|
} else {
|
||||||
entityId = this.groupEntity.entity_id;
|
entityId = this.groupEntity.entity_id;
|
||||||
}
|
}
|
||||||
this.fire('hass-more-info', { entityId: entityId });
|
this.fire("hass-more-info", { entityId: entityId });
|
||||||
}
|
}
|
||||||
|
|
||||||
showGroupToggle(groupEntity, states) {
|
showGroupToggle(groupEntity, states) {
|
||||||
if (!groupEntity || !states || groupEntity.attributes.control === 'hidden'
|
if (
|
||||||
|| (groupEntity.state !== 'on' && groupEntity.state !== 'off')) {
|
!groupEntity ||
|
||||||
|
!states ||
|
||||||
|
groupEntity.attributes.control === "hidden" ||
|
||||||
|
(groupEntity.state !== "on" && groupEntity.state !== "off")
|
||||||
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,4 +165,4 @@ class HaEntitiesCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
return canToggleCount > 1;
|
return canToggleCount > 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define('ha-entities-card', HaEntitiesCard);
|
customElements.define("ha-entities-card", HaEntitiesCard);
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import '@polymer/paper-card/paper-card.js';
|
import "@polymer/paper-card/paper-card.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/state-history-charts.js';
|
import "../components/state-history-charts.js";
|
||||||
import '../data/ha-state-history-data.js';
|
import "../data/ha-state-history-data.js";
|
||||||
|
|
||||||
|
import computeStateName from "../common/entity/compute_state_name.js";
|
||||||
import computeStateName from '../common/entity/compute_state_name.js';
|
import EventsMixin from "../mixins/events-mixin.js";
|
||||||
import EventsMixin from '../mixins/events-mixin.js';
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @appliesMixin EventsMixin
|
* @appliesMixin EventsMixin
|
||||||
@@ -55,7 +54,7 @@ class HaHistoryGraphCard extends EventsMixin(PolymerElement) {
|
|||||||
hass: Object,
|
hass: Object,
|
||||||
stateObj: {
|
stateObj: {
|
||||||
type: Object,
|
type: Object,
|
||||||
observer: 'stateObjObserver',
|
observer: "stateObjObserver",
|
||||||
},
|
},
|
||||||
inDialog: {
|
inDialog: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@@ -76,14 +75,19 @@ class HaHistoryGraphCard extends EventsMixin(PolymerElement) {
|
|||||||
|
|
||||||
stateObjObserver(stateObj) {
|
stateObjObserver(stateObj) {
|
||||||
if (!stateObj) return;
|
if (!stateObj) return;
|
||||||
if (this.cacheConfig.cacheKey !== stateObj.entity_id
|
if (
|
||||||
|| this.cacheConfig.refresh !== (stateObj.attributes.refresh || 0)
|
this.cacheConfig.cacheKey !== stateObj.entity_id ||
|
||||||
|| this.cacheConfig.hoursToShow !== (stateObj.attributes.hours_to_show || 24)) {
|
this.cacheConfig.refresh !== (stateObj.attributes.refresh || 0) ||
|
||||||
this.cacheConfig = Object.assign({}, {
|
this.cacheConfig.hoursToShow !== (stateObj.attributes.hours_to_show || 24)
|
||||||
|
) {
|
||||||
|
this.cacheConfig = Object.assign(
|
||||||
|
{},
|
||||||
|
{
|
||||||
refresh: stateObj.attributes.refresh || 0,
|
refresh: stateObj.attributes.refresh || 0,
|
||||||
cacheKey: stateObj.entity_id,
|
cacheKey: stateObj.entity_id,
|
||||||
hoursToShow: stateObj.attributes.hours_to_show || 24
|
hoursToShow: stateObj.attributes.hours_to_show || 24,
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +96,7 @@ class HaHistoryGraphCard extends EventsMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
computeContentClass(inDialog) {
|
computeContentClass(inDialog) {
|
||||||
return inDialog ? '' : 'content';
|
return inDialog ? "" : "content";
|
||||||
}
|
}
|
||||||
|
|
||||||
computeHistoryEntities(stateObj) {
|
computeHistoryEntities(stateObj) {
|
||||||
@@ -104,11 +108,11 @@ class HaHistoryGraphCard extends EventsMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cardTapped(ev) {
|
cardTapped(ev) {
|
||||||
const mq = window.matchMedia('(min-width: 610px) and (min-height: 550px)');
|
const mq = window.matchMedia("(min-width: 610px) and (min-height: 550px)");
|
||||||
if (mq.matches) {
|
if (mq.matches) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this.fire('hass-more-info', { entityId: this.stateObj.entity_id });
|
this.fire("hass-more-info", { entityId: this.stateObj.entity_id });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define('ha-history_graph-card', HaHistoryGraphCard);
|
customElements.define("ha-history_graph-card", HaHistoryGraphCard);
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
import "@polymer/iron-flex-layout/iron-flex-layout-classes.js";
|
||||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
import "@polymer/paper-icon-button/paper-icon-button.js";
|
||||||
import '@polymer/paper-progress/paper-progress.js';
|
import "@polymer/paper-progress/paper-progress.js";
|
||||||
import '@polymer/paper-styles/element-styles/paper-material-styles.js';
|
import "@polymer/paper-styles/element-styles/paper-material-styles.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import HassMediaPlayerEntity from '../util/hass-media-player-model.js';
|
import HassMediaPlayerEntity from "../util/hass-media-player-model.js";
|
||||||
|
|
||||||
import computeStateName from '../common/entity/compute_state_name.js';
|
import computeStateName from "../common/entity/compute_state_name.js";
|
||||||
import EventsMixin from '../mixins/events-mixin.js';
|
import EventsMixin from "../mixins/events-mixin.js";
|
||||||
import LocalizeMixin from '../mixins/localize-mixin.js';
|
import LocalizeMixin from "../mixins/localize-mixin.js";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @appliesMixin LocalizeMixin
|
* @appliesMixin LocalizeMixin
|
||||||
@@ -189,12 +189,12 @@ class HaMediaPlayerCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
stateObj: Object,
|
stateObj: Object,
|
||||||
playerObj: {
|
playerObj: {
|
||||||
type: Object,
|
type: Object,
|
||||||
computed: 'computePlayerObj(hass, stateObj)',
|
computed: "computePlayerObj(hass, stateObj)",
|
||||||
observer: 'playerObjChanged',
|
observer: "playerObjChanged",
|
||||||
},
|
},
|
||||||
playbackControlIcon: {
|
playbackControlIcon: {
|
||||||
type: String,
|
type: String,
|
||||||
computed: 'computePlaybackControlIcon(playerObj)',
|
computed: "computePlaybackControlIcon(playerObj)",
|
||||||
},
|
},
|
||||||
playbackPosition: Number,
|
playbackPosition: Number,
|
||||||
};
|
};
|
||||||
@@ -203,7 +203,10 @@ class HaMediaPlayerCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
async playerObjChanged(playerObj, oldPlayerObj) {
|
async playerObjChanged(playerObj, oldPlayerObj) {
|
||||||
if (playerObj.isPlaying && playerObj.showProgress) {
|
if (playerObj.isPlaying && playerObj.showProgress) {
|
||||||
if (!this._positionTracking) {
|
if (!this._positionTracking) {
|
||||||
this._positionTracking = setInterval(() => this.updatePlaybackPosition(), 1000);
|
this._positionTracking = setInterval(
|
||||||
|
() => this.updatePlaybackPosition(),
|
||||||
|
1000
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else if (this._positionTracking) {
|
} else if (this._positionTracking) {
|
||||||
clearInterval(this._positionTracking);
|
clearInterval(this._positionTracking);
|
||||||
@@ -214,25 +217,27 @@ class HaMediaPlayerCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const picture = playerObj.stateObj.attributes.entity_picture;
|
const picture = playerObj.stateObj.attributes.entity_picture;
|
||||||
const oldPicture = oldPlayerObj && oldPlayerObj.stateObj.attributes.entity_picture;
|
const oldPicture =
|
||||||
|
oldPlayerObj && oldPlayerObj.stateObj.attributes.entity_picture;
|
||||||
|
|
||||||
if (picture !== oldPicture && !picture) {
|
if (picture !== oldPicture && !picture) {
|
||||||
this.$.cover.style.backgroundImage = '';
|
this.$.cover.style.backgroundImage = "";
|
||||||
return;
|
return;
|
||||||
} if (picture === oldPicture) {
|
}
|
||||||
|
if (picture === oldPicture) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have a new picture url
|
// We have a new picture url
|
||||||
try {
|
try {
|
||||||
const { content_type: contentType, content } = await this.hass.callWS({
|
const { content_type: contentType, content } = await this.hass.callWS({
|
||||||
type: 'media_player_thumbnail',
|
type: "media_player_thumbnail",
|
||||||
entity_id: playerObj.stateObj.entity_id,
|
entity_id: playerObj.stateObj.entity_id,
|
||||||
});
|
});
|
||||||
this.$.cover.style.backgroundImage = `url(data:${contentType};base64,${content})`;
|
this.$.cover.style.backgroundImage = `url(data:${contentType};base64,${content})`;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.$.cover.style.backgroundImage = '';
|
this.$.cover.style.backgroundImage = "";
|
||||||
this.$.cover.parentElement.classList.add('no-cover');
|
this.$.cover.parentElement.classList.add("no-cover");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,14 +246,14 @@ class HaMediaPlayerCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
computeBannerClasses(playerObj) {
|
computeBannerClasses(playerObj) {
|
||||||
var cls = 'banner';
|
var cls = "banner";
|
||||||
|
|
||||||
if (playerObj.isOff || playerObj.isIdle) {
|
if (playerObj.isOff || playerObj.isIdle) {
|
||||||
cls += ' is-off no-cover';
|
cls += " is-off no-cover";
|
||||||
} else if (!playerObj.stateObj.attributes.entity_picture) {
|
} else if (!playerObj.stateObj.attributes.entity_picture) {
|
||||||
cls += ' no-cover';
|
cls += " no-cover";
|
||||||
} else if (playerObj.stateObj.attributes.media_content_type === 'music') {
|
} else if (playerObj.stateObj.attributes.media_content_type === "music") {
|
||||||
cls += ' content-type-music';
|
cls += " content-type-music";
|
||||||
}
|
}
|
||||||
|
|
||||||
return cls;
|
return cls;
|
||||||
@@ -259,7 +264,9 @@ class HaMediaPlayerCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
computeHidePowerButton(playerObj) {
|
computeHidePowerButton(playerObj) {
|
||||||
return playerObj.isOff ? !playerObj.supportsTurnOn : !playerObj.supportsTurnOff;
|
return playerObj.isOff
|
||||||
|
? !playerObj.supportsTurnOn
|
||||||
|
: !playerObj.supportsTurnOff;
|
||||||
}
|
}
|
||||||
|
|
||||||
computePlayerObj(hass, stateObj) {
|
computePlayerObj(hass, stateObj) {
|
||||||
@@ -267,21 +274,29 @@ class HaMediaPlayerCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
computePrimaryText(localize, playerObj) {
|
computePrimaryText(localize, playerObj) {
|
||||||
return playerObj.primaryTitle
|
return (
|
||||||
|| localize(`state.media_player.${playerObj.stateObj.state}`)
|
playerObj.primaryTitle ||
|
||||||
|| localize(`state.default.${playerObj.stateObj.state}`) || playerObj.stateObj.state;
|
localize(`state.media_player.${playerObj.stateObj.state}`) ||
|
||||||
|
localize(`state.default.${playerObj.stateObj.state}`) ||
|
||||||
|
playerObj.stateObj.state
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
computePlaybackControlIcon(playerObj) {
|
computePlaybackControlIcon(playerObj) {
|
||||||
if (playerObj.isPlaying) {
|
if (playerObj.isPlaying) {
|
||||||
return playerObj.supportsPause ? 'hass:pause' : 'hass:stop';
|
return playerObj.supportsPause ? "hass:pause" : "hass:stop";
|
||||||
} if (playerObj.hasMediaControl || playerObj.isOff || playerObj.isIdle) {
|
|
||||||
if (playerObj.hasMediaControl && playerObj.supportsPause && !playerObj.isPaused) {
|
|
||||||
return 'hass:play-pause';
|
|
||||||
}
|
}
|
||||||
return playerObj.supportsPlay ? 'hass:play' : null;
|
if (playerObj.hasMediaControl || playerObj.isOff || playerObj.isIdle) {
|
||||||
|
if (
|
||||||
|
playerObj.hasMediaControl &&
|
||||||
|
playerObj.supportsPause &&
|
||||||
|
!playerObj.isPaused
|
||||||
|
) {
|
||||||
|
return "hass:play-pause";
|
||||||
}
|
}
|
||||||
return '';
|
return playerObj.supportsPlay ? "hass:play" : null;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
_computeStateName(stateObj) {
|
_computeStateName(stateObj) {
|
||||||
@@ -295,7 +310,7 @@ class HaMediaPlayerCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
|
|
||||||
handleOpenMoreInfo(ev) {
|
handleOpenMoreInfo(ev) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this.fire('hass-more-info', { entityId: this.stateObj.entity_id });
|
this.fire("hass-more-info", { entityId: this.stateObj.entity_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePlaybackControl(ev) {
|
handlePlaybackControl(ev) {
|
||||||
@@ -313,4 +328,4 @@ class HaMediaPlayerCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
this.playerObj.togglePower();
|
this.playerObj.togglePower();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define('ha-media_player-card', HaMediaPlayerCard);
|
customElements.define("ha-media_player-card", HaMediaPlayerCard);
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
import '@polymer/paper-button/paper-button.js';
|
import "@polymer/paper-button/paper-button.js";
|
||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/ha-card.js';
|
import "../components/ha-card.js";
|
||||||
import '../components/ha-markdown.js';
|
import "../components/ha-markdown.js";
|
||||||
|
|
||||||
|
import computeStateName from "../common/entity/compute_state_name.js";
|
||||||
import computeStateName from '../common/entity/compute_state_name.js';
|
import LocalizeMixin from "../mixins/localize-mixin.js";
|
||||||
import LocalizeMixin from '../mixins/localize-mixin.js';
|
import computeObjectId from "../common/entity/compute_object_id";
|
||||||
import computeObjectId from '../common/entity/compute_object_id';
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @appliesMixin LocalizeMixin
|
* @appliesMixin LocalizeMixin
|
||||||
@@ -60,15 +59,17 @@ class HaPersistentNotificationCard extends LocalizeMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
computeTitle(stateObj) {
|
computeTitle(stateObj) {
|
||||||
return (stateObj.attributes.title
|
return stateObj.attributes.title || computeStateName(stateObj);
|
||||||
|| computeStateName(stateObj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dismissTap(ev) {
|
dismissTap(ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
this.hass.callService('persistent_notification', 'dismiss', {
|
this.hass.callService("persistent_notification", "dismiss", {
|
||||||
notification_id: computeObjectId(this.stateObj.entity_id)
|
notification_id: computeObjectId(this.stateObj.entity_id),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define('ha-persistent_notification-card', HaPersistentNotificationCard);
|
customElements.define(
|
||||||
|
"ha-persistent_notification-card",
|
||||||
|
HaPersistentNotificationCard
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/ha-card.js';
|
import "../components/ha-card.js";
|
||||||
import '../components/ha-icon.js';
|
import "../components/ha-icon.js";
|
||||||
|
|
||||||
import computeStateName from '../common/entity/compute_state_name.js';
|
import computeStateName from "../common/entity/compute_state_name.js";
|
||||||
import EventsMixin from '../mixins/events-mixin.js';
|
import EventsMixin from "../mixins/events-mixin.js";
|
||||||
|
|
||||||
class HaPlantCard extends EventsMixin(PolymerElement) {
|
class HaPlantCard extends EventsMixin(PolymerElement) {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -85,18 +85,18 @@ class HaPlantCard extends EventsMixin(PolymerElement) {
|
|||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
hass: Object,
|
hass: Object,
|
||||||
stateObj: Object
|
stateObj: Object,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.sensors = {
|
this.sensors = {
|
||||||
moisture: 'hass:water',
|
moisture: "hass:water",
|
||||||
temperature: 'hass:thermometer',
|
temperature: "hass:thermometer",
|
||||||
brightness: 'hass:white-balance-sunny',
|
brightness: "hass:white-balance-sunny",
|
||||||
conductivity: 'hass:emoticon-poop',
|
conductivity: "hass:emoticon-poop",
|
||||||
battery: 'hass:battery'
|
battery: "hass:battery",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,16 +105,17 @@ class HaPlantCard extends EventsMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
computeAttributes(data) {
|
computeAttributes(data) {
|
||||||
return Object.keys(this.sensors).filter(key => key in data);
|
return Object.keys(this.sensors).filter((key) => key in data);
|
||||||
}
|
}
|
||||||
|
|
||||||
computeIcon(attr, batLvl) {
|
computeIcon(attr, batLvl) {
|
||||||
const icon = this.sensors[attr];
|
const icon = this.sensors[attr];
|
||||||
if (attr === 'battery') {
|
if (attr === "battery") {
|
||||||
if (batLvl <= 5) {
|
if (batLvl <= 5) {
|
||||||
return `${icon}-alert`;
|
return `${icon}-alert`;
|
||||||
} if (batLvl < 95) {
|
}
|
||||||
return `${icon}-${Math.round((batLvl / 10) - 0.01) * 10}`;
|
if (batLvl < 95) {
|
||||||
|
return `${icon}-${Math.round(batLvl / 10 - 0.01) * 10}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return icon;
|
return icon;
|
||||||
@@ -125,20 +126,22 @@ class HaPlantCard extends EventsMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
computeUom(dict, attr) {
|
computeUom(dict, attr) {
|
||||||
return dict[attr] || '';
|
return dict[attr] || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
computeAttributeClass(problem, attr) {
|
computeAttributeClass(problem, attr) {
|
||||||
return problem.indexOf(attr) === -1 ? '' : 'problem';
|
return problem.indexOf(attr) === -1 ? "" : "problem";
|
||||||
}
|
}
|
||||||
|
|
||||||
computeImageClass(entityPicture) {
|
computeImageClass(entityPicture) {
|
||||||
return entityPicture ? 'has-plant-image' : '';
|
return entityPicture ? "has-plant-image" : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
attributeClicked(ev) {
|
attributeClicked(ev) {
|
||||||
this.fire('hass-more-info', { entityId: this.stateObj.attributes.sensors[ev.model.item] });
|
this.fire("hass-more-info", {
|
||||||
|
entityId: this.stateObj.attributes.sensors[ev.model.item],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('ha-plant-card', HaPlantCard);
|
customElements.define("ha-plant-card", HaPlantCard);
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
import '../components/ha-card.js';
|
import "../components/ha-card.js";
|
||||||
import '../components/ha-icon.js';
|
import "../components/ha-icon.js";
|
||||||
|
|
||||||
import EventsMixin from '../mixins/events-mixin.js';
|
import EventsMixin from "../mixins/events-mixin.js";
|
||||||
import LocalizeMixin from '../mixins/localize-mixin.js';
|
import LocalizeMixin from "../mixins/localize-mixin.js";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @appliesMixin LocalizeMixin
|
* @appliesMixin LocalizeMixin
|
||||||
*/
|
*/
|
||||||
class HaWeatherCard extends
|
class HaWeatherCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
||||||
LocalizeMixin(EventsMixin(PolymerElement)) {
|
|
||||||
static get template() {
|
static get template() {
|
||||||
return html`
|
return html`
|
||||||
<style>
|
<style>
|
||||||
@@ -160,42 +159,57 @@ class HaWeatherCard extends
|
|||||||
stateObj: Object,
|
stateObj: Object,
|
||||||
forecast: {
|
forecast: {
|
||||||
type: Array,
|
type: Array,
|
||||||
computed: 'computeForecast(stateObj.attributes.forecast)'
|
computed: "computeForecast(stateObj.attributes.forecast)",
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.cardinalDirections = [
|
this.cardinalDirections = [
|
||||||
'N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE',
|
"N",
|
||||||
'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N'
|
"NNE",
|
||||||
|
"NE",
|
||||||
|
"ENE",
|
||||||
|
"E",
|
||||||
|
"ESE",
|
||||||
|
"SE",
|
||||||
|
"SSE",
|
||||||
|
"S",
|
||||||
|
"SSW",
|
||||||
|
"SW",
|
||||||
|
"WSW",
|
||||||
|
"W",
|
||||||
|
"WNW",
|
||||||
|
"NW",
|
||||||
|
"NNW",
|
||||||
|
"N",
|
||||||
];
|
];
|
||||||
this.weatherIcons = {
|
this.weatherIcons = {
|
||||||
'clear-night': 'hass:weather-night',
|
"clear-night": "hass:weather-night",
|
||||||
cloudy: 'hass:weather-cloudy',
|
cloudy: "hass:weather-cloudy",
|
||||||
fog: 'hass:weather-fog',
|
fog: "hass:weather-fog",
|
||||||
hail: 'hass:weather-hail',
|
hail: "hass:weather-hail",
|
||||||
lightning: 'hass:weather-lightning',
|
lightning: "hass:weather-lightning",
|
||||||
'lightning-rainy': 'hass:weather-lightning-rainy',
|
"lightning-rainy": "hass:weather-lightning-rainy",
|
||||||
partlycloudy: 'hass:weather-partlycloudy',
|
partlycloudy: "hass:weather-partlycloudy",
|
||||||
pouring: 'hass:weather-pouring',
|
pouring: "hass:weather-pouring",
|
||||||
rainy: 'hass:weather-rainy',
|
rainy: "hass:weather-rainy",
|
||||||
snowy: 'hass:weather-snowy',
|
snowy: "hass:weather-snowy",
|
||||||
'snowy-rainy': 'hass:weather-snowy-rainy',
|
"snowy-rainy": "hass:weather-snowy-rainy",
|
||||||
sunny: 'hass:weather-sunny',
|
sunny: "hass:weather-sunny",
|
||||||
windy: 'hass:weather-windy',
|
windy: "hass:weather-windy",
|
||||||
'windy-variant': 'hass:weather-windy-variant'
|
"windy-variant": "hass:weather-windy-variant",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ready() {
|
ready() {
|
||||||
this.addEventListener('click', this._onClick);
|
this.addEventListener("click", this._onClick);
|
||||||
super.ready();
|
super.ready();
|
||||||
}
|
}
|
||||||
|
|
||||||
_onClick() {
|
_onClick() {
|
||||||
this.fire('hass-more-info', { entityId: this.stateObj.entity_id });
|
this.fire("hass-more-info", { entityId: this.stateObj.entity_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
computeForecast(forecast) {
|
computeForecast(forecast) {
|
||||||
@@ -203,16 +217,16 @@ class HaWeatherCard extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
getUnit(measure) {
|
getUnit(measure) {
|
||||||
const lengthUnit = this.hass.config.unit_system.length || '';
|
const lengthUnit = this.hass.config.unit_system.length || "";
|
||||||
switch (measure) {
|
switch (measure) {
|
||||||
case 'air_pressure':
|
case "air_pressure":
|
||||||
return lengthUnit === 'km' ? 'hPa' : 'inHg';
|
return lengthUnit === "km" ? "hPa" : "inHg";
|
||||||
case 'length':
|
case "length":
|
||||||
return lengthUnit;
|
return lengthUnit;
|
||||||
case 'precipitation':
|
case "precipitation":
|
||||||
return lengthUnit === 'km' ? 'mm' : 'in';
|
return lengthUnit === "km" ? "mm" : "in";
|
||||||
default:
|
default:
|
||||||
return this.hass.config.unit_system[measure] || '';
|
return this.hass.config.unit_system[measure] || "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,20 +253,22 @@ class HaWeatherCard extends
|
|||||||
getWind(speed, bearing, localize) {
|
getWind(speed, bearing, localize) {
|
||||||
if (bearing != null) {
|
if (bearing != null) {
|
||||||
const cardinalDirection = this.windBearingToText(bearing);
|
const cardinalDirection = this.windBearingToText(bearing);
|
||||||
return `${speed} ${this.getUnit('length')}/h (${localize(`ui.card.weather.cardinal_direction.${cardinalDirection.toLowerCase()}`) || cardinalDirection})`;
|
return `${speed} ${this.getUnit("length")}/h (${localize(
|
||||||
|
`ui.card.weather.cardinal_direction.${cardinalDirection.toLowerCase()}`
|
||||||
|
) || cardinalDirection})`;
|
||||||
}
|
}
|
||||||
return `${speed} ${this.getUnit('length')}/h`;
|
return `${speed} ${this.getUnit("length")}/h`;
|
||||||
}
|
}
|
||||||
|
|
||||||
_showValue(item) {
|
_showValue(item) {
|
||||||
return typeof item !== 'undefined' && item !== null;
|
return typeof item !== "undefined" && item !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
computeDate(data) {
|
computeDate(data) {
|
||||||
const date = new Date(data);
|
const date = new Date(data);
|
||||||
return date.toLocaleDateString(
|
return date.toLocaleDateString(
|
||||||
this.hass.selectedLanguage || this.hass.language,
|
this.hass.selectedLanguage || this.hass.language,
|
||||||
{ weekday: 'short' }
|
{ weekday: "short" }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,8 +276,8 @@ class HaWeatherCard extends
|
|||||||
const date = new Date(data);
|
const date = new Date(data);
|
||||||
return date.toLocaleTimeString(
|
return date.toLocaleTimeString(
|
||||||
this.hass.selectedLanguage || this.hass.language,
|
this.hass.selectedLanguage || this.hass.language,
|
||||||
{ hour: 'numeric' }
|
{ hour: "numeric" }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define('ha-weather-card', HaWeatherCard);
|
customElements.define("ha-weather-card", HaWeatherCard);
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
/**
|
/**
|
||||||
* Auth class that connects to a native app for authentication.
|
* Auth class that connects to a native app for authentication.
|
||||||
*/
|
*/
|
||||||
import { Auth } from 'home-assistant-js-websocket';
|
import { Auth } from "home-assistant-js-websocket";
|
||||||
|
|
||||||
const CALLBACK_SET_TOKEN = 'externalAuthSetToken';
|
const CALLBACK_SET_TOKEN = "externalAuthSetToken";
|
||||||
const CALLBACK_REVOKE_TOKEN = 'externalAuthRevokeToken';
|
const CALLBACK_REVOKE_TOKEN = "externalAuthRevokeToken";
|
||||||
|
|
||||||
if (!window.externalApp && !window.webkit) {
|
if (!window.externalApp && !window.webkit) {
|
||||||
throw new Error('External auth requires either externalApp or webkit defined on Window object.');
|
throw new Error(
|
||||||
|
"External auth requires either externalApp or webkit defined on Window object."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class ExternalAuth extends Auth {
|
export default class ExternalAuth extends Auth {
|
||||||
@@ -16,7 +18,7 @@ export default class ExternalAuth extends Auth {
|
|||||||
|
|
||||||
this.data = {
|
this.data = {
|
||||||
hassUrl,
|
hassUrl,
|
||||||
access_token: '',
|
access_token: "",
|
||||||
// This will trigger connection to do a refresh right away
|
// This will trigger connection to do a refresh right away
|
||||||
expires: 0,
|
expires: 0,
|
||||||
};
|
};
|
||||||
@@ -24,7 +26,8 @@ export default class ExternalAuth extends Auth {
|
|||||||
|
|
||||||
async refreshAccessToken() {
|
async refreshAccessToken() {
|
||||||
const responseProm = new Promise((resolve, reject) => {
|
const responseProm = new Promise((resolve, reject) => {
|
||||||
window[CALLBACK_SET_TOKEN] = (success, data) => (success ? resolve(data) : reject(data));
|
window[CALLBACK_SET_TOKEN] = (success, data) =>
|
||||||
|
success ? resolve(data) : reject(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Allow promise to set resolve on window object.
|
// Allow promise to set resolve on window object.
|
||||||
@@ -35,7 +38,9 @@ export default class ExternalAuth extends Auth {
|
|||||||
if (window.externalApp) {
|
if (window.externalApp) {
|
||||||
window.externalApp.getExternalAuth(callbackPayload);
|
window.externalApp.getExternalAuth(callbackPayload);
|
||||||
} else {
|
} else {
|
||||||
window.webkit.messageHandlers.getExternalAuth.postMessage(callbackPayload);
|
window.webkit.messageHandlers.getExternalAuth.postMessage(
|
||||||
|
callbackPayload
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Response we expect back:
|
// Response we expect back:
|
||||||
@@ -46,12 +51,13 @@ export default class ExternalAuth extends Auth {
|
|||||||
const tokens = await responseProm;
|
const tokens = await responseProm;
|
||||||
|
|
||||||
this.data.access_token = tokens.access_token;
|
this.data.access_token = tokens.access_token;
|
||||||
this.data.expires = (tokens.expires_in * 1000) + Date.now();
|
this.data.expires = tokens.expires_in * 1000 + Date.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
async revoke() {
|
async revoke() {
|
||||||
const responseProm = new Promise((resolve, reject) => {
|
const responseProm = new Promise((resolve, reject) => {
|
||||||
window[CALLBACK_REVOKE_TOKEN] = (success, data) => (success ? resolve(data) : reject(data));
|
window[CALLBACK_REVOKE_TOKEN] = (success, data) =>
|
||||||
|
success ? resolve(data) : reject(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Allow promise to set resolve on window object.
|
// Allow promise to set resolve on window object.
|
||||||
@@ -62,7 +68,9 @@ export default class ExternalAuth extends Auth {
|
|||||||
if (window.externalApp) {
|
if (window.externalApp) {
|
||||||
window.externalApp.revokeExternalAuth(callbackPayload);
|
window.externalApp.revokeExternalAuth(callbackPayload);
|
||||||
} else {
|
} else {
|
||||||
window.webkit.messageHandlers.revokeExternalAuth.postMessage(callbackPayload);
|
window.webkit.messageHandlers.revokeExternalAuth.postMessage(
|
||||||
|
callbackPayload
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await responseProm;
|
await responseProm;
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ if (!tokenCache) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function askWrite() {
|
export function askWrite() {
|
||||||
return tokenCache.tokens !== undefined && tokenCache.writeEnabled === undefined;
|
return (
|
||||||
|
tokenCache.tokens !== undefined && tokenCache.writeEnabled === undefined
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function saveTokens(tokens) {
|
export function saveTokens(tokens) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/** Return if the displaymode is in standalone mode (PWA). */
|
/** Return if the displaymode is in standalone mode (PWA). */
|
||||||
export default function isPwa() {
|
export default function isPwa() {
|
||||||
return (window.matchMedia('(display-mode: standalone)').matches);
|
return window.matchMedia("(display-mode: standalone)").matches;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,84 +5,80 @@
|
|||||||
// Each constant should have a description what it is supposed to be used for.
|
// Each constant should have a description what it is supposed to be used for.
|
||||||
|
|
||||||
/** Icon to use when no icon specified for domain. */
|
/** Icon to use when no icon specified for domain. */
|
||||||
export const DEFAULT_DOMAIN_ICON = 'hass:bookmark';
|
export const DEFAULT_DOMAIN_ICON = "hass:bookmark";
|
||||||
|
|
||||||
/** Domains that have a state card. */
|
/** Domains that have a state card. */
|
||||||
export const DOMAINS_WITH_CARD = [
|
export const DOMAINS_WITH_CARD = [
|
||||||
'climate',
|
"climate",
|
||||||
'cover',
|
"cover",
|
||||||
'configurator',
|
"configurator",
|
||||||
'input_select',
|
"input_select",
|
||||||
'input_number',
|
"input_number",
|
||||||
'input_text',
|
"input_text",
|
||||||
'lock',
|
"lock",
|
||||||
'media_player',
|
"media_player",
|
||||||
'scene',
|
"scene",
|
||||||
'script',
|
"script",
|
||||||
'timer',
|
"timer",
|
||||||
'vacuum',
|
"vacuum",
|
||||||
'water_heater',
|
"water_heater",
|
||||||
'weblink',
|
"weblink",
|
||||||
];
|
];
|
||||||
|
|
||||||
/** Domains with separate more info dialog. */
|
/** Domains with separate more info dialog. */
|
||||||
export const DOMAINS_WITH_MORE_INFO = [
|
export const DOMAINS_WITH_MORE_INFO = [
|
||||||
'alarm_control_panel',
|
"alarm_control_panel",
|
||||||
'automation',
|
"automation",
|
||||||
'camera',
|
"camera",
|
||||||
'climate',
|
"climate",
|
||||||
'configurator',
|
"configurator",
|
||||||
'cover',
|
"cover",
|
||||||
'fan',
|
"fan",
|
||||||
'group',
|
"group",
|
||||||
'history_graph',
|
"history_graph",
|
||||||
'input_datetime',
|
"input_datetime",
|
||||||
'light',
|
"light",
|
||||||
'lock',
|
"lock",
|
||||||
'media_player',
|
"media_player",
|
||||||
'script',
|
"script",
|
||||||
'sun',
|
"sun",
|
||||||
'updater',
|
"updater",
|
||||||
'vacuum',
|
"vacuum",
|
||||||
'water_heater',
|
"water_heater",
|
||||||
'weather'
|
"weather",
|
||||||
];
|
];
|
||||||
|
|
||||||
/** Domains that show no more info dialog. */
|
/** Domains that show no more info dialog. */
|
||||||
export const DOMAINS_HIDE_MORE_INFO = [
|
export const DOMAINS_HIDE_MORE_INFO = [
|
||||||
'input_number',
|
"input_number",
|
||||||
'input_select',
|
"input_select",
|
||||||
'input_text',
|
"input_text",
|
||||||
'scene',
|
"scene",
|
||||||
'weblink'
|
"weblink",
|
||||||
];
|
];
|
||||||
|
|
||||||
/** Domains that should have the history hidden in the more info dialog. */
|
/** Domains that should have the history hidden in the more info dialog. */
|
||||||
export const DOMAINS_MORE_INFO_NO_HISTORY = [
|
export const DOMAINS_MORE_INFO_NO_HISTORY = [
|
||||||
'camera',
|
"camera",
|
||||||
'configurator',
|
"configurator",
|
||||||
'history_graph',
|
"history_graph",
|
||||||
'scene',
|
"scene",
|
||||||
];
|
];
|
||||||
|
|
||||||
/** States that we consider "off". */
|
/** States that we consider "off". */
|
||||||
export const STATES_OFF = [
|
export const STATES_OFF = ["closed", "locked", "off"];
|
||||||
'closed',
|
|
||||||
'locked',
|
|
||||||
'off'
|
|
||||||
];
|
|
||||||
|
|
||||||
/** Domains where we allow toggle in Lovelace. */
|
/** Domains where we allow toggle in Lovelace. */
|
||||||
export const DOMAINS_TOGGLE = new Set([
|
export const DOMAINS_TOGGLE = new Set([
|
||||||
'fan',
|
"fan",
|
||||||
'input_boolean',
|
"input_boolean",
|
||||||
'light',
|
"light",
|
||||||
'switch'
|
"switch",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/** Temperature units. */
|
/** Temperature units. */
|
||||||
export const UNIT_C = '°C';
|
export const UNIT_C = "°C";
|
||||||
export const UNIT_F = '°F';
|
export const UNIT_F = "°F";
|
||||||
|
|
||||||
/** Entity ID of the default view. */
|
/** Entity ID of the default view. */
|
||||||
export const DEFAULT_VIEW_ENTITY_ID = 'group.default_view';
|
export const DEFAULT_VIEW_ENTITY_ID = "group.default_view";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export default function durationToSeconds(duration) {
|
export default function durationToSeconds(duration) {
|
||||||
const parts = duration.split(':').map(Number);
|
const parts = duration.split(":").map(Number);
|
||||||
return (parts[0] * 3600) + (parts[1] * 60) + parts[2];
|
return parts[0] * 3600 + parts[1] * 60 + parts[2];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
import fecha from 'fecha';
|
import fecha from "fecha";
|
||||||
|
|
||||||
// Check for support of native locale string options
|
// Check for support of native locale string options
|
||||||
function toLocaleDateStringSupportsOptions() {
|
function toLocaleDateStringSupportsOptions() {
|
||||||
try {
|
try {
|
||||||
new Date().toLocaleDateString('i');
|
new Date().toLocaleDateString("i");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return e.name === 'RangeError';
|
return e.name === "RangeError";
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (toLocaleDateStringSupportsOptions()
|
export default (toLocaleDateStringSupportsOptions()
|
||||||
? function (dateObj, locales) {
|
? (dateObj, locales) =>
|
||||||
return dateObj.toLocaleDateString(
|
dateObj.toLocaleDateString(locales, {
|
||||||
locales,
|
year: "numeric",
|
||||||
{ year: 'numeric', month: 'long', day: 'numeric' },
|
month: "long",
|
||||||
);
|
day: "numeric",
|
||||||
} : function (dateObj, locales) { // eslint-disable-line no-unused-vars
|
})
|
||||||
return fecha.format(dateObj, 'mediumDate');
|
: // eslint-disable-next-line no-unused-vars
|
||||||
});
|
(dateObj, locales) => fecha.format(dateObj, "mediumDate"));
|
||||||
|
|||||||
@@ -1,24 +1,23 @@
|
|||||||
import fecha from 'fecha';
|
import fecha from "fecha";
|
||||||
|
|
||||||
// Check for support of native locale string options
|
// Check for support of native locale string options
|
||||||
function toLocaleStringSupportsOptions() {
|
function toLocaleStringSupportsOptions() {
|
||||||
try {
|
try {
|
||||||
new Date().toLocaleString('i');
|
new Date().toLocaleString("i");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return e.name === 'RangeError';
|
return e.name === "RangeError";
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (toLocaleStringSupportsOptions()
|
export default (toLocaleStringSupportsOptions()
|
||||||
? function (dateObj, locales) {
|
? (dateObj, locales) =>
|
||||||
return dateObj.toLocaleString(locales, {
|
dateObj.toLocaleString(locales, {
|
||||||
year: 'numeric',
|
year: "numeric",
|
||||||
month: 'long',
|
month: "long",
|
||||||
day: 'numeric',
|
day: "numeric",
|
||||||
hour: 'numeric',
|
hour: "numeric",
|
||||||
minute: '2-digit',
|
minute: "2-digit",
|
||||||
});
|
})
|
||||||
} : function (dateObj, locales) { // eslint-disable-line no-unused-vars
|
: // eslint-disable-next-line no-unused-vars
|
||||||
return fecha.format(dateObj, 'haDateTime');
|
(dateObj, locales) => fecha.format(dateObj, "haDateTime"));
|
||||||
});
|
|
||||||
|
|||||||
@@ -1,21 +1,20 @@
|
|||||||
import fecha from 'fecha';
|
import fecha from "fecha";
|
||||||
|
|
||||||
// Check for support of native locale string options
|
// Check for support of native locale string options
|
||||||
function toLocaleTimeStringSupportsOptions() {
|
function toLocaleTimeStringSupportsOptions() {
|
||||||
try {
|
try {
|
||||||
new Date().toLocaleTimeString('i');
|
new Date().toLocaleTimeString("i");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return e.name === 'RangeError';
|
return e.name === "RangeError";
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (toLocaleTimeStringSupportsOptions()
|
export default (toLocaleTimeStringSupportsOptions()
|
||||||
? function (dateObj, locales) {
|
? (dateObj, locales) =>
|
||||||
return dateObj.toLocaleTimeString(
|
dateObj.toLocaleTimeString(locales, {
|
||||||
locales,
|
hour: "numeric",
|
||||||
{ hour: 'numeric', minute: '2-digit' }
|
minute: "2-digit",
|
||||||
);
|
})
|
||||||
} : function (dateObj, locales) { // eslint-disable-line no-unused-vars
|
: // eslint-disable-next-line no-unused-vars
|
||||||
return fecha.format(dateObj, 'shortTime');
|
(dateObj, locales) => fecha.format(dateObj, "shortTime"));
|
||||||
});
|
|
||||||
|
|||||||
@@ -1,30 +1,33 @@
|
|||||||
/** Calculate a string representing a date object as relative time from now.
|
/** Calculate a string representing a date object as relative time from now.
|
||||||
*
|
*
|
||||||
* Example output: 5 minutes ago, in 3 days.
|
* Example output: 5 minutes ago, in 3 days.
|
||||||
*/
|
*/
|
||||||
const tests = [
|
const tests = [60, "second", 60, "minute", 24, "hour", 7, "day"];
|
||||||
60, 'second',
|
|
||||||
60, 'minute',
|
|
||||||
24, 'hour',
|
|
||||||
7, 'day',
|
|
||||||
];
|
|
||||||
|
|
||||||
export default function relativeTime(dateObj, localize) {
|
export default function relativeTime(dateObj, localize) {
|
||||||
let delta = (new Date() - dateObj) / 1000;
|
let delta = (new Date() - dateObj) / 1000;
|
||||||
const tense = delta >= 0 ? 'past' : 'future';
|
const tense = delta >= 0 ? "past" : "future";
|
||||||
delta = Math.abs(delta);
|
delta = Math.abs(delta);
|
||||||
|
|
||||||
for (let i = 0; i < tests.length; i += 2) {
|
for (let i = 0; i < tests.length; i += 2) {
|
||||||
if (delta < tests[i]) {
|
if (delta < tests[i]) {
|
||||||
delta = Math.floor(delta);
|
delta = Math.floor(delta);
|
||||||
const time = localize(`ui.components.relative_time.duration.${tests[i + 1]}`, 'count', delta);
|
const time = localize(
|
||||||
return localize(`ui.components.relative_time.${tense}`, 'time', time);
|
`ui.components.relative_time.duration.${tests[i + 1]}`,
|
||||||
|
"count",
|
||||||
|
delta
|
||||||
|
);
|
||||||
|
return localize(`ui.components.relative_time.${tense}`, "time", time);
|
||||||
}
|
}
|
||||||
|
|
||||||
delta /= tests[i];
|
delta /= tests[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
delta = Math.floor(delta);
|
delta = Math.floor(delta);
|
||||||
const time = localize('ui.components.relative_time.duration.week', 'count', delta);
|
const time = localize(
|
||||||
return localize(`ui.components.relative_time.${tense}`, 'time', time);
|
"ui.components.relative_time.duration.week",
|
||||||
|
"count",
|
||||||
|
delta
|
||||||
|
);
|
||||||
|
return localize(`ui.components.relative_time.${tense}`, "time", time);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
const leftPad = number => (number < 10 ? `0${number}` : number);
|
const leftPad = (number) => (number < 10 ? `0${number}` : number);
|
||||||
|
|
||||||
export default function secondsToDuration(d) {
|
export default function secondsToDuration(d) {
|
||||||
const h = Math.floor(d / 3600);
|
const h = Math.floor(d / 3600);
|
||||||
const m = Math.floor((d % 3600) / 60);
|
const m = Math.floor((d % 3600) / 60);
|
||||||
const s = Math.floor(d % 3600 % 60);
|
const s = Math.floor((d % 3600) % 60);
|
||||||
|
|
||||||
if (h > 0) {
|
if (h > 0) {
|
||||||
return `${h}:${leftPad(m)}:${leftPad(s)}`;
|
return `${h}:${leftPad(m)}:${leftPad(s)}`;
|
||||||
} if (m > 0) {
|
}
|
||||||
|
if (m > 0) {
|
||||||
return `${m}:${leftPad(s)}`;
|
return `${m}:${leftPad(s)}`;
|
||||||
} if (s > 0) {
|
}
|
||||||
return '' + s;
|
if (s > 0) {
|
||||||
|
return "" + s;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,21 +5,26 @@
|
|||||||
* themes: HASS Theme information
|
* themes: HASS Theme information
|
||||||
* localTheme: selected theme.
|
* localTheme: selected theme.
|
||||||
* updateMeta: boolean if we should update the theme-color meta element.
|
* updateMeta: boolean if we should update the theme-color meta element.
|
||||||
*/
|
*/
|
||||||
export default function applyThemesOnElement(element, themes, localTheme, updateMeta = false) {
|
export default function applyThemesOnElement(
|
||||||
|
element,
|
||||||
|
themes,
|
||||||
|
localTheme,
|
||||||
|
updateMeta = false
|
||||||
|
) {
|
||||||
if (!element._themes) {
|
if (!element._themes) {
|
||||||
element._themes = {};
|
element._themes = {};
|
||||||
}
|
}
|
||||||
let themeName = themes.default_theme;
|
let themeName = themes.default_theme;
|
||||||
if (localTheme === 'default' || (localTheme && themes.themes[localTheme])) {
|
if (localTheme === "default" || (localTheme && themes.themes[localTheme])) {
|
||||||
themeName = localTheme;
|
themeName = localTheme;
|
||||||
}
|
}
|
||||||
const styles = Object.assign({}, element._themes);
|
const styles = Object.assign({}, element._themes);
|
||||||
if (themeName !== 'default') {
|
if (themeName !== "default") {
|
||||||
var theme = themes.themes[themeName];
|
var theme = themes.themes[themeName];
|
||||||
Object.keys(theme).forEach((key) => {
|
Object.keys(theme).forEach((key) => {
|
||||||
var prefixedKey = '--' + key;
|
var prefixedKey = "--" + key;
|
||||||
element._themes[prefixedKey] = '';
|
element._themes[prefixedKey] = "";
|
||||||
styles[prefixedKey] = theme[key];
|
styles[prefixedKey] = theme[key];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -27,17 +32,18 @@ export default function applyThemesOnElement(element, themes, localTheme, update
|
|||||||
element.updateStyles(styles);
|
element.updateStyles(styles);
|
||||||
} else if (window.ShadyCSS) {
|
} else if (window.ShadyCSS) {
|
||||||
// implement updateStyles() method of Polemer elements
|
// implement updateStyles() method of Polemer elements
|
||||||
window.ShadyCSS.styleSubtree(/** @type {!HTMLElement} */(element), styles);
|
window.ShadyCSS.styleSubtree(/** @type {!HTMLElement} */ (element), styles);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!updateMeta) return;
|
if (!updateMeta) return;
|
||||||
|
|
||||||
const meta = document.querySelector('meta[name=theme-color]');
|
const meta = document.querySelector("meta[name=theme-color]");
|
||||||
if (meta) {
|
if (meta) {
|
||||||
if (!meta.hasAttribute('default-content')) {
|
if (!meta.hasAttribute("default-content")) {
|
||||||
meta.setAttribute('default-content', meta.getAttribute('content'));
|
meta.setAttribute("default-content", meta.getAttribute("content"));
|
||||||
}
|
}
|
||||||
const themeColor = styles['--primary-color'] || meta.getAttribute('default-content');
|
const themeColor =
|
||||||
meta.setAttribute('content', themeColor);
|
styles["--primary-color"] || meta.getAttribute("default-content");
|
||||||
|
meta.setAttribute("content", themeColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,11 +45,11 @@
|
|||||||
*/
|
*/
|
||||||
export default function fire(node, type, detail, options) {
|
export default function fire(node, type, detail, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
detail = (detail === null || detail === undefined) ? {} : detail;
|
detail = detail === null || detail === undefined ? {} : detail;
|
||||||
const event = new Event(type, {
|
const event = new Event(type, {
|
||||||
bubbles: options.bubbles === undefined ? true : options.bubbles,
|
bubbles: options.bubbles === undefined ? true : options.bubbles,
|
||||||
cancelable: Boolean(options.cancelable),
|
cancelable: Boolean(options.cancelable),
|
||||||
composed: options.composed === undefined ? true : options.composed
|
composed: options.composed === undefined ? true : options.composed,
|
||||||
});
|
});
|
||||||
event.detail = detail;
|
event.detail = detail;
|
||||||
node.dispatchEvent(event);
|
node.dispatchEvent(event);
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
|
|
||||||
function _load(tag, url, type) {
|
function _load(tag, url, type) {
|
||||||
// This promise will be used by Promise.all to determine success or failure
|
// This promise will be used by Promise.all to determine success or failure
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
const element = document.createElement(tag);
|
const element = document.createElement(tag);
|
||||||
let attr = 'src';
|
let attr = "src";
|
||||||
let parent = 'body';
|
let parent = "body";
|
||||||
|
|
||||||
// Important success and error for the promise
|
// Important success and error for the promise
|
||||||
element.onload = () => resolve(url);
|
element.onload = () => resolve(url);
|
||||||
@@ -14,17 +14,17 @@ function _load(tag, url, type) {
|
|||||||
|
|
||||||
// Need to set different attributes depending on tag type
|
// Need to set different attributes depending on tag type
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case 'script':
|
case "script":
|
||||||
element.async = true;
|
element.async = true;
|
||||||
if (type) {
|
if (type) {
|
||||||
element.type = type;
|
element.type = type;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'link':
|
case "link":
|
||||||
element.type = 'text/css';
|
element.type = "text/css";
|
||||||
element.rel = 'stylesheet';
|
element.rel = "stylesheet";
|
||||||
attr = 'href';
|
attr = "href";
|
||||||
parent = 'head';
|
parent = "head";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inject into document to kick off loading
|
// Inject into document to kick off loading
|
||||||
@@ -33,7 +33,7 @@ function _load(tag, url, type) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const loadCSS = url => _load('link', url);
|
export const loadCSS = (url) => _load("link", url);
|
||||||
export const loadJS = url => _load('script', url);
|
export const loadJS = (url) => _load("script", url);
|
||||||
export const loadImg = url => _load('img', url);
|
export const loadImg = (url) => _load("img", url);
|
||||||
export const loadModule = url => _load('script', url, 'module');
|
export const loadModule = (url) => _load("script", url, "module");
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export default function scrollToTarget(element, target) {
|
|||||||
var easingFn = function easeOutQuad(t, b, c, d) {
|
var easingFn = function easeOutQuad(t, b, c, d) {
|
||||||
/* eslint-disable no-param-reassign, space-infix-ops, no-mixed-operators */
|
/* eslint-disable no-param-reassign, space-infix-ops, no-mixed-operators */
|
||||||
t /= d;
|
t /= d;
|
||||||
return -c * t*(t-2) + b;
|
return -c * t * (t - 2) + b;
|
||||||
/* eslint-enable no-param-reassign, space-infix-ops, no-mixed-operators */
|
/* eslint-enable no-param-reassign, space-infix-ops, no-mixed-operators */
|
||||||
};
|
};
|
||||||
var animationId = Math.random();
|
var animationId = Math.random();
|
||||||
@@ -31,8 +31,13 @@ export default function scrollToTarget(element, target) {
|
|||||||
if (elapsedTime > duration) {
|
if (elapsedTime > duration) {
|
||||||
scroller.scrollTop = top;
|
scroller.scrollTop = top;
|
||||||
} else if (element._currentAnimationId === animationId) {
|
} else if (element._currentAnimationId === animationId) {
|
||||||
scroller.scrollTop = easingFn(elapsedTime, currentScrollTop, deltaScrollTop, duration);
|
scroller.scrollTop = easingFn(
|
||||||
|
elapsedTime,
|
||||||
|
currentScrollTop,
|
||||||
|
deltaScrollTop,
|
||||||
|
duration
|
||||||
|
);
|
||||||
requestAnimationFrame(updateFrame.bind(element));
|
requestAnimationFrame(updateFrame.bind(element));
|
||||||
}
|
}
|
||||||
}).call(element);
|
}.call(element));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,21 @@
|
|||||||
import Leaflet from 'leaflet';
|
import Leaflet from "leaflet";
|
||||||
|
|
||||||
// Sets up a Leaflet map on the provided DOM element
|
// Sets up a Leaflet map on the provided DOM element
|
||||||
export default function setupLeafletMap(mapElement) {
|
export default function setupLeafletMap(mapElement) {
|
||||||
const map = Leaflet.map(mapElement);
|
const map = Leaflet.map(mapElement);
|
||||||
const style = document.createElement('link');
|
const style = document.createElement("link");
|
||||||
style.setAttribute('href', '/static/images/leaflet/leaflet.css');
|
style.setAttribute("href", "/static/images/leaflet/leaflet.css");
|
||||||
style.setAttribute('rel', 'stylesheet');
|
style.setAttribute("rel", "stylesheet");
|
||||||
mapElement.parentNode.appendChild(style);
|
mapElement.parentNode.appendChild(style);
|
||||||
map.setView([51.505, -0.09], 13);
|
map.setView([51.505, -0.09], 13);
|
||||||
Leaflet.tileLayer(
|
Leaflet.tileLayer(
|
||||||
`https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}${Leaflet.Browser.retina ? '@2x.png' : '.png'}`,
|
`https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}${
|
||||||
|
Leaflet.Browser.retina ? "@2x.png" : ".png"
|
||||||
|
}`,
|
||||||
{
|
{
|
||||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>, © <a href="https://carto.com/attributions">CARTO</a>',
|
attribution:
|
||||||
subdomains: 'abcd',
|
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>, © <a href="https://carto.com/attributions">CARTO</a>',
|
||||||
|
subdomains: "abcd",
|
||||||
minZoom: 0,
|
minZoom: 0,
|
||||||
maxZoom: 20,
|
maxZoom: 20,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
/** An empty image which can be set as src of an img element. */
|
/** An empty image which can be set as src of an img element. */
|
||||||
export default 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
|
export default "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
export default function attributeClassNames(stateObj, attributes) {
|
export default function attributeClassNames(stateObj, attributes) {
|
||||||
if (!stateObj) return '';
|
if (!stateObj) return "";
|
||||||
return attributes.map(function (attribute) {
|
return attributes
|
||||||
return attribute in stateObj.attributes ? 'has-' + attribute : '';
|
.map(function(attribute) {
|
||||||
}).filter(attr => attr !== '').join(' ');
|
return attribute in stateObj.attributes ? "has-" + attribute : "";
|
||||||
|
})
|
||||||
|
.filter((attr) => attr !== "")
|
||||||
|
.join(" ");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +1,49 @@
|
|||||||
/** Return an icon representing a binary sensor state. */
|
/** Return an icon representing a binary sensor state. */
|
||||||
|
|
||||||
export default function binarySensorIcon(state) {
|
export default function binarySensorIcon(state) {
|
||||||
var activated = state.state && state.state === 'off';
|
var activated = state.state && state.state === "off";
|
||||||
switch (state.attributes.device_class) {
|
switch (state.attributes.device_class) {
|
||||||
case 'battery':
|
case "battery":
|
||||||
return activated ? 'hass:battery' : 'hass:battery-outline';
|
return activated ? "hass:battery" : "hass:battery-outline";
|
||||||
case 'cold':
|
case "cold":
|
||||||
return activated ? 'hass:thermometer' : 'hass:snowflake';
|
return activated ? "hass:thermometer" : "hass:snowflake";
|
||||||
case 'connectivity':
|
case "connectivity":
|
||||||
return activated ? 'hass:server-network-off' : 'hass:server-network';
|
return activated ? "hass:server-network-off" : "hass:server-network";
|
||||||
case 'door':
|
case "door":
|
||||||
return activated ? 'hass:door-closed' : 'hass:door-open';
|
return activated ? "hass:door-closed" : "hass:door-open";
|
||||||
case 'garage_door':
|
case "garage_door":
|
||||||
return activated ? 'hass:garage' : 'hass:garage-open';
|
return activated ? "hass:garage" : "hass:garage-open";
|
||||||
case 'gas':
|
case "gas":
|
||||||
case 'power':
|
case "power":
|
||||||
case 'problem':
|
case "problem":
|
||||||
case 'safety':
|
case "safety":
|
||||||
case 'smoke':
|
case "smoke":
|
||||||
return activated ? 'hass:verified' : 'hass:alert';
|
return activated ? "hass:verified" : "hass:alert";
|
||||||
case 'heat':
|
case "heat":
|
||||||
return activated ? 'hass:thermometer' : 'hass:fire';
|
return activated ? "hass:thermometer" : "hass:fire";
|
||||||
case 'light':
|
case "light":
|
||||||
return activated ? 'hass:brightness-5' : 'hass:brightness-7';
|
return activated ? "hass:brightness-5" : "hass:brightness-7";
|
||||||
case 'lock':
|
case "lock":
|
||||||
return activated ? 'hass:lock' : 'hass:lock-open';
|
return activated ? "hass:lock" : "hass:lock-open";
|
||||||
case 'moisture':
|
case "moisture":
|
||||||
return activated ? 'hass:water-off' : 'hass:water';
|
return activated ? "hass:water-off" : "hass:water";
|
||||||
case 'motion':
|
case "motion":
|
||||||
return activated ? 'hass:walk' : 'hass:run';
|
return activated ? "hass:walk" : "hass:run";
|
||||||
case 'occupancy':
|
case "occupancy":
|
||||||
return activated ? 'hass:home-outline' : 'hass:home';
|
return activated ? "hass:home-outline" : "hass:home";
|
||||||
case 'opening':
|
case "opening":
|
||||||
return activated ? 'hass:square' : 'hass:square-outline';
|
return activated ? "hass:square" : "hass:square-outline";
|
||||||
case 'plug':
|
case "plug":
|
||||||
return activated ? 'hass:power-plug-off' : 'hass:power-plug';
|
return activated ? "hass:power-plug-off" : "hass:power-plug";
|
||||||
case 'presence':
|
case "presence":
|
||||||
return activated ? 'hass:home-outline' : 'hass:home';
|
return activated ? "hass:home-outline" : "hass:home";
|
||||||
case 'sound':
|
case "sound":
|
||||||
return activated ? 'hass:music-note-off' : 'hass:music-note';
|
return activated ? "hass:music-note-off" : "hass:music-note";
|
||||||
case 'vibration':
|
case "vibration":
|
||||||
return activated ? 'hass:crop-portrait' : 'hass:vibrate';
|
return activated ? "hass:crop-portrait" : "hass:vibrate";
|
||||||
case 'window':
|
case "window":
|
||||||
return activated ? 'hass:window-closed' : 'hass:window-open';
|
return activated ? "hass:window-closed" : "hass:window-open";
|
||||||
default:
|
default:
|
||||||
return activated ? 'hass:radiobox-blank' : 'hass:checkbox-marked-circle';
|
return activated ? "hass:radiobox-blank" : "hass:checkbox-marked-circle";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
export default function canToggleDomain(hass, domain) {
|
export default function canToggleDomain(hass, domain) {
|
||||||
const services = hass.services[domain];
|
const services = hass.services[domain];
|
||||||
if (!services) { return false; }
|
if (!services) {
|
||||||
|
return false;
|
||||||
if (domain === 'lock') {
|
|
||||||
return 'lock' in services;
|
|
||||||
} if (domain === 'cover') {
|
|
||||||
return 'open_cover' in services;
|
|
||||||
}
|
}
|
||||||
return 'turn_on' in services;
|
|
||||||
|
if (domain === "lock") {
|
||||||
|
return "lock" in services;
|
||||||
|
}
|
||||||
|
if (domain === "cover") {
|
||||||
|
return "open_cover" in services;
|
||||||
|
}
|
||||||
|
return "turn_on" in services;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import canToggleDomain from './can_toggle_domain.js';
|
import canToggleDomain from "./can_toggle_domain.js";
|
||||||
import computeStateDomain from './compute_state_domain.js';
|
import computeStateDomain from "./compute_state_domain.js";
|
||||||
|
|
||||||
export default function canToggleState(hass, stateObj) {
|
export default function canToggleState(hass, stateObj) {
|
||||||
const domain = computeStateDomain(stateObj);
|
const domain = computeStateDomain(stateObj);
|
||||||
if (domain === 'group') {
|
if (domain === "group") {
|
||||||
return stateObj.state === 'on' || stateObj.state === 'off';
|
return stateObj.state === "on" || stateObj.state === "off";
|
||||||
}
|
}
|
||||||
if (domain === 'climate') {
|
if (domain === "climate") {
|
||||||
return !!((stateObj.attributes || {}).supported_features & 4096);
|
return !!((stateObj.attributes || {}).supported_features & 4096);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
export default function computeDomain(entityId) {
|
export default function computeDomain(entityId) {
|
||||||
return entityId.substr(0, entityId.indexOf('.'));
|
return entityId.substr(0, entityId.indexOf("."));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/** Compute the object ID of a state. */
|
/** Compute the object ID of a state. */
|
||||||
export default function computeObjectId(entityId) {
|
export default function computeObjectId(entityId) {
|
||||||
return entityId.substr(entityId.indexOf('.') + 1);
|
return entityId.substr(entityId.indexOf(".") + 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,32 @@
|
|||||||
import computeStateDomain from './compute_state_domain.js';
|
import computeStateDomain from "./compute_state_domain.js";
|
||||||
import formatDateTime from '../datetime/format_date_time.js';
|
import formatDateTime from "../datetime/format_date_time.js";
|
||||||
import formatDate from '../datetime/format_date.js';
|
import formatDate from "../datetime/format_date.js";
|
||||||
import formatTime from '../datetime/format_time.js';
|
import formatTime from "../datetime/format_time.js";
|
||||||
|
|
||||||
export default function computeStateDisplay(localize, stateObj, language) {
|
export default function computeStateDisplay(localize, stateObj, language) {
|
||||||
if (!stateObj._stateDisplay) {
|
if (!stateObj._stateDisplay) {
|
||||||
const domain = computeStateDomain(stateObj);
|
const domain = computeStateDomain(stateObj);
|
||||||
if (domain === 'binary_sensor') {
|
if (domain === "binary_sensor") {
|
||||||
// Try device class translation, then default binary sensor translation
|
// Try device class translation, then default binary sensor translation
|
||||||
if (stateObj.attributes.device_class) {
|
if (stateObj.attributes.device_class) {
|
||||||
stateObj._stateDisplay = localize(`state.${domain}.${stateObj.attributes.device_class}.${stateObj.state}`);
|
stateObj._stateDisplay = localize(
|
||||||
|
`state.${domain}.${stateObj.attributes.device_class}.${
|
||||||
|
stateObj.state
|
||||||
|
}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (!stateObj._stateDisplay) {
|
if (!stateObj._stateDisplay) {
|
||||||
stateObj._stateDisplay = localize(`state.${domain}.default.${stateObj.state}`);
|
stateObj._stateDisplay = localize(
|
||||||
|
`state.${domain}.default.${stateObj.state}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else if (stateObj.attributes.unit_of_measurement && !['unknown', 'unavailable'].includes(stateObj.state)) {
|
} else if (
|
||||||
stateObj._stateDisplay = stateObj.state + ' ' + stateObj.attributes.unit_of_measurement;
|
stateObj.attributes.unit_of_measurement &&
|
||||||
} else if (domain === 'input_datetime') {
|
!["unknown", "unavailable"].includes(stateObj.state)
|
||||||
|
) {
|
||||||
|
stateObj._stateDisplay =
|
||||||
|
stateObj.state + " " + stateObj.attributes.unit_of_measurement;
|
||||||
|
} else if (domain === "input_datetime") {
|
||||||
let date;
|
let date;
|
||||||
if (!stateObj.attributes.has_time) {
|
if (!stateObj.attributes.has_time) {
|
||||||
date = new Date(
|
date = new Date(
|
||||||
@@ -30,33 +40,44 @@ export default function computeStateDisplay(localize, stateObj, language) {
|
|||||||
date = new Date(
|
date = new Date(
|
||||||
// Due to bugs.chromium.org/p/chromium/issues/detail?id=797548
|
// Due to bugs.chromium.org/p/chromium/issues/detail?id=797548
|
||||||
// don't use artificial 1970 year.
|
// don't use artificial 1970 year.
|
||||||
now.getFullYear(), now.getMonth(), now.getDay(),
|
now.getFullYear(),
|
||||||
|
now.getMonth(),
|
||||||
|
now.getDay(),
|
||||||
stateObj.attributes.hour,
|
stateObj.attributes.hour,
|
||||||
stateObj.attributes.minute
|
stateObj.attributes.minute
|
||||||
);
|
);
|
||||||
stateObj._stateDisplay = formatTime(date, language);
|
stateObj._stateDisplay = formatTime(date, language);
|
||||||
} else {
|
} else {
|
||||||
date = new Date(
|
date = new Date(
|
||||||
stateObj.attributes.year, stateObj.attributes.month - 1,
|
stateObj.attributes.year,
|
||||||
stateObj.attributes.day, stateObj.attributes.hour,
|
stateObj.attributes.month - 1,
|
||||||
|
stateObj.attributes.day,
|
||||||
|
stateObj.attributes.hour,
|
||||||
stateObj.attributes.minute
|
stateObj.attributes.minute
|
||||||
);
|
);
|
||||||
stateObj._stateDisplay = formatDateTime(date, language);
|
stateObj._stateDisplay = formatDateTime(date, language);
|
||||||
}
|
}
|
||||||
} else if (domain === 'zwave') {
|
} else if (domain === "zwave") {
|
||||||
if (['initializing', 'dead'].includes(stateObj.state)) {
|
if (["initializing", "dead"].includes(stateObj.state)) {
|
||||||
stateObj._stateDisplay = localize(`state.zwave.query_stage.${stateObj.state}`, 'query_stage', stateObj.attributes.query_stage);
|
stateObj._stateDisplay = localize(
|
||||||
|
`state.zwave.query_stage.${stateObj.state}`,
|
||||||
|
"query_stage",
|
||||||
|
stateObj.attributes.query_stage
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
stateObj._stateDisplay = localize(`state.zwave.default.${stateObj.state}`);
|
stateObj._stateDisplay = localize(
|
||||||
|
`state.zwave.default.${stateObj.state}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
stateObj._stateDisplay = localize(`state.${domain}.${stateObj.state}`);
|
stateObj._stateDisplay = localize(`state.${domain}.${stateObj.state}`);
|
||||||
}
|
}
|
||||||
// Fall back to default, component backend translation, or raw state if nothing else matches.
|
// Fall back to default, component backend translation, or raw state if nothing else matches.
|
||||||
stateObj._stateDisplay = stateObj._stateDisplay
|
stateObj._stateDisplay =
|
||||||
|| localize(`state.default.${stateObj.state}`)
|
stateObj._stateDisplay ||
|
||||||
|| localize(`component.${domain}.state.${stateObj.state}`)
|
localize(`state.default.${stateObj.state}`) ||
|
||||||
|| stateObj.state;
|
localize(`component.${domain}.state.${stateObj.state}`) ||
|
||||||
|
stateObj.state;
|
||||||
}
|
}
|
||||||
|
|
||||||
return stateObj._stateDisplay;
|
return stateObj._stateDisplay;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import computeDomain from './compute_domain.js';
|
import computeDomain from "./compute_domain.js";
|
||||||
|
|
||||||
export default function computeStateDomain(stateObj) {
|
export default function computeStateDomain(stateObj) {
|
||||||
return computeDomain(stateObj.entity_id);
|
return computeDomain(stateObj.entity_id);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import computeObjectId from './compute_object_id';
|
import computeObjectId from "./compute_object_id";
|
||||||
|
|
||||||
export default function computeStateName(stateObj) {
|
export default function computeStateName(stateObj) {
|
||||||
if (stateObj._entityDisplay === undefined) {
|
if (stateObj._entityDisplay === undefined) {
|
||||||
stateObj._entityDisplay = (
|
stateObj._entityDisplay =
|
||||||
stateObj.attributes.friendly_name
|
stateObj.attributes.friendly_name ||
|
||||||
|| computeObjectId(stateObj.entity_id).replace(/_/g, ' '));
|
computeObjectId(stateObj.entity_id).replace(/_/g, " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
return stateObj._entityDisplay;
|
return stateObj._entityDisplay;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
/** Return an icon representing a cover state. */
|
/** Return an icon representing a cover state. */
|
||||||
import domainIcon from './domain_icon.js';
|
import domainIcon from "./domain_icon.js";
|
||||||
|
|
||||||
export default function coverIcon(state) {
|
export default function coverIcon(state) {
|
||||||
var open = state.state && state.state !== 'closed';
|
var open = state.state && state.state !== "closed";
|
||||||
switch (state.attributes.device_class) {
|
switch (state.attributes.device_class) {
|
||||||
case 'garage':
|
case "garage":
|
||||||
return open ? 'hass:garage-open' : 'hass:garage';
|
return open ? "hass:garage-open" : "hass:garage";
|
||||||
default:
|
default:
|
||||||
return domainIcon('cover', state.state);
|
return domainIcon("cover", state.state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user