mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-19 14:19:30 +00:00
Compare commits
25 Commits
fix-number
...
Better-row
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d3765987c4 | ||
![]() |
259cb6a2d2 | ||
![]() |
68c3825c7b | ||
![]() |
2e3c3ded96 | ||
![]() |
b6a93b439e | ||
![]() |
ea4a5e4f1d | ||
![]() |
de71c348a5 | ||
![]() |
b27fe7e703 | ||
![]() |
06db9c4bee | ||
![]() |
ae5018b501 | ||
![]() |
9ef3d02636 | ||
![]() |
9f2723deb8 | ||
![]() |
e9845e1009 | ||
![]() |
40d8a76b4d | ||
![]() |
7a282ede59 | ||
![]() |
48455c767f | ||
![]() |
4385dd5c44 | ||
![]() |
7733a5f831 | ||
![]() |
b6c9676930 | ||
![]() |
3692e36f12 | ||
![]() |
30e5fdb6e5 | ||
![]() |
99f4afec8d | ||
![]() |
5ae6c05fe6 | ||
![]() |
effd5e4982 | ||
![]() |
5592ea80a9 |
@@ -26,9 +26,6 @@
|
|||||||
"[typescript]": {
|
"[typescript]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
},
|
},
|
||||||
"[javascript]": {
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
||||||
},
|
|
||||||
"files.trimTrailingWhitespace": true
|
"files.trimTrailingWhitespace": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
.github/ISSUE_TEMPLATE/BUG_REPORT.md
vendored
10
.github/ISSUE_TEMPLATE/BUG_REPORT.md
vendored
@@ -74,12 +74,12 @@ DO NOT DELETE ANY TEXT from this template! Otherwise, your issue may be closed w
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Problem-relevant frontend configuration
|
## Problem-relevant configuration
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
An example configuration that caused the problem for you, e.g. the YAML configuration
|
An example configuration that caused the problem for you. Fill this out even
|
||||||
of the used cards. Fill this out even if it seems unimportant to you. Please be sure
|
if it seems unimportant to you. Please be sure to remove personal information
|
||||||
to remove personal information like passwords, private URLs and other credentials.
|
like passwords, private URLs and other credentials.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@@ -89,7 +89,7 @@ DO NOT DELETE ANY TEXT from this template! Otherwise, your issue may be closed w
|
|||||||
## Javascript errors shown in your browser console/inspector
|
## Javascript errors shown in your browser console/inspector
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
If you come across any Javascript or other error logs, e.g. in your browser
|
If you come across any javascript or other error logs, e.g., in your browser
|
||||||
console/inspector please provide them.
|
console/inspector please provide them.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
19
.github/workflows/netflify.yml
vendored
19
.github/workflows/netflify.yml
vendored
@@ -1,19 +0,0 @@
|
|||||||
name: Netlify
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 0 * * *"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
trigger_builds:
|
|
||||||
name: Trigger netlify build preview
|
|
||||||
runs-on: "ubuntu-latest"
|
|
||||||
steps:
|
|
||||||
- name: Trigger Cast build
|
|
||||||
run: curl -X POST -d {} https://api.netlify.com/build_hooks/${{ secrets.NETLIFY_CAST_DEV_BUILD_HOOK }}
|
|
||||||
|
|
||||||
- name: Trigger Demo build
|
|
||||||
run: curl -X POST -d {} https://api.netlify.com/build_hooks/${{ secrets.NETLIFY_DEMO_DEV_BUILD_HOOK }}
|
|
||||||
|
|
||||||
- name: Trigger Gallery build
|
|
||||||
run: curl -X POST -d {} https://api.netlify.com/build_hooks/${{ secrets.NETLIFY_GALLERY_DEV_BUILD_HOOK }}
|
|
81
.github/workflows/release.yaml
vendored
81
.github/workflows/release.yaml
vendored
@@ -1,81 +0,0 @@
|
|||||||
name: Release
|
|
||||||
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types:
|
|
||||||
- published
|
|
||||||
|
|
||||||
env:
|
|
||||||
WHEELS_TAG: 3.7-alpine3.11
|
|
||||||
PYTHON_VERSION: 3.7
|
|
||||||
NODE_VERSION: 12.1
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
release:
|
|
||||||
name: Release
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout the repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Verify version
|
|
||||||
uses: home-assistant/actions/helpers/verify-version@master
|
|
||||||
|
|
||||||
- name: Set up Python ${{ env.PYTHON_VERSION }}
|
|
||||||
uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: ${{ env.PYTHON_VERSION }}
|
|
||||||
|
|
||||||
- name: Set up Node ${{ env.NODE_VERSION }}
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: ${{ env.NODE_VERSION }}
|
|
||||||
|
|
||||||
- name: Build and release package
|
|
||||||
run: |
|
|
||||||
python3 -m pip install twine
|
|
||||||
export TWINE_USERNAME="__token__"
|
|
||||||
export TWINE_PASSWORD="${{ secrets.TWINE_TOKEN }}"
|
|
||||||
|
|
||||||
script/release
|
|
||||||
|
|
||||||
wheels-init:
|
|
||||||
name: Init wheels build
|
|
||||||
needs: release
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Generate requirements.txt
|
|
||||||
run: |
|
|
||||||
# Sleep to give pypi time to populate the new version across mirrors
|
|
||||||
sleep 240
|
|
||||||
version=$(echo "${{ github.ref }}" | awk -F"/" '{print $NF}' )
|
|
||||||
echo "home-assistant-frontend==$version" > ./requirements.txt
|
|
||||||
|
|
||||||
- name: Upload requirements.txt
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: requirements
|
|
||||||
path: ./requirements.txt
|
|
||||||
|
|
||||||
build-wheels:
|
|
||||||
name: Build wheels for ${{ matrix.arch }}
|
|
||||||
needs: wheels-init
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
arch: ["aarch64", "armhf", "armv7", "amd64", "i386"]
|
|
||||||
steps:
|
|
||||||
- name: Download requirements.txt
|
|
||||||
uses: actions/download-artifact@v2
|
|
||||||
with:
|
|
||||||
name: requirements
|
|
||||||
|
|
||||||
- name: Build wheels
|
|
||||||
uses: home-assistant/wheels@master
|
|
||||||
with:
|
|
||||||
tag: ${{ env.WHEELS_TAG }}
|
|
||||||
arch: ${{ matrix.arch }}
|
|
||||||
wheels-host: ${{ secrets.WHEELS_HOST }}
|
|
||||||
wheels-key: ${{ secrets.WHEELS_KEY }}
|
|
||||||
wheels-user: wheels
|
|
||||||
requirements: "requirements.txt"
|
|
65
.github/workflows/translations.yaml
vendored
65
.github/workflows/translations.yaml
vendored
@@ -1,65 +0,0 @@
|
|||||||
name: Translations
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "30 0 * * *"
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- dev
|
|
||||||
paths:
|
|
||||||
- translations/en.json
|
|
||||||
|
|
||||||
env:
|
|
||||||
NODE_VERSION: 12
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
upload:
|
|
||||||
name: Upload
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout the repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Set up Node ${{ env.NODE_VERSION }}
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: ${{ env.NODE_VERSION }}
|
|
||||||
|
|
||||||
- name: Upload Translations
|
|
||||||
run: |
|
|
||||||
export LOKALISE_TOKEN="${{ secrets.LOKALISE_TOKEN }}"
|
|
||||||
|
|
||||||
./script/translations_upload_base
|
|
||||||
|
|
||||||
download:
|
|
||||||
name: Download
|
|
||||||
needs: upload
|
|
||||||
if: github.event_name == 'schedule'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout the repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Set up Node ${{ env.NODE_VERSION }}
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: ${{ env.NODE_VERSION }}
|
|
||||||
|
|
||||||
- name: Download Translations
|
|
||||||
run: |
|
|
||||||
export LOKALISE_TOKEN="${{ secrets.LOKALISE_TOKEN }}"
|
|
||||||
|
|
||||||
npm install
|
|
||||||
./script/translations_download
|
|
||||||
|
|
||||||
- name: Initialize git
|
|
||||||
uses: home-assistant/actions/helpers/git-init@master
|
|
||||||
with:
|
|
||||||
name: GitHub Action
|
|
||||||
email: github-action@users.noreply.github.com
|
|
||||||
|
|
||||||
- name: Update translation
|
|
||||||
run: |
|
|
||||||
git add translations
|
|
||||||
git commit -am "Translation update"
|
|
||||||
git push
|
|
@@ -14,7 +14,7 @@ This is the repository for the official [Home Assistant](https://home-assistant.
|
|||||||
- Development: [Instructions](https://developers.home-assistant.io/docs/frontend/development/)
|
- Development: [Instructions](https://developers.home-assistant.io/docs/frontend/development/)
|
||||||
- Production build: `script/build_frontend`
|
- Production build: `script/build_frontend`
|
||||||
- Gallery: `cd gallery && script/develop_gallery`
|
- Gallery: `cd gallery && script/develop_gallery`
|
||||||
- Supervisor: [Instructions](https://developers.home-assistant.io/docs/supervisor/developing)
|
- Hass.io: [Instructions](https://developers.home-assistant.io/docs/en/hassio_hass.html)
|
||||||
|
|
||||||
## Frontend development
|
## Frontend development
|
||||||
|
|
||||||
|
30
azure-pipelines-netlify.yml
Normal file
30
azure-pipelines-netlify.yml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# https://dev.azure.com/home-assistant
|
||||||
|
|
||||||
|
trigger: none
|
||||||
|
pr: none
|
||||||
|
schedules:
|
||||||
|
- cron: "0 0 * * *"
|
||||||
|
displayName: "build preview"
|
||||||
|
branches:
|
||||||
|
include:
|
||||||
|
- dev
|
||||||
|
always: true
|
||||||
|
variables:
|
||||||
|
- group: netlify
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
- job: 'Netlify_preview'
|
||||||
|
pool:
|
||||||
|
vmImage: 'ubuntu-latest'
|
||||||
|
steps:
|
||||||
|
- script: |
|
||||||
|
# Cast
|
||||||
|
curl -X POST -d {} https://api.netlify.com/build_hooks/${NETLIFY_CAST}
|
||||||
|
|
||||||
|
# Demo
|
||||||
|
curl -X POST -d {} https://api.netlify.com/build_hooks/${NETLIFY_DEMO}
|
||||||
|
|
||||||
|
# Gallery
|
||||||
|
curl -X POST -d {} https://api.netlify.com/build_hooks/${NETLIFY_GALLERY}
|
||||||
|
displayName: 'Trigger netlify build preview'
|
59
azure-pipelines-release.yml
Normal file
59
azure-pipelines-release.yml
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# https://dev.azure.com/home-assistant
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
batch: true
|
||||||
|
tags:
|
||||||
|
include:
|
||||||
|
- "*"
|
||||||
|
pr: none
|
||||||
|
variables:
|
||||||
|
- name: versionWheels
|
||||||
|
value: '1.10.1-3.7-alpine3.11'
|
||||||
|
- name: versionNode
|
||||||
|
value: '12.1'
|
||||||
|
- group: twine
|
||||||
|
resources:
|
||||||
|
repositories:
|
||||||
|
- repository: azure
|
||||||
|
type: github
|
||||||
|
name: 'home-assistant/ci-azure'
|
||||||
|
endpoint: 'home-assistant'
|
||||||
|
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- stage: "Validate"
|
||||||
|
jobs:
|
||||||
|
- template: templates/azp-job-version.yaml@azure
|
||||||
|
|
||||||
|
- stage: "Build"
|
||||||
|
jobs:
|
||||||
|
- job: "ReleasePython"
|
||||||
|
pool:
|
||||||
|
vmImage: "ubuntu-latest"
|
||||||
|
steps:
|
||||||
|
- task: UsePythonVersion@0
|
||||||
|
displayName: "Use Python 3.7"
|
||||||
|
inputs:
|
||||||
|
versionSpec: "3.7"
|
||||||
|
- task: NodeTool@0
|
||||||
|
displayName: "Use Node $(versionNode)"
|
||||||
|
inputs:
|
||||||
|
versionSpec: "$(versionNode)"
|
||||||
|
- script: pip install twine wheel
|
||||||
|
displayName: "Install tools"
|
||||||
|
- script: |
|
||||||
|
export TWINE_USERNAME="$(twineUser)"
|
||||||
|
export TWINE_PASSWORD="$(twinePassword)"
|
||||||
|
|
||||||
|
script/release
|
||||||
|
displayName: "Build and release package"
|
||||||
|
- stage: "Wheels"
|
||||||
|
jobs:
|
||||||
|
- template: templates/azp-job-wheels.yaml@azure
|
||||||
|
parameters:
|
||||||
|
builderVersion: '$(versionWheels)'
|
||||||
|
wheelsRequirement: 'requirement.txt'
|
||||||
|
preBuild:
|
||||||
|
- script: |
|
||||||
|
sleep 240
|
||||||
|
echo "home-assistant-frontend==$(Build.SourceBranchName)" > requirement.txt
|
70
azure-pipelines-translation.yml
Normal file
70
azure-pipelines-translation.yml
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# https://dev.azure.com/home-assistant
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
batch: true
|
||||||
|
branches:
|
||||||
|
include:
|
||||||
|
- dev
|
||||||
|
paths:
|
||||||
|
include:
|
||||||
|
- translations/en.json
|
||||||
|
pr: none
|
||||||
|
schedules:
|
||||||
|
- cron: "30 0 * * *"
|
||||||
|
displayName: "frontend translation update"
|
||||||
|
branches:
|
||||||
|
include:
|
||||||
|
- dev
|
||||||
|
always: true
|
||||||
|
variables:
|
||||||
|
- group: translation
|
||||||
|
resources:
|
||||||
|
repositories:
|
||||||
|
- repository: azure
|
||||||
|
type: github
|
||||||
|
name: 'home-assistant/ci-azure'
|
||||||
|
endpoint: 'home-assistant'
|
||||||
|
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
- job: 'Upload'
|
||||||
|
pool:
|
||||||
|
vmImage: 'ubuntu-latest'
|
||||||
|
steps:
|
||||||
|
- task: NodeTool@0
|
||||||
|
displayName: 'Use Node 12.x'
|
||||||
|
inputs:
|
||||||
|
versionSpec: '12.x'
|
||||||
|
- script: |
|
||||||
|
export LOKALISE_TOKEN="$(lokaliseToken)"
|
||||||
|
export AZURE_BRANCH="$(Build.SourceBranchName)"
|
||||||
|
|
||||||
|
./script/translations_upload_base
|
||||||
|
displayName: 'Upload Translation'
|
||||||
|
|
||||||
|
- job: 'Download'
|
||||||
|
dependsOn:
|
||||||
|
- 'Upload'
|
||||||
|
condition: or(eq(variables['Build.Reason'], 'Schedule'), eq(variables['Build.Reason'], 'Manual'))
|
||||||
|
pool:
|
||||||
|
vmImage: 'ubuntu-latest'
|
||||||
|
steps:
|
||||||
|
- task: NodeTool@0
|
||||||
|
displayName: 'Use Node 12.x'
|
||||||
|
inputs:
|
||||||
|
versionSpec: '12.x'
|
||||||
|
- template: templates/azp-step-git-init.yaml@azure
|
||||||
|
- script: |
|
||||||
|
export LOKALISE_TOKEN="$(lokaliseToken)"
|
||||||
|
export AZURE_BRANCH="$(Build.SourceBranchName)"
|
||||||
|
|
||||||
|
npm install
|
||||||
|
./script/translations_download
|
||||||
|
displayName: 'Download Translation'
|
||||||
|
- script: |
|
||||||
|
git checkout dev
|
||||||
|
git add translation
|
||||||
|
git commit -am "[ci skip] Translation update"
|
||||||
|
git push
|
||||||
|
displayName: 'Update translation'
|
@@ -36,7 +36,6 @@ const createWebpackConfig = ({
|
|||||||
const ignorePackages = bundle.ignorePackages({ latestBuild });
|
const ignorePackages = bundle.ignorePackages({ latestBuild });
|
||||||
return {
|
return {
|
||||||
mode: isProdBuild ? "production" : "development",
|
mode: isProdBuild ? "production" : "development",
|
||||||
target: ["web", latestBuild ? "es2017" : "es5"],
|
|
||||||
devtool: isProdBuild
|
devtool: isProdBuild
|
||||||
? "cheap-module-source-map"
|
? "cheap-module-source-map"
|
||||||
: "eval-cheap-module-source-map",
|
: "eval-cheap-module-source-map",
|
||||||
@@ -132,6 +131,22 @@ const createWebpackConfig = ({
|
|||||||
}
|
}
|
||||||
return `${chunk.name}.${chunk.hash.substr(0, 8)}.js`;
|
return `${chunk.name}.${chunk.hash.substr(0, 8)}.js`;
|
||||||
},
|
},
|
||||||
|
environment: {
|
||||||
|
// The environment supports arrow functions ('() => { ... }').
|
||||||
|
arrowFunction: latestBuild,
|
||||||
|
// The environment supports BigInt as literal (123n).
|
||||||
|
bigIntLiteral: false,
|
||||||
|
// The environment supports const and let for variable declarations.
|
||||||
|
const: latestBuild,
|
||||||
|
// The environment supports destructuring ('{ a, b } = obj').
|
||||||
|
destructuring: latestBuild,
|
||||||
|
// The environment supports an async import() function to import EcmaScript modules.
|
||||||
|
dynamicImport: latestBuild,
|
||||||
|
// The environment supports 'for of' iteration ('for (const x of array) { ... }').
|
||||||
|
forOf: latestBuild,
|
||||||
|
// The environment supports ECMAScript Module syntax to import ECMAScript modules (import ... from '...').
|
||||||
|
module: latestBuild,
|
||||||
|
},
|
||||||
chunkFilename:
|
chunkFilename:
|
||||||
isProdBuild && !isStatsBuild
|
isProdBuild && !isStatsBuild
|
||||||
? "chunk.[chunkhash].js"
|
? "chunk.[chunkhash].js"
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
customElement,
|
customElement,
|
||||||
html,
|
html,
|
||||||
internalProperty,
|
|
||||||
property,
|
property,
|
||||||
|
internalProperty,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { mockHistory } from "../../../../demo/src/stubs/history";
|
import { mockHistory } from "../../../../demo/src/stubs/history";
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import "web-animations-js/web-animations-next-lite.min";
|
import "web-animations-js/web-animations-next-lite.min";
|
||||||
import "../../../src/resources/ha-style";
|
|
||||||
import "../../../src/resources/roboto";
|
import "../../../src/resources/roboto";
|
||||||
|
import "../../../src/resources/ha-style";
|
||||||
import "./layout/hc-lovelace";
|
import "./layout/hc-lovelace";
|
||||||
|
@@ -54,8 +54,6 @@ export const demoEntitiesArsaboo: DemoConfig["entities"] = (localize) =>
|
|||||||
state: "21",
|
state: "21",
|
||||||
attributes: {
|
attributes: {
|
||||||
friendly_name: "Living room temperature",
|
friendly_name: "Living room temperature",
|
||||||
device_class: "temperature",
|
|
||||||
unit_of_measurement: "°C",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"sensor.study_temp_rounded": {
|
"sensor.study_temp_rounded": {
|
||||||
@@ -63,8 +61,6 @@ export const demoEntitiesArsaboo: DemoConfig["entities"] = (localize) =>
|
|||||||
state: "23",
|
state: "23",
|
||||||
attributes: {
|
attributes: {
|
||||||
friendly_name: "Study temperature",
|
friendly_name: "Study temperature",
|
||||||
device_class: "temperature",
|
|
||||||
unit_of_measurement: "°C",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"sensor.living_room": {
|
"sensor.living_room": {
|
||||||
@@ -265,7 +261,7 @@ export const demoEntitiesArsaboo: DemoConfig["entities"] = (localize) =>
|
|||||||
entity_id: "light.kitchen_lights",
|
entity_id: "light.kitchen_lights",
|
||||||
state: "off",
|
state: "off",
|
||||||
attributes: {
|
attributes: {
|
||||||
friendly_name: "Kitchen Lights",
|
friendly_name: "Kitchen lights",
|
||||||
supported_features: 1,
|
supported_features: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -488,7 +484,7 @@ export const demoEntitiesArsaboo: DemoConfig["entities"] = (localize) =>
|
|||||||
attributes: {
|
attributes: {
|
||||||
min_mireds: 111,
|
min_mireds: 111,
|
||||||
max_mireds: 400,
|
max_mireds: 400,
|
||||||
friendly_name: "Garage Lights",
|
friendly_name: "Garage lights",
|
||||||
supported_features: 55,
|
supported_features: 55,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@@ -12,7 +12,6 @@ export const demoLovelaceArsaboo: DemoConfig["lovelace"] = (localize) => ({
|
|||||||
{
|
{
|
||||||
type: "entities",
|
type: "entities",
|
||||||
title: localize("ui.panel.page-demo.config.arsaboo.labels.lights"),
|
title: localize("ui.panel.page-demo.config.arsaboo.labels.lights"),
|
||||||
state_color: true,
|
|
||||||
entities: [
|
entities: [
|
||||||
{
|
{
|
||||||
entity: "light.kitchen_lights",
|
entity: "light.kitchen_lights",
|
||||||
|
@@ -653,7 +653,7 @@ export const demoEntitiesJimpower: DemoConfig["entities"] = () =>
|
|||||||
entity_id: "binary_sensor.smoke_sensor_158d0001b8ddc7",
|
entity_id: "binary_sensor.smoke_sensor_158d0001b8ddc7",
|
||||||
state: "off",
|
state: "off",
|
||||||
attributes: {
|
attributes: {
|
||||||
density: 0,
|
Density: 0,
|
||||||
battery_level: 59,
|
battery_level: 59,
|
||||||
friendly_name: "Downstairs Smoke Detector",
|
friendly_name: "Downstairs Smoke Detector",
|
||||||
device_class: "smoke",
|
device_class: "smoke",
|
||||||
@@ -663,7 +663,7 @@ export const demoEntitiesJimpower: DemoConfig["entities"] = () =>
|
|||||||
entity_id: "binary_sensor.smoke_sensor_158d0001b8deba",
|
entity_id: "binary_sensor.smoke_sensor_158d0001b8deba",
|
||||||
state: "off",
|
state: "off",
|
||||||
attributes: {
|
attributes: {
|
||||||
density: 0,
|
Density: 0,
|
||||||
battery_level: 65,
|
battery_level: 65,
|
||||||
friendly_name: "Upstairs Smoke Detector",
|
friendly_name: "Upstairs Smoke Detector",
|
||||||
device_class: "smoke",
|
device_class: "smoke",
|
||||||
|
@@ -3,7 +3,49 @@ import { DemoConfig } from "../types";
|
|||||||
|
|
||||||
export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
|
export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
|
||||||
name: "Kingia Castle",
|
name: "Kingia Castle",
|
||||||
resources: [],
|
resources: [
|
||||||
|
// {
|
||||||
|
// url: "/local/custom_ui/dark-sky-weather-card.js?v=4",
|
||||||
|
// type: "js",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// url: "/local/custom_ui/mini-media-player-bundle.js?v=0.9.8",
|
||||||
|
// type: "module",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// url: "/local/custom_ui/tracker-card.js?v=0.1.5",
|
||||||
|
// type: "js",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// url: "/local/custom_ui/surveillance-card.js?v=0.0.1",
|
||||||
|
// type: "module",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// url: "/local/custom_ui/mini-graph-card-bundle.js?v=0.1.0",
|
||||||
|
// type: "module",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// url: "/local/custom_ui/slider-entity-row.js?v=d6da75",
|
||||||
|
// type: "js",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// url:
|
||||||
|
// "/local/custom_ui/compact-custom-header/compact-custom-header.js?v=0.2.7",
|
||||||
|
// type: "js",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// url: "/local/custom_ui/waze-card.js?v=1.1.1",
|
||||||
|
// type: "js",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// url: "/local/custom_ui/circle-sensor-card.js?v=1.2.0",
|
||||||
|
// type: "module",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// url: "/local/custom_ui/monster-card.js?v=0.2.3",
|
||||||
|
// type: "js",
|
||||||
|
// },
|
||||||
|
],
|
||||||
views: [
|
views: [
|
||||||
{
|
{
|
||||||
cards: [
|
cards: [
|
||||||
@@ -561,6 +603,89 @@ export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
cards: [
|
cards: [
|
||||||
|
// {
|
||||||
|
// style: {
|
||||||
|
// "background-image": 'url("/assets/jimpower/cardbackK.png")',
|
||||||
|
// "background-size": "100% 400px",
|
||||||
|
// "box-shadow": "3px 3px rgba(0,0,0,0.4)",
|
||||||
|
// "background-repeat": "no-repeat",
|
||||||
|
// color: "#999999",
|
||||||
|
// "border-radius": "20px",
|
||||||
|
// border: "solid 1px rgba(100,100,100,0.3)",
|
||||||
|
// "background-color": "rgba(50,50,50,0.3)",
|
||||||
|
// },
|
||||||
|
// type: "custom:card-modder",
|
||||||
|
// card: {
|
||||||
|
// entity_visibility: "sensor.dark_sky_visibility",
|
||||||
|
// entity_sun: "sun.sun",
|
||||||
|
// entity_daily_summary:
|
||||||
|
// "sensor.bom_gc_forecast_detailed_summary_0",
|
||||||
|
// entity_temperature: "sensor.bom_temp",
|
||||||
|
// entity_forecast_high_temp_3:
|
||||||
|
// "sensor.bom_gc_forecast_max_temp_c_3",
|
||||||
|
// entity_forecast_high_temp_2:
|
||||||
|
// "sensor.bom_gc_forecast_max_temp_c_2",
|
||||||
|
// entity_forecast_high_temp_5:
|
||||||
|
// "sensor.bom_gc_forecast_max_temp_c_5",
|
||||||
|
// entity_forecast_high_temp_4:
|
||||||
|
// "sensor.bom_gc_forecast_max_temp_c_4",
|
||||||
|
// entity_wind_speed: "sensor.bom_wind_sp",
|
||||||
|
// entity_forecast_icon_4: "sensor.dark_sky_icon_4",
|
||||||
|
// entity_forecast_icon_5: "sensor.dark_sky_icon_5",
|
||||||
|
// entity_forecast_icon_2: "sensor.dark_sky_icon_2",
|
||||||
|
// entity_forecast_icon_3: "sensor.dark_sky_icon_3",
|
||||||
|
// entity_forecast_icon_1: "sensor.dark_sky_icon_1",
|
||||||
|
// entity_forecast_high_temp_1:
|
||||||
|
// "sensor.bom_gc_forecast_max_temp_c_1",
|
||||||
|
// entity_wind_bearing: "sensor.bom_wind_bear",
|
||||||
|
// entity_forecast_low_temp_2:
|
||||||
|
// "sensor.bom_gc_forecast_min_temp_c_2",
|
||||||
|
// entity_forecast_low_temp_3:
|
||||||
|
// "sensor.bom_gc_forecast_min_temp_c_3",
|
||||||
|
// entity_pressure: "sensor.bom_pres",
|
||||||
|
// entity_forecast_low_temp_1:
|
||||||
|
// "sensor.bom_gc_forecast_min_temp_c_1",
|
||||||
|
// entity_forecast_low_temp_4:
|
||||||
|
// "sensor.bom_gc_forecast_min_temp_c_4",
|
||||||
|
// entity_forecast_low_temp_5:
|
||||||
|
// "sensor.bom_gc_forecast_min_temp_c_5",
|
||||||
|
// entity_humidity: "sensor.bom_humd",
|
||||||
|
// type: "custom:dark-sky-weather-card",
|
||||||
|
// entity_current_conditions: "sensor.dark_sky_icon",
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// style: {
|
||||||
|
// "background-image": 'url("/assets/jimpower/home/waze_5.png")',
|
||||||
|
// "background-size": "100% 400px",
|
||||||
|
// "box-shadow": "3px 3px rgba(0,0,0,0.4)",
|
||||||
|
// "background-repeat": "no-repeat",
|
||||||
|
// "border-radius": "20px",
|
||||||
|
// border: "solid 1px rgba(100,100,100,0.3)",
|
||||||
|
// "background-color": "rgba(50,50,50,0.3)",
|
||||||
|
// },
|
||||||
|
// type: "custom:card-modder",
|
||||||
|
// card: {
|
||||||
|
// entities: [
|
||||||
|
// {
|
||||||
|
// name: "James",
|
||||||
|
// zone: "zone.home",
|
||||||
|
// entity: "sensor.james_to_home",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: "Tina",
|
||||||
|
// zone: "zone.home",
|
||||||
|
// entity: "sensor.tina_to_home",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: "Work",
|
||||||
|
// zone: "zone.powertec",
|
||||||
|
// entity: "sensor.commute_to_work",
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// type: "custom:waze-card",
|
||||||
|
// },
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
style: {
|
style: {
|
||||||
"border-radius": "20px",
|
"border-radius": "20px",
|
||||||
@@ -597,8 +722,46 @@ export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
|
|||||||
],
|
],
|
||||||
type: "vertical-stack",
|
type: "vertical-stack",
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// cards: [
|
||||||
|
// {
|
||||||
|
// style: {
|
||||||
|
// "border-radius": "20px",
|
||||||
|
// color: "#999999",
|
||||||
|
// "box-shadow": "3px 3px rgba(0,0,0,0.4)",
|
||||||
|
// border: "solid 1px rgba(100,100,100,0.3)",
|
||||||
|
// },
|
||||||
|
// type: "custom:card-modder",
|
||||||
|
// card: {
|
||||||
|
// type: "picture-entity",
|
||||||
|
// entity: "camera.bom_radar",
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// // {
|
||||||
|
// // style: {
|
||||||
|
// // "background-image": 'url("/assets/jimpower/cardbackK.png")',
|
||||||
|
// // "background-size": "100% 525px",
|
||||||
|
// // "box-shadow": "3px 3px rgba(0,0,0,0.4)",
|
||||||
|
// // "background-repeat": "no-repeat",
|
||||||
|
// // color: "#999999",
|
||||||
|
// // "border-radius": "20px",
|
||||||
|
// // border: "solid 1px rgba(100,100,100,0.3)",
|
||||||
|
// // "background-color": "rgba(50,50,50,0.3)",
|
||||||
|
// // },
|
||||||
|
// // type: "custom:card-modder",
|
||||||
|
// // card: {
|
||||||
|
// // title: null,
|
||||||
|
// // type: "custom:tracker-card",
|
||||||
|
// // trackers: [
|
||||||
|
// // "sensor.custom_card_tracker",
|
||||||
|
// // "sensor.custom_component_tracker",
|
||||||
|
// // ],
|
||||||
|
// // },
|
||||||
|
// // },
|
||||||
|
// ],
|
||||||
|
// type: "vertical-stack",
|
||||||
|
// },
|
||||||
],
|
],
|
||||||
path: "home",
|
|
||||||
icon: "mdi:castle",
|
icon: "mdi:castle",
|
||||||
name: "Home",
|
name: "Home",
|
||||||
background:
|
background:
|
||||||
@@ -718,13 +881,26 @@ export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
|
|||||||
card: {
|
card: {
|
||||||
image: "/assets/jimpower/security/air_8.jpg",
|
image: "/assets/jimpower/security/air_8.jpg",
|
||||||
elements: [
|
elements: [
|
||||||
|
{
|
||||||
|
image:
|
||||||
|
"https://www.airvisual.com/assets/aqi/ic-face-1-green.svg",
|
||||||
|
type: "image",
|
||||||
|
style: {
|
||||||
|
width: "80px",
|
||||||
|
top: "30%",
|
||||||
|
left: "12%",
|
||||||
|
transform: "none",
|
||||||
|
height: "80px",
|
||||||
|
},
|
||||||
|
entity: "sensor.us_air_pollution_level_2",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
style: {
|
style: {
|
||||||
color: "hsl(120, 41%, 39%)",
|
color: "hsl(120, 41%, 39%)",
|
||||||
top: "50%",
|
top: "50%",
|
||||||
"font-weight": 600,
|
"font-weight": 600,
|
||||||
"font-size": "50px",
|
"font-size": "20px",
|
||||||
left: "30%",
|
left: "44%",
|
||||||
},
|
},
|
||||||
type: "state-label",
|
type: "state-label",
|
||||||
entity: "sensor.us_air_pollution_level_2",
|
entity: "sensor.us_air_pollution_level_2",
|
||||||
@@ -744,7 +920,7 @@ export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
|
|||||||
style: {
|
style: {
|
||||||
color: "white",
|
color: "white",
|
||||||
top: "80%",
|
top: "80%",
|
||||||
left: "48%",
|
left: "52%",
|
||||||
},
|
},
|
||||||
type: "state-icon",
|
type: "state-icon",
|
||||||
entity: "sensor.us_main_pollutant_2",
|
entity: "sensor.us_main_pollutant_2",
|
||||||
@@ -1235,7 +1411,6 @@ export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
|
|||||||
type: "vertical-stack",
|
type: "vertical-stack",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
path: "security",
|
|
||||||
icon: "hass:shield-home",
|
icon: "hass:shield-home",
|
||||||
name: "Security",
|
name: "Security",
|
||||||
background:
|
background:
|
||||||
|
@@ -101,12 +101,7 @@ export const demoEntitiesKernehed: DemoConfig["entities"] = () =>
|
|||||||
"sensor.zwave_battery_front_door": {
|
"sensor.zwave_battery_front_door": {
|
||||||
entity_id: "sensor.zwave_battery_front_door",
|
entity_id: "sensor.zwave_battery_front_door",
|
||||||
state: "63",
|
state: "63",
|
||||||
attributes: {
|
attributes: { friendly_name: "Battery", icon: "mdi:battery-60" },
|
||||||
friendly_name: "Battery",
|
|
||||||
icon: "mdi:battery-60",
|
|
||||||
unit_of_measurement: "%",
|
|
||||||
device_class: "battery",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
"sensor.oskar_devices": {
|
"sensor.oskar_devices": {
|
||||||
entity_id: "sensor.oskar_devices",
|
entity_id: "sensor.oskar_devices",
|
||||||
@@ -169,7 +164,7 @@ export const demoEntitiesKernehed: DemoConfig["entities"] = () =>
|
|||||||
},
|
},
|
||||||
"input_select.christmas_pattern": {
|
"input_select.christmas_pattern": {
|
||||||
entity_id: "input_select.christmas_pattern",
|
entity_id: "input_select.christmas_pattern",
|
||||||
state: "Rainbow",
|
state: "None",
|
||||||
attributes: {
|
attributes: {
|
||||||
options: [
|
options: [
|
||||||
"None",
|
"None",
|
||||||
@@ -191,7 +186,7 @@ export const demoEntitiesKernehed: DemoConfig["entities"] = () =>
|
|||||||
},
|
},
|
||||||
"input_select.christmas_palette": {
|
"input_select.christmas_palette": {
|
||||||
entity_id: "input_select.christmas_palette",
|
entity_id: "input_select.christmas_palette",
|
||||||
state: "Party",
|
state: "None",
|
||||||
attributes: {
|
attributes: {
|
||||||
options: [
|
options: [
|
||||||
"None",
|
"None",
|
||||||
@@ -462,7 +457,7 @@ export const demoEntitiesKernehed: DemoConfig["entities"] = () =>
|
|||||||
state: "0.0",
|
state: "0.0",
|
||||||
attributes: {
|
attributes: {
|
||||||
unit_of_measurement: "kB/s",
|
unit_of_measurement: "kB/s",
|
||||||
friendly_name: "Downloading",
|
friendly_name: "Nedladdning",
|
||||||
icon: "mdi:file-download",
|
icon: "mdi:file-download",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -476,7 +471,7 @@ export const demoEntitiesKernehed: DemoConfig["entities"] = () =>
|
|||||||
state: "0.0",
|
state: "0.0",
|
||||||
attributes: {
|
attributes: {
|
||||||
unit_of_measurement: "kB/s",
|
unit_of_measurement: "kB/s",
|
||||||
friendly_name: "Uploading",
|
friendly_name: "Uppladdning",
|
||||||
icon: "mdi:file-upload",
|
icon: "mdi:file-upload",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@@ -2,7 +2,44 @@ import { DemoConfig } from "../types";
|
|||||||
|
|
||||||
export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
|
export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
|
||||||
name: "Hem",
|
name: "Hem",
|
||||||
resources: [],
|
resources: [
|
||||||
|
// {
|
||||||
|
// url: "/local/custom-lovelace/monster-card.js",
|
||||||
|
// type: "js",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// url: "/local/custom-lovelace/mini-media-player-bundle.js?v=0.9.8",
|
||||||
|
// type: "module",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// url: "/local/custom-lovelace/slideshow-card.js?=1.1.0",
|
||||||
|
// type: "js",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// url: "/local/custom-lovelace/fold-entity-row.js?v=3ae2c4",
|
||||||
|
// type: "js",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// url: "/local/custom-lovelace/swipe-card/swipe-card.js?v=2.0.0",
|
||||||
|
// type: "module",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// url: "/local/custom-lovelace/upcoming-media-card/upcoming-media-card.js",
|
||||||
|
// type: "js",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// url: "/local/custom-lovelace/tracker-card.js?v=0.1.5",
|
||||||
|
// type: "js",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// url: "/local/custom-lovelace/card-tools.js?v=6ce5d0",
|
||||||
|
// type: "js",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// url: "/local/custom-lovelace/krisinfo.js?=0.0.1",
|
||||||
|
// type: "js",
|
||||||
|
// },
|
||||||
|
],
|
||||||
views: [
|
views: [
|
||||||
{
|
{
|
||||||
cards: [
|
cards: [
|
||||||
@@ -27,7 +64,7 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
|
|||||||
style: {
|
style: {
|
||||||
color: "white",
|
color: "white",
|
||||||
top: "93%",
|
top: "93%",
|
||||||
left: "85%",
|
left: "90%",
|
||||||
},
|
},
|
||||||
type: "state-label",
|
type: "state-label",
|
||||||
entity: "sensor.battery_oskar",
|
entity: "sensor.battery_oskar",
|
||||||
@@ -50,7 +87,7 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
|
|||||||
{
|
{
|
||||||
style: {
|
style: {
|
||||||
color: "white",
|
color: "white",
|
||||||
top: "93%",
|
top: "92%",
|
||||||
left: "20%",
|
left: "20%",
|
||||||
},
|
},
|
||||||
type: "state-label",
|
type: "state-label",
|
||||||
@@ -59,8 +96,8 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
|
|||||||
{
|
{
|
||||||
style: {
|
style: {
|
||||||
color: "white",
|
color: "white",
|
||||||
top: "93%",
|
top: "92%",
|
||||||
left: "85%",
|
left: "90%",
|
||||||
},
|
},
|
||||||
type: "state-label",
|
type: "state-label",
|
||||||
entity: "sensor.battery_bella",
|
entity: "sensor.battery_bella",
|
||||||
@@ -68,7 +105,7 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
|
|||||||
{
|
{
|
||||||
style: {
|
style: {
|
||||||
color: "white",
|
color: "white",
|
||||||
top: "93%",
|
top: "92%",
|
||||||
left: "55%",
|
left: "55%",
|
||||||
},
|
},
|
||||||
type: "state-label",
|
type: "state-label",
|
||||||
@@ -94,6 +131,78 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
|
|||||||
type: "entities",
|
type: "entities",
|
||||||
title: "Lock",
|
title: "Lock",
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// filter: {
|
||||||
|
// exclude: [
|
||||||
|
// {
|
||||||
|
// state: "not_home",
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// include: [
|
||||||
|
// {
|
||||||
|
// entity_id: "device_tracker.annasiphone",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// entity_id: "device_tracker.iphone_2",
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
// type: "custom:monster-card",
|
||||||
|
// card: {
|
||||||
|
// show_header_toggle: false,
|
||||||
|
// type: "entities",
|
||||||
|
// title: "G\u00e4ster",
|
||||||
|
// },
|
||||||
|
// show_empty: false,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// filter: {
|
||||||
|
// exclude: [
|
||||||
|
// {
|
||||||
|
// state: "Inget",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// state: "i.u.",
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// include: [
|
||||||
|
// {
|
||||||
|
// entity_id: "sensor.pollen_al",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// entity_id: "sensor.pollen_alm",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// entity_id: "sensor.pollen_salg_vide",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// entity_id: "sensor.pollen_bjork",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// entity_id: "sensor.pollen_bok",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// entity_id: "sensor.pollen_ek",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// entity_id: "sensor.pollen_grabo",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// entity_id: "sensor.pollen_gras",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// entity_id: "sensor.pollen_hassel",
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
// type: "custom:monster-card",
|
||||||
|
// card: {
|
||||||
|
// show_header_toggle: false,
|
||||||
|
// type: "entities",
|
||||||
|
// title: "Pollenniv\u00e5er",
|
||||||
|
// },
|
||||||
|
// show_empty: false,
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
cards: [
|
cards: [
|
||||||
{
|
{
|
||||||
@@ -117,6 +226,10 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
|
|||||||
],
|
],
|
||||||
type: "vertical-stack",
|
type: "vertical-stack",
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// url: "https://embed.windy.com/embed2.html",
|
||||||
|
// type: "iframe",
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
entities: [
|
entities: [
|
||||||
{
|
{
|
||||||
@@ -150,7 +263,6 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
|
|||||||
],
|
],
|
||||||
type: "glance",
|
type: "glance",
|
||||||
show_state: false,
|
show_state: false,
|
||||||
columns: 4,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
entities: ["sensor.oskar_bluetooth"],
|
entities: ["sensor.oskar_bluetooth"],
|
||||||
@@ -158,6 +270,32 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
|
|||||||
type: "entities",
|
type: "entities",
|
||||||
title: "Occupancy",
|
title: "Occupancy",
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// filter: {
|
||||||
|
// exclude: [
|
||||||
|
// {
|
||||||
|
// state: false,
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// include: [
|
||||||
|
// {
|
||||||
|
// entity_id:
|
||||||
|
// "binary_sensor.fibaro_system_unknown_type0c02_id1003_sensor_2",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// entity_id:
|
||||||
|
// "binary_sensor.fibaro_system_unknown_type0c02_id1003_sensor_3",
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
// type: "custom:monster-card",
|
||||||
|
// card: {
|
||||||
|
// show_header_toggle: false,
|
||||||
|
// type: "entities",
|
||||||
|
// title: "Brandvarnare",
|
||||||
|
// },
|
||||||
|
// show_empty: false,
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
type: "weather-forecast",
|
type: "weather-forecast",
|
||||||
entity: "weather.smhi_vader",
|
entity: "weather.smhi_vader",
|
||||||
@@ -240,9 +378,41 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
|
|||||||
"binary_sensor.windows_server",
|
"binary_sensor.windows_server",
|
||||||
"binary_sensor.teamspeak",
|
"binary_sensor.teamspeak",
|
||||||
"binary_sensor.harmony_hub",
|
"binary_sensor.harmony_hub",
|
||||||
|
// {
|
||||||
|
// style: {
|
||||||
|
// height: "1px",
|
||||||
|
// width: "85%",
|
||||||
|
// "margin-left": "auto",
|
||||||
|
// background: "#62717b",
|
||||||
|
// "margin-right": "auto",
|
||||||
|
// },
|
||||||
|
// type: "divider",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// items: ["sensor.uptime_router", "sensor.installerad_routeros"],
|
||||||
|
// head: {
|
||||||
|
// entity: "binary_sensor.router",
|
||||||
|
// },
|
||||||
|
// type: "custom:fold-entity-row",
|
||||||
|
// group_config: {
|
||||||
|
// icon: "mdi:router",
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// items: [
|
||||||
|
// "sensor.uptime_router_server",
|
||||||
|
// "sensor.installerad_routeros_server",
|
||||||
|
// ],
|
||||||
|
// head: {
|
||||||
|
// entity: "binary_sensor.router_server",
|
||||||
|
// },
|
||||||
|
// type: "custom:fold-entity-row",
|
||||||
|
// group_config: {
|
||||||
|
// icon: "mdi:router",
|
||||||
|
// },
|
||||||
|
// },
|
||||||
],
|
],
|
||||||
show_header_toggle: false,
|
show_header_toggle: false,
|
||||||
state_color: true,
|
|
||||||
type: "entities",
|
type: "entities",
|
||||||
title: "Network",
|
title: "Network",
|
||||||
},
|
},
|
||||||
@@ -252,10 +422,29 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
|
|||||||
"binary_sensor.ubiquiti_switch",
|
"binary_sensor.ubiquiti_switch",
|
||||||
"binary_sensor.ubiquiti_nvr",
|
"binary_sensor.ubiquiti_nvr",
|
||||||
"binary_sensor.entre_kamera",
|
"binary_sensor.entre_kamera",
|
||||||
|
// {
|
||||||
|
// items: ["sensor.uptime_ap_1"],
|
||||||
|
// head: {
|
||||||
|
// entity: "binary_sensor.accesspunkt_1",
|
||||||
|
// },
|
||||||
|
// type: "custom:fold-entity-row",
|
||||||
|
// group_config: {
|
||||||
|
// icon: "router-wireless",
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// items: ["sensor.uptime_ap_2"],
|
||||||
|
// head: {
|
||||||
|
// entity: "binary_sensor.accesspunkt_2",
|
||||||
|
// },
|
||||||
|
// type: "custom:fold-entity-row",
|
||||||
|
// group_config: {
|
||||||
|
// icon: "router-wireless",
|
||||||
|
// },
|
||||||
|
// },
|
||||||
"sensor.total_clients_wireless",
|
"sensor.total_clients_wireless",
|
||||||
],
|
],
|
||||||
show_header_toggle: false,
|
show_header_toggle: false,
|
||||||
state_color: true,
|
|
||||||
type: "entities",
|
type: "entities",
|
||||||
title: "Ubiquiti",
|
title: "Ubiquiti",
|
||||||
},
|
},
|
||||||
|
@@ -215,7 +215,6 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
card: {
|
card: {
|
||||||
type: "glance",
|
type: "glance",
|
||||||
show_state: false,
|
show_state: false,
|
||||||
columns: 4,
|
|
||||||
},
|
},
|
||||||
state_filter: ["on"],
|
state_filter: ["on"],
|
||||||
},
|
},
|
||||||
@@ -809,6 +808,67 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
],
|
],
|
||||||
type: "vertical-stack",
|
type: "vertical-stack",
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// cards: [
|
||||||
|
// {
|
||||||
|
// entities: [
|
||||||
|
// {
|
||||||
|
// hide_when_off: true,
|
||||||
|
// toggle: true,
|
||||||
|
// type: "custom:slider-entity-row",
|
||||||
|
// name: "Bedside",
|
||||||
|
// entity: "light.bedside_lamp",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// hide_when_off: true,
|
||||||
|
// toggle: true,
|
||||||
|
// type: "custom:slider-entity-row",
|
||||||
|
// name: "Bedroom",
|
||||||
|
// entity: "light.bedroom_ceiling_light",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// hide_when_off: true,
|
||||||
|
// toggle: true,
|
||||||
|
// type: "custom:slider-entity-row",
|
||||||
|
// name: "Isa",
|
||||||
|
// entity: "light.isa_ceiling_light",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// hide_when_off: true,
|
||||||
|
// toggle: true,
|
||||||
|
// type: "custom:slider-entity-row",
|
||||||
|
// name: "Upstairs hallway",
|
||||||
|
// entity: "light.upstairs_hallway_ceiling_light_level",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// hide_when_off: true,
|
||||||
|
// toggle: true,
|
||||||
|
// type: "custom:slider-entity-row",
|
||||||
|
// name: "Nightlight",
|
||||||
|
// entity: "light.gateway_light_34ce008bfc4b",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// hide_when_off: true,
|
||||||
|
// toggle: true,
|
||||||
|
// type: "custom:slider-entity-row",
|
||||||
|
// name: "Walk in closet",
|
||||||
|
// entity: "light.walk_in_closet_lights",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// hide_when_off: true,
|
||||||
|
// toggle: false,
|
||||||
|
// type: "custom:slider-entity-row",
|
||||||
|
// name: "Stefan",
|
||||||
|
// entity: "light.stefan_lightstrip",
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// show_header_toggle: false,
|
||||||
|
// type: "entities",
|
||||||
|
// title: "Upstairs",
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// type: "vertical-stack",
|
||||||
|
// },
|
||||||
],
|
],
|
||||||
path: "lights",
|
path: "lights",
|
||||||
title: "Lights",
|
title: "Lights",
|
||||||
@@ -858,6 +918,10 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
name: "Dafang",
|
name: "Dafang",
|
||||||
icon: "mdi:webcam",
|
icon: "mdi:webcam",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "IR Hallway",
|
||||||
|
entity: "sensor.system_ir_blaster",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "IR Bedroom",
|
name: "IR Bedroom",
|
||||||
entity: "sensor.system_ir_blaster_bedroom",
|
entity: "sensor.system_ir_blaster_bedroom",
|
||||||
@@ -876,7 +940,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
"sensor.system_ring_chime",
|
"sensor.system_ring_chime",
|
||||||
],
|
],
|
||||||
type: "glance",
|
type: "glance",
|
||||||
columns: 4,
|
columns: 5,
|
||||||
show_state: false,
|
show_state: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@@ -3,8 +3,8 @@ import {
|
|||||||
CSSResult,
|
CSSResult,
|
||||||
customElement,
|
customElement,
|
||||||
html,
|
html,
|
||||||
internalProperty,
|
|
||||||
LitElement,
|
LitElement,
|
||||||
|
internalProperty,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { CastManager } from "../../../src/cast/cast_manager";
|
import { CastManager } from "../../../src/cast/cast_manager";
|
||||||
|
@@ -3,9 +3,9 @@ import {
|
|||||||
css,
|
css,
|
||||||
CSSResult,
|
CSSResult,
|
||||||
html,
|
html,
|
||||||
internalProperty,
|
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
|
internalProperty,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { until } from "lit-html/directives/until";
|
import { until } from "lit-html/directives/until";
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
|
import "../../src/resources/safari-14-attachshadow-patch";
|
||||||
import "@polymer/polymer/lib/elements/dom-if";
|
import "@polymer/polymer/lib/elements/dom-if";
|
||||||
import "@polymer/polymer/lib/elements/dom-repeat";
|
import "@polymer/polymer/lib/elements/dom-repeat";
|
||||||
import "../../src/resources/ha-style";
|
import "../../src/resources/ha-style";
|
||||||
import "../../src/resources/roboto";
|
import "../../src/resources/roboto";
|
||||||
import "../../src/resources/safari-14-attachshadow-patch";
|
|
||||||
import "./ha-demo";
|
import "./ha-demo";
|
||||||
|
|
||||||
/* polyfill for paper-dropdown */
|
/* polyfill for paper-dropdown */
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
// Compat needs to be first import
|
|
||||||
import "../../src/resources/compatibility";
|
import "../../src/resources/compatibility";
|
||||||
import { isNavigationClick } from "../../src/common/dom/is-navigation-click";
|
import { isNavigationClick } from "../../src/common/dom/is-navigation-click";
|
||||||
import { navigate } from "../../src/common/navigate";
|
import { navigate } from "../../src/common/navigate";
|
||||||
|
@@ -2,10 +2,10 @@ import "@polymer/app-layout/app-toolbar/app-toolbar";
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
/* eslint-plugin-disable lit */
|
/* eslint-plugin-disable lit */
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element";
|
|
||||||
import "../../../src/components/ha-formfield";
|
|
||||||
import "../../../src/components/ha-switch";
|
import "../../../src/components/ha-switch";
|
||||||
|
import "../../../src/components/ha-formfield";
|
||||||
import "./demo-card";
|
import "./demo-card";
|
||||||
|
import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element";
|
||||||
|
|
||||||
class DemoCards extends PolymerElement {
|
class DemoCards extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
|
@@ -2,36 +2,37 @@ import { html } from "@polymer/polymer/lib/utils/html-tag";
|
|||||||
/* eslint-plugin-disable lit */
|
/* eslint-plugin-disable lit */
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
import "../../../src/components/ha-card";
|
import "../../../src/components/ha-card";
|
||||||
import "../../../src/dialogs/more-info/more-info-content";
|
|
||||||
import "../../../src/state-summary/state-card-content";
|
import "../../../src/state-summary/state-card-content";
|
||||||
|
import "../../../src/dialogs/more-info/more-info-content";
|
||||||
|
|
||||||
class DemoMoreInfo extends PolymerElement {
|
class DemoMoreInfo extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
return html`
|
return html`
|
||||||
<style>
|
<style>
|
||||||
.root {
|
:host {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: start;
|
||||||
}
|
}
|
||||||
#card {
|
|
||||||
max-width: 400px;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
ha-card {
|
ha-card {
|
||||||
width: 352px;
|
width: 333px;
|
||||||
padding: 20px 24px;
|
padding: 20px 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
state-card-content {
|
state-card-content {
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
width: 400px;
|
width: 400px;
|
||||||
margin: 0 16px;
|
margin: 0 16px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
color: var(--primary-text-color);
|
color: var(--primary-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 800px) {
|
@media only screen and (max-width: 800px) {
|
||||||
.root {
|
:host {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
pre {
|
pre {
|
||||||
@@ -39,25 +40,21 @@ class DemoMoreInfo extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="root">
|
<ha-card>
|
||||||
<div id="card">
|
<state-card-content
|
||||||
<ha-card>
|
state-obj="[[_stateObj]]"
|
||||||
<state-card-content
|
hass="[[hass]]"
|
||||||
state-obj="[[_stateObj]]"
|
in-dialog
|
||||||
hass="[[hass]]"
|
></state-card-content>
|
||||||
in-dialog
|
|
||||||
></state-card-content>
|
|
||||||
|
|
||||||
<more-info-content
|
<more-info-content
|
||||||
hass="[[hass]]"
|
hass="[[hass]]"
|
||||||
state-obj="[[_stateObj]]"
|
state-obj="[[_stateObj]]"
|
||||||
></more-info-content>
|
></more-info-content>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
</div>
|
<template is="dom-if" if="[[showConfig]]">
|
||||||
<template is="dom-if" if="[[showConfig]]">
|
<pre>[[_jsonEntity(_stateObj)]]</pre>
|
||||||
<pre>[[_jsonEntity(_stateObj)]]</pre>
|
</template>
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,8 +2,6 @@ import "@polymer/app-layout/app-toolbar/app-toolbar";
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
/* eslint-plugin-disable lit */
|
/* eslint-plugin-disable lit */
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element";
|
|
||||||
import "../../../src/components/ha-formfield";
|
|
||||||
import "../../../src/components/ha-switch";
|
import "../../../src/components/ha-switch";
|
||||||
import "./demo-more-info";
|
import "./demo-more-info";
|
||||||
|
|
||||||
@@ -11,10 +9,6 @@ class DemoMoreInfos extends PolymerElement {
|
|||||||
static get template() {
|
static get template() {
|
||||||
return html`
|
return html`
|
||||||
<style>
|
<style>
|
||||||
#container {
|
|
||||||
min-height: calc(100vh - 128px);
|
|
||||||
background: var(--primary-background-color);
|
|
||||||
}
|
|
||||||
.cards {
|
.cards {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@@ -29,31 +23,20 @@ class DemoMoreInfos extends PolymerElement {
|
|||||||
.filters {
|
.filters {
|
||||||
margin-left: 60px;
|
margin-left: 60px;
|
||||||
}
|
}
|
||||||
ha-formfield {
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
<app-toolbar>
|
<app-toolbar>
|
||||||
<div class="filters">
|
<div class="filters">
|
||||||
<ha-formfield label="Show entities">
|
<ha-switch checked="{{_showConfig}}">Show entity</ha-switch>
|
||||||
<ha-switch checked="[[_showConfig]]" on-change="_showConfigToggled">
|
|
||||||
</ha-switch>
|
|
||||||
</ha-formfield>
|
|
||||||
<ha-formfield label="Dark theme">
|
|
||||||
<ha-switch on-change="_darkThemeToggled"> </ha-switch>
|
|
||||||
</ha-formfield>
|
|
||||||
</div>
|
</div>
|
||||||
</app-toolbar>
|
</app-toolbar>
|
||||||
<div id="container">
|
<div class="cards">
|
||||||
<div class="cards">
|
<template is="dom-repeat" items="[[entities]]">
|
||||||
<template is="dom-repeat" items="[[entities]]">
|
<demo-more-info
|
||||||
<demo-more-info
|
entity-id="[[item]]"
|
||||||
entity-id="[[item]]"
|
show-config="[[_showConfig]]"
|
||||||
show-config="[[_showConfig]]"
|
hass="[[hass]]"
|
||||||
hass="[[hass]]"
|
></demo-more-info>
|
||||||
></demo-more-info>
|
</template>
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@@ -68,16 +51,6 @@ class DemoMoreInfos extends PolymerElement {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_showConfigToggled(ev) {
|
|
||||||
this._showConfig = ev.target.checked;
|
|
||||||
}
|
|
||||||
|
|
||||||
_darkThemeToggled(ev) {
|
|
||||||
applyThemesOnElement(this.$.container, { themes: {} }, "default", {
|
|
||||||
dark: ev.target.checked,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-more-infos", DemoMoreInfos);
|
customElements.define("demo-more-infos", DemoMoreInfos);
|
||||||
|
@@ -7,8 +7,8 @@ export const createMediaPlayerEntities = () => [
|
|||||||
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",
|
||||||
// Pause + Seek + Volume Set + Volume Mute + Previous Track + Next Track + Play Media +
|
// Pause + Seek + Volume Set + Volume Mute + Previous Track + Next Track + Play Media +
|
||||||
// Select Source + Stop + Clear + Play + Shuffle Set
|
// Select Source + Stop + Clear + Play + Shuffle Set + Browse Media
|
||||||
supported_features: 64063,
|
supported_features: 195135,
|
||||||
entity_picture: "/images/album_cover_2.jpg",
|
entity_picture: "/images/album_cover_2.jpg",
|
||||||
media_duration: 300,
|
media_duration: 300,
|
||||||
media_position: 50,
|
media_position: 50,
|
||||||
@@ -24,8 +24,8 @@ export const createMediaPlayerEntities = () => [
|
|||||||
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",
|
||||||
// Pause + Seek + Volume Set + Volume Mute + Previous Track + Next Track + Play Media +
|
// Pause + Seek + Volume Set + Volume Mute + Previous Track + Next Track + Play Media +
|
||||||
// Select Source + Stop + Clear + Play + Shuffle Set + Browse Media
|
// Select Source + Stop + Clear + Play + Shuffle Set
|
||||||
supported_features: 195135,
|
supported_features: 64063,
|
||||||
entity_picture: "/images/album_cover.jpg",
|
entity_picture: "/images/album_cover.jpg",
|
||||||
media_duration: 300,
|
media_duration: 300,
|
||||||
media_position: 0,
|
media_position: 0,
|
||||||
|
@@ -1,72 +0,0 @@
|
|||||||
import { getEntity } from "../../../src/fake_data/entity";
|
|
||||||
|
|
||||||
export const createPlantEntities = () => [
|
|
||||||
getEntity("plant", "lemon_tree", "ok", {
|
|
||||||
problem: "none",
|
|
||||||
sensors: {
|
|
||||||
moisture: "sensor.lemon_tree_moisture",
|
|
||||||
battery: "sensor.lemon_tree_battery",
|
|
||||||
temperature: "sensor.lemon_tree_temperature",
|
|
||||||
conductivity: "sensor.lemon_tree_conductivity",
|
|
||||||
brightness: "sensor.lemon_tree_brightness",
|
|
||||||
},
|
|
||||||
unit_of_measurement_dict: {
|
|
||||||
temperature: "°C",
|
|
||||||
moisture: "%",
|
|
||||||
brightness: "lx",
|
|
||||||
battery: "%",
|
|
||||||
conductivity: "μS/cm",
|
|
||||||
},
|
|
||||||
moisture: 54,
|
|
||||||
battery: 95,
|
|
||||||
temperature: 15.6,
|
|
||||||
conductivity: 1,
|
|
||||||
brightness: 12,
|
|
||||||
max_brightness: 20,
|
|
||||||
friendly_name: "Lemon Tree",
|
|
||||||
}),
|
|
||||||
getEntity("plant", "apple_tree", "ok", {
|
|
||||||
problem: "brightness",
|
|
||||||
sensors: {
|
|
||||||
moisture: "sensor.apple_tree_moisture",
|
|
||||||
battery: "sensor.apple_tree_battery",
|
|
||||||
temperature: "sensor.apple_tree_temperature",
|
|
||||||
conductivity: "sensor.apple_tree_conductivity",
|
|
||||||
brightness: "sensor.apple_tree_brightness",
|
|
||||||
},
|
|
||||||
unit_of_measurement_dict: {
|
|
||||||
temperature: "°C",
|
|
||||||
moisture: "%",
|
|
||||||
brightness: "lx",
|
|
||||||
battery: "%",
|
|
||||||
conductivity: "μS/cm",
|
|
||||||
},
|
|
||||||
moisture: 54,
|
|
||||||
battery: 2,
|
|
||||||
temperature: 15.6,
|
|
||||||
conductivity: 1,
|
|
||||||
brightness: 25,
|
|
||||||
max_brightness: 20,
|
|
||||||
friendly_name: "Apple Tree",
|
|
||||||
}),
|
|
||||||
getEntity("plant", "sunflowers", "ok", {
|
|
||||||
problem: "moisture, temperature, conductivity",
|
|
||||||
sensors: {
|
|
||||||
moisture: "sensor.sunflowers_moisture",
|
|
||||||
temperature: "sensor.sunflowers_temperature",
|
|
||||||
conductivity: "sensor.sunflowers_conductivity",
|
|
||||||
brightness: "sensor.sunflowers_brightness",
|
|
||||||
},
|
|
||||||
unit_of_measurement_dict: {
|
|
||||||
temperature: "°C",
|
|
||||||
moisture: "%",
|
|
||||||
brightness: "lx",
|
|
||||||
conductivity: "μS/cm",
|
|
||||||
},
|
|
||||||
moisture: 54,
|
|
||||||
temperature: 15.6,
|
|
||||||
conductivity: 1,
|
|
||||||
brightness: 25,
|
|
||||||
entity_picture: "/images/sunflowers.jpg",
|
|
||||||
}),
|
|
||||||
];
|
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { getEntity } from "../../../src/fake_data/entity";
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
@@ -76,19 +71,28 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-alarm-panel-card")
|
class DemoAlarmPanelEntity extends PolymerElement {
|
||||||
class DemoAlarmPanelEntity extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
hass.updateTranslations(null, "en");
|
type: Object,
|
||||||
hass.updateTranslations("lovelace", "en");
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
this._setupDemo();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _setupDemo() {
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
|
await hass.updateTranslations(null, "en");
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { getEntity } from "../../../src/fake_data/entity";
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
@@ -58,19 +53,24 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-conditional-card")
|
class DemoConditional extends PolymerElement {
|
||||||
class DemoConditional extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.updateTranslations("lovelace", "en");
|
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { getEntity } from "../../../src/fake_data/entity";
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
@@ -222,19 +217,24 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-entities-card")
|
class DemoEntities extends PolymerElement {
|
||||||
class DemoEntities extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.updateTranslations("lovelace", "en");
|
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { getEntity } from "../../../src/fake_data/entity";
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
@@ -53,7 +48,7 @@ const CONFIGS = [
|
|||||||
config: `
|
config: `
|
||||||
- type: button
|
- type: button
|
||||||
entity: light.bed_light
|
entity: light.bed_light
|
||||||
tap_action:
|
tap_action:
|
||||||
action: toggle
|
action: toggle
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
@@ -74,19 +69,24 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-entity-button-card")
|
class DemoButtonEntity extends PolymerElement {
|
||||||
class DemoButtonEntity extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.updateTranslations("lovelace", "en");
|
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { getEntity } from "../../../src/fake_data/entity";
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
@@ -48,7 +43,7 @@ const ENTITIES = [
|
|||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
{
|
{
|
||||||
heading: "Unfiltered controller",
|
heading: "Controller",
|
||||||
config: `
|
config: `
|
||||||
- type: entities
|
- type: entities
|
||||||
entities:
|
entities:
|
||||||
@@ -58,7 +53,7 @@ const CONFIGS = [
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "Filtered entities card",
|
heading: "Basic",
|
||||||
config: `
|
config: `
|
||||||
- type: entity-filter
|
- type: entity-filter
|
||||||
entities:
|
entities:
|
||||||
@@ -74,27 +69,7 @@ const CONFIGS = [
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: 'With "entities" card config',
|
heading: "With card config",
|
||||||
config: `
|
|
||||||
- type: entity-filter
|
|
||||||
entities:
|
|
||||||
- device_tracker.demo_anne_therese
|
|
||||||
- device_tracker.demo_home_boy
|
|
||||||
- device_tracker.demo_paulus
|
|
||||||
- light.bed_light
|
|
||||||
- light.ceiling_lights
|
|
||||||
- light.kitchen_lights
|
|
||||||
state_filter:
|
|
||||||
- "on"
|
|
||||||
- not_home
|
|
||||||
card:
|
|
||||||
type: entities
|
|
||||||
title: Custom Title
|
|
||||||
show_header_toggle: false
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
heading: 'With "glance" card config',
|
|
||||||
config: `
|
config: `
|
||||||
- type: entity-filter
|
- type: entity-filter
|
||||||
entities:
|
entities:
|
||||||
@@ -109,27 +84,31 @@ const CONFIGS = [
|
|||||||
- not_home
|
- not_home
|
||||||
card:
|
card:
|
||||||
type: glance
|
type: glance
|
||||||
show_state: true
|
show_state: false
|
||||||
title: Custom Title
|
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-entity-filter-card")
|
class DemoFilter extends PolymerElement {
|
||||||
class DemoEntityFilter extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.updateTranslations("lovelace", "en");
|
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-hui-entity-filter-card", DemoEntityFilter);
|
customElements.define("demo-hui-entity-filter-card", DemoFilter);
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { getEntity } from "../../../src/fake_data/entity";
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
@@ -112,19 +107,24 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-gauge-card")
|
class DemoGaugeEntity extends PolymerElement {
|
||||||
class DemoGaugeEntity extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.updateTranslations("lovelace", "en");
|
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { getEntity } from "../../../src/fake_data/entity";
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
@@ -82,8 +77,7 @@ const CONFIGS = [
|
|||||||
heading: "With title",
|
heading: "With title",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
title: Custom title
|
title: This is glance
|
||||||
columns: 4
|
|
||||||
entities:
|
entities:
|
||||||
- device_tracker.demo_paulus
|
- device_tracker.demo_paulus
|
||||||
- media_player.living_room
|
- media_player.living_room
|
||||||
@@ -110,10 +104,9 @@ const CONFIGS = [
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "No entity names",
|
heading: "No name",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
columns: 4
|
|
||||||
show_name: false
|
show_name: false
|
||||||
entities:
|
entities:
|
||||||
- device_tracker.demo_paulus
|
- device_tracker.demo_paulus
|
||||||
@@ -126,10 +119,9 @@ const CONFIGS = [
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "No state labels",
|
heading: "No state",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
columns: 4
|
|
||||||
show_state: false
|
show_state: false
|
||||||
entities:
|
entities:
|
||||||
- device_tracker.demo_paulus
|
- device_tracker.demo_paulus
|
||||||
@@ -142,10 +134,9 @@ const CONFIGS = [
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "No names and no state labels",
|
heading: "No name and no state",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
columns: 4
|
|
||||||
show_name: false
|
show_name: false
|
||||||
show_state: false
|
show_state: false
|
||||||
entities:
|
entities:
|
||||||
@@ -159,24 +150,47 @@ const CONFIGS = [
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "Custom name + custom icon",
|
heading: "Custom name, custom icon",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
columns: 4
|
|
||||||
entities:
|
entities:
|
||||||
- entity: device_tracker.demo_paulus
|
- entity: device_tracker.demo_paulus
|
||||||
name: ¯\\_(ツ)_/¯
|
name: ¯\\_(ツ)_/¯
|
||||||
icon: mdi:home-assistant
|
icon: mdi:home-assistant
|
||||||
- entity: media_player.living_room
|
- media_player.living_room
|
||||||
name: ¯\\_(ツ)_/¯
|
- sun.sun
|
||||||
icon: mdi:home-assistant
|
- cover.kitchen_window
|
||||||
|
- entity: light.kitchen_lights
|
||||||
|
icon: mdi:alarm-light
|
||||||
|
- lock.kitchen_door
|
||||||
|
- light.ceiling_lights
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Custom tap action",
|
||||||
|
config: `
|
||||||
|
- type: glance
|
||||||
|
entities:
|
||||||
|
- entity: lock.kitchen_door
|
||||||
|
tap_action:
|
||||||
|
type: toggle
|
||||||
|
- entity: light.ceiling_lights
|
||||||
|
tap_action:
|
||||||
|
action: call-service
|
||||||
|
service: light.turn_on
|
||||||
|
service_data:
|
||||||
|
entity_id: light.ceiling_lights
|
||||||
|
- device_tracker.demo_paulus
|
||||||
|
- media_player.living_room
|
||||||
|
- sun.sun
|
||||||
|
- cover.kitchen_window
|
||||||
|
- light.kitchen_lights
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "Selectively hidden name",
|
heading: "Selectively hidden name",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
columns: 4
|
|
||||||
entities:
|
entities:
|
||||||
- device_tracker.demo_paulus
|
- device_tracker.demo_paulus
|
||||||
- entity: media_player.living_room
|
- entity: media_player.living_room
|
||||||
@@ -185,51 +199,45 @@ const CONFIGS = [
|
|||||||
- entity: cover.kitchen_window
|
- entity: cover.kitchen_window
|
||||||
name:
|
name:
|
||||||
- light.kitchen_lights
|
- light.kitchen_lights
|
||||||
- entity: lock.kitchen_door
|
|
||||||
name:
|
|
||||||
- light.ceiling_lights
|
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "Custom tap action",
|
heading: "Primary theme",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
columns: 4
|
theming: primary
|
||||||
entities:
|
entities:
|
||||||
- entity: lock.kitchen_door
|
- device_tracker.demo_paulus
|
||||||
name: Custom
|
- media_player.living_room
|
||||||
tap_action:
|
- sun.sun
|
||||||
type: toggle
|
- cover.kitchen_window
|
||||||
- entity: light.ceiling_lights
|
- light.kitchen_lights
|
||||||
name: Custom
|
- lock.kitchen_door
|
||||||
tap_action:
|
- light.ceiling_lights
|
||||||
action: call-service
|
|
||||||
service: light.turn_on
|
|
||||||
service_data:
|
|
||||||
entity_id: light.ceiling_lights
|
|
||||||
- entity: sun.sun
|
|
||||||
name: Regular
|
|
||||||
- entity: light.kitchen_lights
|
|
||||||
name: Regular
|
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-glance-card")
|
class DemoPicEntity extends PolymerElement {
|
||||||
class DemoGlanceEntity extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.updateTranslations("lovelace", "en");
|
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-hui-glance-card", DemoGlanceEntity);
|
customElements.define("demo-hui-glance-card", DemoPicEntity);
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
import { customElement, html, LitElement, TemplateResult } from "lit-element";
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
|
/* eslint-plugin-disable lit */
|
||||||
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
@@ -35,10 +37,18 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-iframe-card")
|
class DemoIframe extends PolymerElement {
|
||||||
class DemoIframe extends LitElement {
|
static get template() {
|
||||||
protected render(): TemplateResult {
|
return html` <demo-cards configs="[[_configs]]"></demo-cards> `;
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { getEntity } from "../../../src/fake_data/entity";
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
@@ -68,19 +63,24 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-light-card")
|
class DemoLightEntity extends PolymerElement {
|
||||||
class DemoLightEntity extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.updateTranslations("lovelace", "en");
|
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { getEntity } from "../../../src/fake_data/entity";
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
@@ -166,19 +161,24 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-map-card")
|
class DemoMap extends PolymerElement {
|
||||||
class DemoMap extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.updateTranslations("lovelace", "en");
|
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { mockTemplate } from "../../../demo/src/stubs/template";
|
import { mockTemplate } from "../../../demo/src/stubs/template";
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
@@ -259,19 +254,23 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-markdown-card")
|
class DemoMarkdown extends PolymerElement {
|
||||||
class DemoMarkdown extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
hass.updateTranslations(null, "en");
|
type: Object,
|
||||||
hass.updateTranslations("lovelace", "en");
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
mockTemplate(hass);
|
mockTemplate(hass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
import { createMediaPlayerEntities } from "../data/media_players";
|
import { createMediaPlayerEntities } from "../data/media_players";
|
||||||
@@ -151,33 +146,28 @@ const CONFIGS = [
|
|||||||
entity: media_player.receiver_off
|
entity: media_player.receiver_off
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
heading: "Grid Full Size",
|
|
||||||
config: `
|
|
||||||
- type: grid
|
|
||||||
columns: 1
|
|
||||||
cards:
|
|
||||||
- type: media-control
|
|
||||||
entity: media_player.music_paused
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-media-control-card")
|
class DemoHuiMediControlCard extends PolymerElement {
|
||||||
class DemoHuiMediaControlCard extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.updateTranslations("lovelace", "en");
|
|
||||||
hass.addEntities(createMediaPlayerEntities());
|
hass.addEntities(createMediaPlayerEntities());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-hui-media-control-card", DemoHuiMediaControlCard);
|
customElements.define("demo-hui-media-control-card", DemoHuiMediControlCard);
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
import { createMediaPlayerEntities } from "../data/media_players";
|
import { createMediaPlayerEntities } from "../data/media_players";
|
||||||
@@ -31,9 +26,9 @@ const CONFIGS = [
|
|||||||
- entity: media_player.android_cast
|
- entity: media_player.android_cast
|
||||||
name: Screen casting
|
name: Screen casting
|
||||||
- entity: media_player.image_display
|
- entity: media_player.image_display
|
||||||
name: Digital Picture Frame
|
name: Digital Picture Frame
|
||||||
- entity: media_player.sonos_idle
|
- entity: media_player.sonos_idle
|
||||||
name: Sonos Idle
|
name: Sonos Idle
|
||||||
- entity: media_player.idle_browse_media
|
- entity: media_player.idle_browse_media
|
||||||
name: Idle waiting for Browse Media
|
name: Idle waiting for Browse Media
|
||||||
- entity: media_player.theater_off
|
- entity: media_player.theater_off
|
||||||
@@ -43,7 +38,7 @@ const CONFIGS = [
|
|||||||
- entity: media_player.theater_off_static
|
- entity: media_player.theater_off_static
|
||||||
name: Player Off (cannot be switched on)
|
name: Player Off (cannot be switched on)
|
||||||
- entity: media_player.theater_on_static
|
- entity: media_player.theater_on_static
|
||||||
name: Player On (cannot be switched off)
|
name: Player On (cannot be switched off)
|
||||||
- entity: media_player.idle
|
- entity: media_player.idle
|
||||||
name: Player Idle
|
name: Player Idle
|
||||||
- entity: media_player.playing
|
- entity: media_player.playing
|
||||||
@@ -60,21 +55,26 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-media-player-row")
|
class DemoHuiMediaPlayerRows extends PolymerElement {
|
||||||
class DemoHuiMediaPlayerRow extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.updateTranslations("lovelace", "en");
|
|
||||||
hass.addEntities(createMediaPlayerEntities());
|
hass.addEntities(createMediaPlayerEntities());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-hui-media-player-row", DemoHuiMediaPlayerRow);
|
customElements.define("demo-hui-media-player-rows", DemoHuiMediaPlayerRows);
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { getEntity } from "../../../src/fake_data/entity";
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
@@ -130,21 +125,26 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-picture-elements-card")
|
class DemoPicElements extends PolymerElement {
|
||||||
class DemoPictureElements extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.updateTranslations("lovelace", "en");
|
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-hui-picture-elements-card", DemoPictureElements);
|
customElements.define("demo-hui-picture-elements-card", DemoPicElements);
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { getEntity } from "../../../src/fake_data/entity";
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
@@ -85,21 +80,26 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-picture-entity-card")
|
class DemoPicEntity extends PolymerElement {
|
||||||
class DemoPictureEntity extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.updateTranslations("lovelace", "en");
|
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-hui-picture-entity-card", DemoPictureEntity);
|
customElements.define("demo-hui-picture-entity-card", DemoPicEntity);
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { getEntity } from "../../../src/fake_data/entity";
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
@@ -126,21 +121,26 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-picture-glance-card")
|
class DemoPicGlance extends PolymerElement {
|
||||||
class DemoPictureGlance extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.updateTranslations("lovelace", "en");
|
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-hui-picture-glance-card", DemoPictureGlance);
|
customElements.define("demo-hui-picture-glance-card", DemoPicGlance);
|
||||||
|
@@ -1,55 +0,0 @@
|
|||||||
import {
|
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
|
||||||
import "../components/demo-cards";
|
|
||||||
import { createPlantEntities } from "../data/plants";
|
|
||||||
|
|
||||||
const CONFIGS = [
|
|
||||||
{
|
|
||||||
heading: "Basic example",
|
|
||||||
config: `
|
|
||||||
- type: plant-status
|
|
||||||
entity: plant.lemon_tree
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
heading: "Problem (too bright) + low battery",
|
|
||||||
config: `
|
|
||||||
- type: plant-status
|
|
||||||
entity: plant.apple_tree
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
heading: "With picture + multiple problems",
|
|
||||||
config: `
|
|
||||||
- type: plant-status
|
|
||||||
entity: plant.sunflowers
|
|
||||||
name: Sunflowers Name Overwrite
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
@customElement("demo-hui-plant-card")
|
|
||||||
export class DemoPlantEntity extends LitElement {
|
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
|
||||||
super.firstUpdated(changedProperties);
|
|
||||||
const hass = provideHass(this._demoRoot);
|
|
||||||
hass.updateTranslations(null, "en");
|
|
||||||
hass.updateTranslations("lovelace", "en");
|
|
||||||
hass.addEntities(createPlantEntities());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
customElements.define("demo-hui-plant-card", DemoPlantEntity);
|
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
|
|
||||||
@@ -25,19 +20,24 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-shopping-list-card")
|
class DemoShoppingListEntity extends PolymerElement {
|
||||||
class DemoShoppingListEntity extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.updateTranslations("lovelace", "en");
|
|
||||||
|
|
||||||
hass.mockAPI("shopping_list", () => [
|
hass.mockAPI("shopping_list", () => [
|
||||||
{ name: "list", id: 1, complete: false },
|
{ name: "list", id: 1, complete: false },
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { mockHistory } from "../../../demo/src/stubs/history";
|
import { mockHistory } from "../../../demo/src/stubs/history";
|
||||||
import { getEntity } from "../../../src/fake_data/entity";
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
@@ -137,19 +132,24 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-stack-card")
|
class DemoStack extends PolymerElement {
|
||||||
class DemoStack extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.updateTranslations("lovelace", "en");
|
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
mockHistory(hass);
|
mockHistory(hass);
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { getEntity } from "../../../src/fake_data/entity";
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
@@ -79,19 +74,24 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-hui-thermostat-card")
|
class DemoThermostatEntity extends PolymerElement {
|
||||||
class DemoThermostatEntity extends LitElement {
|
static get template() {
|
||||||
@query("#demos") private _demoRoot!: HTMLElement;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.updateTranslations("lovelace", "en");
|
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,29 +1,12 @@
|
|||||||
import {
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
customElement,
|
/* eslint-plugin-disable lit */
|
||||||
html,
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
LitElement,
|
|
||||||
property,
|
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import "../../../src/components/ha-card";
|
import "../../../src/components/ha-card";
|
||||||
import {
|
import { SUPPORT_BRIGHTNESS } from "../../../src/data/light";
|
||||||
SUPPORT_BRIGHTNESS,
|
|
||||||
SUPPORT_COLOR,
|
|
||||||
SUPPORT_COLOR_TEMP,
|
|
||||||
SUPPORT_EFFECT,
|
|
||||||
SUPPORT_FLASH,
|
|
||||||
SUPPORT_TRANSITION,
|
|
||||||
SUPPORT_WHITE_VALUE,
|
|
||||||
} from "../../../src/data/light";
|
|
||||||
import "../../../src/dialogs/more-info/more-info-content";
|
|
||||||
import { getEntity } from "../../../src/fake_data/entity";
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
import {
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
MockHomeAssistant,
|
|
||||||
provideHass,
|
|
||||||
} from "../../../src/fake_data/provide_hass";
|
|
||||||
import "../components/demo-more-infos";
|
import "../components/demo-more-infos";
|
||||||
|
import "../../../src/dialogs/more-info/more-info-content";
|
||||||
|
|
||||||
const ENTITIES = [
|
const ENTITIES = [
|
||||||
getEntity("light", "bed_light", "on", {
|
getEntity("light", "bed_light", "on", {
|
||||||
@@ -31,52 +14,38 @@ const ENTITIES = [
|
|||||||
}),
|
}),
|
||||||
getEntity("light", "kitchen_light", "on", {
|
getEntity("light", "kitchen_light", "on", {
|
||||||
friendly_name: "Brightness Light",
|
friendly_name: "Brightness Light",
|
||||||
brightness: 200,
|
brightness: 80,
|
||||||
supported_features: SUPPORT_BRIGHTNESS,
|
supported_features: SUPPORT_BRIGHTNESS,
|
||||||
}),
|
}),
|
||||||
getEntity("light", "color_temperature_light", "on", {
|
|
||||||
friendly_name: "White Color Temperature Light",
|
|
||||||
brightness: 128,
|
|
||||||
color_temp: 75,
|
|
||||||
min_mireds: 30,
|
|
||||||
max_mireds: 150,
|
|
||||||
supported_features: SUPPORT_BRIGHTNESS + SUPPORT_COLOR_TEMP,
|
|
||||||
}),
|
|
||||||
getEntity("light", "color_effectslight", "on", {
|
|
||||||
friendly_name: "Color Effets Light",
|
|
||||||
brightness: 255,
|
|
||||||
hs_color: [30, 100],
|
|
||||||
white_value: 36,
|
|
||||||
supported_features:
|
|
||||||
SUPPORT_BRIGHTNESS +
|
|
||||||
SUPPORT_EFFECT +
|
|
||||||
SUPPORT_FLASH +
|
|
||||||
SUPPORT_COLOR +
|
|
||||||
SUPPORT_TRANSITION +
|
|
||||||
SUPPORT_WHITE_VALUE,
|
|
||||||
effect_list: ["random", "colorloop"],
|
|
||||||
}),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-more-info-light")
|
class DemoMoreInfoLight extends PolymerElement {
|
||||||
class DemoMoreInfoLight extends LitElement {
|
static get template() {
|
||||||
@property() public hass!: MockHomeAssistant;
|
|
||||||
|
|
||||||
@query("demo-more-infos") private _demoRoot!: HTMLElement;
|
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`
|
return html`
|
||||||
<demo-more-infos
|
<demo-more-infos
|
||||||
.hass=${this.hass}
|
hass="[[hass]]"
|
||||||
.entities=${ENTITIES.map((ent) => ent.entityId)}
|
entities="[[_entities]]"
|
||||||
></demo-more-infos>
|
></demo-more-infos>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
static get properties() {
|
||||||
super.firstUpdated(changedProperties);
|
return {
|
||||||
const hass = provideHass(this._demoRoot);
|
_entities: {
|
||||||
hass.updateTranslations(null, "en");
|
type: Array,
|
||||||
|
value: ENTITIES.map((ent) => ent.entityId),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
this._setupDemo();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _setupDemo() {
|
||||||
|
const hass = provideHass(this);
|
||||||
|
await hass.updateTranslations(null, "en");
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
import "@material/mwc-button";
|
import "@material/mwc-button";
|
||||||
import { customElement, html, LitElement, TemplateResult } from "lit-element";
|
import { html, LitElement, TemplateResult } from "lit-element";
|
||||||
import "../../../src/components/ha-card";
|
import "../../../src/components/ha-card";
|
||||||
import { ActionHandlerEvent } from "../../../src/data/lovelace";
|
import { ActionHandlerEvent } from "../../../src/data/lovelace";
|
||||||
import { actionHandler } from "../../../src/panels/lovelace/common/directives/action-handler-directive";
|
import { actionHandler } from "../../../src/panels/lovelace/common/directives/action-handler-directive";
|
||||||
|
|
||||||
@customElement("demo-util-long-press")
|
|
||||||
export class DemoUtilLongPress extends LitElement {
|
export class DemoUtilLongPress extends LitElement {
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
return html`
|
return html`
|
||||||
@@ -21,7 +20,7 @@ export class DemoUtilLongPress extends LitElement {
|
|||||||
|
|
||||||
<textarea></textarea>
|
<textarea></textarea>
|
||||||
|
|
||||||
<div>Try pressing and scrolling too!</div>
|
<div>(try pressing and scrolling too!)</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
@@ -63,3 +62,5 @@ export class DemoUtilLongPress extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
customElements.define("demo-util-long-press", DemoUtilLongPress);
|
||||||
|
@@ -14,6 +14,8 @@ import "../../src/styles/polymer-ha-style";
|
|||||||
// eslint-disable-next-line import/extensions
|
// eslint-disable-next-line import/extensions
|
||||||
import { DEMOS } from "../build/import-demos";
|
import { DEMOS } from "../build/import-demos";
|
||||||
|
|
||||||
|
const fixPath = (path) => path.substr(2, path.length - 5);
|
||||||
|
|
||||||
class HaGallery extends PolymerElement {
|
class HaGallery extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
return html`
|
return html`
|
||||||
|
@@ -12,7 +12,6 @@ import {
|
|||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { html, TemplateResult } from "lit-html";
|
import { html, TemplateResult } from "lit-html";
|
||||||
import { atLeastVersion } from "../../../src/common/config/version";
|
import { atLeastVersion } from "../../../src/common/config/version";
|
||||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
|
||||||
import "../../../src/common/search/search-input";
|
import "../../../src/common/search/search-input";
|
||||||
import "../../../src/components/ha-button-menu";
|
import "../../../src/components/ha-button-menu";
|
||||||
import "../../../src/components/ha-svg-icon";
|
import "../../../src/components/ha-svg-icon";
|
||||||
@@ -23,7 +22,6 @@ import {
|
|||||||
reloadHassioAddons,
|
reloadHassioAddons,
|
||||||
} from "../../../src/data/hassio/addon";
|
} from "../../../src/data/hassio/addon";
|
||||||
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
|
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
|
||||||
import { fetchHassioSupervisorInfo } from "../../../src/data/hassio/supervisor";
|
|
||||||
import "../../../src/layouts/hass-loading-screen";
|
import "../../../src/layouts/hass-loading-screen";
|
||||||
import "../../../src/layouts/hass-tabs-subpage";
|
import "../../../src/layouts/hass-tabs-subpage";
|
||||||
import { HomeAssistant, Route } from "../../../src/types";
|
import { HomeAssistant, Route } from "../../../src/types";
|
||||||
@@ -192,11 +190,7 @@ class HassioAddonStore extends LitElement {
|
|||||||
|
|
||||||
private async _loadData() {
|
private async _loadData() {
|
||||||
try {
|
try {
|
||||||
const [addonsInfo, supervisor] = await Promise.all([
|
const addonsInfo = await fetchHassioAddonsInfo(this.hass);
|
||||||
fetchHassioAddonsInfo(this.hass),
|
|
||||||
fetchHassioSupervisorInfo(this.hass),
|
|
||||||
]);
|
|
||||||
fireEvent(this, "supervisor-update", { supervisor });
|
|
||||||
this._repos = addonsInfo.repositories;
|
this._repos = addonsInfo.repositories;
|
||||||
this._repos.sort(sortRepos);
|
this._repos.sort(sortRepos);
|
||||||
this._addons = addonsInfo.addons;
|
this._addons = addonsInfo.addons;
|
||||||
|
@@ -7,14 +7,13 @@ import {
|
|||||||
CSSResult,
|
CSSResult,
|
||||||
customElement,
|
customElement,
|
||||||
html,
|
html,
|
||||||
internalProperty,
|
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
|
internalProperty,
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import "web-animations-js/web-animations-next-lite.min";
|
import "web-animations-js/web-animations-next-lite.min";
|
||||||
import "../../../../src/components/buttons/ha-progress-button";
|
|
||||||
import "../../../../src/components/ha-card";
|
import "../../../../src/components/ha-card";
|
||||||
import {
|
import {
|
||||||
HassioAddonDetails,
|
HassioAddonDetails,
|
||||||
@@ -29,6 +28,7 @@ import { haStyle } from "../../../../src/resources/styles";
|
|||||||
import { HomeAssistant } from "../../../../src/types";
|
import { HomeAssistant } from "../../../../src/types";
|
||||||
import { suggestAddonRestart } from "../../dialogs/suggestAddonRestart";
|
import { suggestAddonRestart } from "../../dialogs/suggestAddonRestart";
|
||||||
import { hassioStyle } from "../../resources/hassio-style";
|
import { hassioStyle } from "../../resources/hassio-style";
|
||||||
|
import "../../../../src/components/buttons/ha-progress-button";
|
||||||
|
|
||||||
@customElement("hassio-addon-audio")
|
@customElement("hassio-addon-audio")
|
||||||
class HassioAddonAudio extends LitElement {
|
class HassioAddonAudio extends LitElement {
|
||||||
|
@@ -7,11 +7,11 @@ import {
|
|||||||
property,
|
property,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import "../../../../src/components/ha-circular-progress";
|
|
||||||
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||||
import { haStyle } from "../../../../src/resources/styles";
|
import { haStyle } from "../../../../src/resources/styles";
|
||||||
import { HomeAssistant } from "../../../../src/types";
|
import { HomeAssistant } from "../../../../src/types";
|
||||||
import { hassioStyle } from "../../resources/hassio-style";
|
import { hassioStyle } from "../../resources/hassio-style";
|
||||||
|
import "../../../../src/components/ha-circular-progress";
|
||||||
import "./hassio-addon-audio";
|
import "./hassio-addon-audio";
|
||||||
import "./hassio-addon-config";
|
import "./hassio-addon-config";
|
||||||
import "./hassio-addon-network";
|
import "./hassio-addon-network";
|
||||||
@@ -26,41 +26,28 @@ class HassioAddonConfigDashboard extends LitElement {
|
|||||||
if (!this.addon) {
|
if (!this.addon) {
|
||||||
return html`<ha-circular-progress active></ha-circular-progress>`;
|
return html`<ha-circular-progress active></ha-circular-progress>`;
|
||||||
}
|
}
|
||||||
const hasOptions =
|
|
||||||
this.addon.options && Object.keys(this.addon.options).length;
|
|
||||||
const hasSchema =
|
|
||||||
this.addon.schema && Object.keys(this.addon.schema).length;
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="content">
|
<div class="content">
|
||||||
${hasOptions || hasSchema || this.addon.network || this.addon.audio
|
<hassio-addon-config
|
||||||
|
.hass=${this.hass}
|
||||||
|
.addon=${this.addon}
|
||||||
|
></hassio-addon-config>
|
||||||
|
${this.addon.network
|
||||||
? html`
|
? html`
|
||||||
${hasOptions || hasSchema
|
<hassio-addon-network
|
||||||
? html`
|
.hass=${this.hass}
|
||||||
<hassio-addon-config
|
.addon=${this.addon}
|
||||||
.hass=${this.hass}
|
></hassio-addon-network>
|
||||||
.addon=${this.addon}
|
|
||||||
></hassio-addon-config>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
${this.addon.network
|
|
||||||
? html`
|
|
||||||
<hassio-addon-network
|
|
||||||
.hass=${this.hass}
|
|
||||||
.addon=${this.addon}
|
|
||||||
></hassio-addon-network>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
${this.addon.audio
|
|
||||||
? html`
|
|
||||||
<hassio-addon-audio
|
|
||||||
.hass=${this.hass}
|
|
||||||
.addon=${this.addon}
|
|
||||||
></hassio-addon-audio>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
`
|
`
|
||||||
: "This add-on does not expose configuration for you to mess with.... 👋"}
|
: ""}
|
||||||
|
${this.addon.audio
|
||||||
|
? html`
|
||||||
|
<hassio-addon-audio
|
||||||
|
.hass=${this.hass}
|
||||||
|
.addon=${this.addon}
|
||||||
|
></hassio-addon-audio>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,4 @@
|
|||||||
import "@material/mwc-button";
|
import "@material/mwc-button";
|
||||||
import { ActionDetail } from "@material/mwc-list";
|
|
||||||
import "@material/mwc-list/mwc-list-item";
|
|
||||||
import { mdiDotsVertical } from "@mdi/js";
|
|
||||||
import "@polymer/iron-autogrow-textarea/iron-autogrow-textarea";
|
import "@polymer/iron-autogrow-textarea/iron-autogrow-textarea";
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
@@ -17,9 +14,7 @@ import {
|
|||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||||
import "../../../../src/components/buttons/ha-progress-button";
|
import "../../../../src/components/buttons/ha-progress-button";
|
||||||
import "../../../../src/components/ha-button-menu";
|
|
||||||
import "../../../../src/components/ha-card";
|
import "../../../../src/components/ha-card";
|
||||||
import "../../../../src/components/ha-form/ha-form";
|
|
||||||
import "../../../../src/components/ha-yaml-editor";
|
import "../../../../src/components/ha-yaml-editor";
|
||||||
import type { HaYamlEditor } from "../../../../src/components/ha-yaml-editor";
|
import type { HaYamlEditor } from "../../../../src/components/ha-yaml-editor";
|
||||||
import {
|
import {
|
||||||
@@ -34,67 +29,35 @@ import type { HomeAssistant } from "../../../../src/types";
|
|||||||
import { suggestAddonRestart } from "../../dialogs/suggestAddonRestart";
|
import { suggestAddonRestart } from "../../dialogs/suggestAddonRestart";
|
||||||
import { hassioStyle } from "../../resources/hassio-style";
|
import { hassioStyle } from "../../resources/hassio-style";
|
||||||
|
|
||||||
const SUPPORTED_UI_TYPES = ["string", "select", "boolean", "integer", "float"];
|
|
||||||
|
|
||||||
@customElement("hassio-addon-config")
|
@customElement("hassio-addon-config")
|
||||||
class HassioAddonConfig extends LitElement {
|
class HassioAddonConfig extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
||||||
|
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@internalProperty() private _error?: string;
|
||||||
|
|
||||||
@property({ type: Boolean }) private _configHasChanged = false;
|
@property({ type: Boolean }) private _configHasChanged = false;
|
||||||
|
|
||||||
@property({ type: Boolean }) private _valid = true;
|
@property({ type: Boolean }) private _valid = true;
|
||||||
|
|
||||||
@internalProperty() private _canShowSchema = false;
|
@query("ha-yaml-editor", true) private _editor!: HaYamlEditor;
|
||||||
|
|
||||||
@internalProperty() private _error?: string;
|
|
||||||
|
|
||||||
@internalProperty() private _options?: Record<string, unknown>;
|
|
||||||
|
|
||||||
@internalProperty() private _yamlMode = false;
|
|
||||||
|
|
||||||
@query("ha-yaml-editor") private _editor?: HaYamlEditor;
|
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
return html`
|
return html`
|
||||||
<h1>${this.addon.name}</h1>
|
<h1>${this.addon.name}</h1>
|
||||||
<ha-card>
|
<ha-card header="Configuration">
|
||||||
<div class="header">
|
|
||||||
<h2>Configuration</h2>
|
|
||||||
<div class="card-menu">
|
|
||||||
<ha-button-menu corner="BOTTOM_START" @action=${this._handleAction}>
|
|
||||||
<mwc-icon-button slot="trigger">
|
|
||||||
<ha-svg-icon .path=${mdiDotsVertical}></ha-svg-icon>
|
|
||||||
</mwc-icon-button>
|
|
||||||
<mwc-list-item .disabled=${!this._canShowSchema}>
|
|
||||||
${this._yamlMode ? "Edit in UI" : "Edit in YAML"}
|
|
||||||
</mwc-list-item>
|
|
||||||
<mwc-list-item class="warning">
|
|
||||||
Reset to defaults
|
|
||||||
</mwc-list-item>
|
|
||||||
</ha-button-menu>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
${!this._yamlMode && this._canShowSchema && this.addon.schema
|
<ha-yaml-editor
|
||||||
? html`<ha-form
|
@value-changed=${this._configChanged}
|
||||||
.data=${this._options!}
|
></ha-yaml-editor>
|
||||||
@value-changed=${this._configChanged}
|
|
||||||
.schema=${this.addon.schema}
|
|
||||||
></ha-form>`
|
|
||||||
: html` <ha-yaml-editor
|
|
||||||
@value-changed=${this._configChanged}
|
|
||||||
></ha-yaml-editor>`}
|
|
||||||
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
|
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
|
||||||
${!this._yamlMode ||
|
${this._valid ? "" : html` <div class="errors">Invalid YAML</div> `}
|
||||||
(this._canShowSchema && this.addon.schema) ||
|
|
||||||
this._valid
|
|
||||||
? ""
|
|
||||||
: html` <div class="errors">Invalid YAML</div> `}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
|
<ha-progress-button class="warning" @click=${this._resetTapped}>
|
||||||
|
Reset to defaults
|
||||||
|
</ha-progress-button>
|
||||||
<ha-progress-button
|
<ha-progress-button
|
||||||
@click=${this._saveTapped}
|
@click=${this._saveTapped}
|
||||||
.disabled=${!this._configHasChanged || !this._valid}
|
.disabled=${!this._configHasChanged || !this._valid}
|
||||||
@@ -106,55 +69,16 @@ class HassioAddonConfig extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProps) {
|
|
||||||
super.firstUpdated(changedProps);
|
|
||||||
this._canShowSchema = !this.addon.schema.find(
|
|
||||||
// @ts-ignore
|
|
||||||
(entry) => !SUPPORTED_UI_TYPES.includes(entry.type) || entry.multiple
|
|
||||||
);
|
|
||||||
this._yamlMode = !this._canShowSchema;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected updated(changedProperties: PropertyValues): void {
|
protected updated(changedProperties: PropertyValues): void {
|
||||||
if (changedProperties.has("addon")) {
|
|
||||||
this._options = { ...this.addon.options };
|
|
||||||
}
|
|
||||||
super.updated(changedProperties);
|
super.updated(changedProperties);
|
||||||
if (
|
if (changedProperties.has("addon")) {
|
||||||
changedProperties.has("_yamlMode") ||
|
this._editor.setValue(this.addon.options);
|
||||||
changedProperties.has("_options")
|
|
||||||
) {
|
|
||||||
if (this._yamlMode) {
|
|
||||||
const editor = this._editor;
|
|
||||||
if (editor) {
|
|
||||||
editor.setValue(this._options!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _handleAction(ev: CustomEvent<ActionDetail>) {
|
|
||||||
switch (ev.detail.index) {
|
|
||||||
case 0:
|
|
||||||
this._yamlMode = !this._yamlMode;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
this._resetTapped(ev);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _configChanged(ev): void {
|
private _configChanged(ev): void {
|
||||||
if (this.addon.schema && this._canShowSchema && !this._yamlMode) {
|
this._configHasChanged = true;
|
||||||
this._valid = true;
|
this._valid = ev.detail.isValid;
|
||||||
this._configHasChanged = true;
|
|
||||||
} else {
|
|
||||||
this._configHasChanged = true;
|
|
||||||
this._valid = ev.detail.isValid;
|
|
||||||
}
|
|
||||||
if (this._valid) {
|
|
||||||
this._options! = ev.detail.value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _resetTapped(ev: CustomEvent): Promise<void> {
|
private async _resetTapped(ev: CustomEvent): Promise<void> {
|
||||||
@@ -198,12 +122,18 @@ class HassioAddonConfig extends LitElement {
|
|||||||
const button = ev.currentTarget as any;
|
const button = ev.currentTarget as any;
|
||||||
button.progress = true;
|
button.progress = true;
|
||||||
|
|
||||||
|
let data: HassioAddonSetOptionParams;
|
||||||
this._error = undefined;
|
this._error = undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await setHassioAddonOption(this.hass, this.addon.slug, {
|
data = {
|
||||||
options: this._options!,
|
options: this._editor.value,
|
||||||
});
|
};
|
||||||
|
} catch (err) {
|
||||||
|
this._error = err;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await setHassioAddonOption(this.hass, this.addon.slug, data);
|
||||||
this._configHasChanged = false;
|
this._configHasChanged = false;
|
||||||
const eventdata = {
|
const eventdata = {
|
||||||
success: true,
|
success: true,
|
||||||
@@ -248,29 +178,6 @@ class HassioAddonConfig extends LitElement {
|
|||||||
.syntaxerror {
|
.syntaxerror {
|
||||||
color: var(--error-color);
|
color: var(--error-color);
|
||||||
}
|
}
|
||||||
.card-menu {
|
|
||||||
float: right;
|
|
||||||
z-index: 3;
|
|
||||||
--mdc-theme-text-primary-on-background: var(--primary-text-color);
|
|
||||||
}
|
|
||||||
mwc-list-item[disabled] {
|
|
||||||
--mdc-theme-text-primary-on-background: var(--disabled-text-color);
|
|
||||||
}
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
.header h2 {
|
|
||||||
color: var(--ha-card-header-color, --primary-text-color);
|
|
||||||
font-family: var(--ha-card-header-font-family, inherit);
|
|
||||||
font-size: var(--ha-card-header-font-size, 24px);
|
|
||||||
letter-spacing: -0.012em;
|
|
||||||
line-height: 48px;
|
|
||||||
padding: 12px 16px 16px;
|
|
||||||
display: block;
|
|
||||||
margin-block: 0px;
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@@ -14,12 +14,12 @@ import {
|
|||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import "../../../src/components/ha-circular-progress";
|
|
||||||
import {
|
import {
|
||||||
fetchHassioAddonInfo,
|
fetchHassioAddonInfo,
|
||||||
HassioAddonDetails,
|
HassioAddonDetails,
|
||||||
} from "../../../src/data/hassio/addon";
|
} from "../../../src/data/hassio/addon";
|
||||||
import "../../../src/layouts/hass-tabs-subpage";
|
import "../../../src/layouts/hass-tabs-subpage";
|
||||||
|
import "../../../src/components/ha-circular-progress";
|
||||||
import type { PageNavigation } from "../../../src/layouts/hass-tabs-subpage";
|
import type { PageNavigation } from "../../../src/layouts/hass-tabs-subpage";
|
||||||
import { haStyle } from "../../../src/resources/styles";
|
import { haStyle } from "../../../src/resources/styles";
|
||||||
import { HomeAssistant, Route } from "../../../src/types";
|
import { HomeAssistant, Route } from "../../../src/types";
|
||||||
|
@@ -7,8 +7,8 @@ import {
|
|||||||
property,
|
property,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import "../../../../src/components/ha-circular-progress";
|
|
||||||
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||||
|
import "../../../../src/components/ha-circular-progress";
|
||||||
import { haStyle } from "../../../../src/resources/styles";
|
import { haStyle } from "../../../../src/resources/styles";
|
||||||
import { HomeAssistant } from "../../../../src/types";
|
import { HomeAssistant } from "../../../../src/types";
|
||||||
import { hassioStyle } from "../../resources/hassio-style";
|
import { hassioStyle } from "../../resources/hassio-style";
|
||||||
|
@@ -49,20 +49,14 @@ import {
|
|||||||
uninstallHassioAddon,
|
uninstallHassioAddon,
|
||||||
validateHassioAddonOption,
|
validateHassioAddonOption,
|
||||||
} from "../../../../src/data/hassio/addon";
|
} from "../../../../src/data/hassio/addon";
|
||||||
import {
|
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
|
||||||
extractApiErrorMessage,
|
|
||||||
fetchHassioStats,
|
|
||||||
HassioStats,
|
|
||||||
} from "../../../../src/data/hassio/common";
|
|
||||||
import {
|
import {
|
||||||
showAlertDialog,
|
showAlertDialog,
|
||||||
showConfirmationDialog,
|
showConfirmationDialog,
|
||||||
} from "../../../../src/dialogs/generic/show-dialog-box";
|
} from "../../../../src/dialogs/generic/show-dialog-box";
|
||||||
import { haStyle } from "../../../../src/resources/styles";
|
import { haStyle } from "../../../../src/resources/styles";
|
||||||
import { HomeAssistant } from "../../../../src/types";
|
import { HomeAssistant } from "../../../../src/types";
|
||||||
import { bytesToString } from "../../../../src/util/bytes-to-string";
|
|
||||||
import "../../components/hassio-card-content";
|
import "../../components/hassio-card-content";
|
||||||
import "../../components/supervisor-metric";
|
|
||||||
import { showHassioMarkdownDialog } from "../../dialogs/markdown/show-dialog-hassio-markdown";
|
import { showHassioMarkdownDialog } from "../../dialogs/markdown/show-dialog-hassio-markdown";
|
||||||
import { hassioStyle } from "../../resources/hassio-style";
|
import { hassioStyle } from "../../resources/hassio-style";
|
||||||
|
|
||||||
@@ -75,7 +69,7 @@ const STAGE_ICON = {
|
|||||||
const PERMIS_DESC = {
|
const PERMIS_DESC = {
|
||||||
stage: {
|
stage: {
|
||||||
title: "Add-on Stage",
|
title: "Add-on Stage",
|
||||||
description: `Add-ons can have one of three stages:\n\n<ha-svg-icon path="${STAGE_ICON.stable}"></ha-svg-icon> **Stable**: These are add-ons ready to be used in production.\n\n<ha-svg-icon path="${STAGE_ICON.experimental}"></ha-svg-icon> **Experimental**: These may contain bugs, and may be unfinished.\n\n<ha-svg-icon path="${STAGE_ICON.deprecated}"></ha-svg-icon> **Deprecated**: These add-ons will no longer receive any updates.`,
|
description: `Add-ons can have one of three stages:\n\n<ha-svg-icon .path='${STAGE_ICON.stable}'></ha-svg-icon> **Stable**: These are add-ons ready to be used in production.\n\n<ha-svg-icon .path='${STAGE_ICON.experimental}'></ha-svg-icon> **Experimental**: These may contain bugs, and may be unfinished.\n\n<ha-svg-icon .path='${STAGE_ICON.deprecated}'></ha-svg-icon> **Deprecated**: These add-ons will no longer receive any updates.`,
|
||||||
},
|
},
|
||||||
rating: {
|
rating: {
|
||||||
title: "Add-on Security Rating",
|
title: "Add-on Security Rating",
|
||||||
@@ -137,24 +131,9 @@ class HassioAddonInfo extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
||||||
|
|
||||||
@internalProperty() private _metrics?: HassioStats;
|
|
||||||
|
|
||||||
@internalProperty() private _error?: string;
|
@internalProperty() private _error?: string;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
const metrics = [
|
|
||||||
{
|
|
||||||
description: "Add-on CPU Usage",
|
|
||||||
value: this._metrics?.cpu_percent,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "Add-on RAM Usage",
|
|
||||||
value: this._metrics?.memory_percent,
|
|
||||||
tooltip: `${bytesToString(this._metrics?.memory_usage)}/${bytesToString(
|
|
||||||
this._metrics?.memory_limit
|
|
||||||
)}`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
return html`
|
return html`
|
||||||
${this.addon.update_available
|
${this.addon.update_available
|
||||||
? html`
|
? html`
|
||||||
@@ -258,281 +237,249 @@ class HassioAddonInfo extends LitElement {
|
|||||||
>
|
>
|
||||||
for details.
|
for details.
|
||||||
</div>
|
</div>
|
||||||
<div class="addon-container">
|
${this.addon.logo
|
||||||
<div>
|
? html`
|
||||||
${this.addon.logo
|
<img
|
||||||
? html`
|
class="logo"
|
||||||
<img
|
src="/api/hassio/addons/${this.addon.slug}/logo"
|
||||||
class="logo"
|
/>
|
||||||
src="/api/hassio/addons/${this.addon.slug}/logo"
|
`
|
||||||
/>
|
: ""}
|
||||||
`
|
<div class="security">
|
||||||
: ""}
|
${this.addon.stage !== "stable"
|
||||||
<div class="security">
|
? html` <ha-label-badge
|
||||||
${this.addon.stage !== "stable"
|
|
||||||
? html` <ha-label-badge
|
|
||||||
class=${classMap({
|
|
||||||
yellow: this.addon.stage === "experimental",
|
|
||||||
red: this.addon.stage === "deprecated",
|
|
||||||
})}
|
|
||||||
@click=${this._showMoreInfo}
|
|
||||||
id="stage"
|
|
||||||
label="stage"
|
|
||||||
description=""
|
|
||||||
>
|
|
||||||
<ha-svg-icon
|
|
||||||
.path=${STAGE_ICON[this.addon.stage]}
|
|
||||||
></ha-svg-icon>
|
|
||||||
</ha-label-badge>`
|
|
||||||
: ""}
|
|
||||||
|
|
||||||
<ha-label-badge
|
|
||||||
class=${classMap({
|
class=${classMap({
|
||||||
green: [5, 6].includes(Number(this.addon.rating)),
|
yellow: this.addon.stage === "experimental",
|
||||||
yellow: [3, 4].includes(Number(this.addon.rating)),
|
red: this.addon.stage === "deprecated",
|
||||||
red: [1, 2].includes(Number(this.addon.rating)),
|
|
||||||
})}
|
})}
|
||||||
@click=${this._showMoreInfo}
|
@click=${this._showMoreInfo}
|
||||||
id="rating"
|
id="stage"
|
||||||
.value=${this.addon.rating}
|
label="stage"
|
||||||
label="rating"
|
|
||||||
description=""
|
description=""
|
||||||
></ha-label-badge>
|
>
|
||||||
${this.addon.host_network
|
<ha-svg-icon
|
||||||
? html`
|
.path=${STAGE_ICON[this.addon.stage]}
|
||||||
<ha-label-badge
|
></ha-svg-icon>
|
||||||
@click=${this._showMoreInfo}
|
</ha-label-badge>`
|
||||||
id="host_network"
|
: ""}
|
||||||
label="host"
|
|
||||||
description=""
|
|
||||||
>
|
|
||||||
<ha-svg-icon .path=${mdiNetwork}></ha-svg-icon>
|
|
||||||
</ha-label-badge>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
${this.addon.full_access
|
|
||||||
? html`
|
|
||||||
<ha-label-badge
|
|
||||||
@click=${this._showMoreInfo}
|
|
||||||
id="full_access"
|
|
||||||
label="hardware"
|
|
||||||
description=""
|
|
||||||
>
|
|
||||||
<ha-svg-icon .path=${mdiChip}></ha-svg-icon>
|
|
||||||
</ha-label-badge>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
${this.addon.homeassistant_api
|
|
||||||
? html`
|
|
||||||
<ha-label-badge
|
|
||||||
@click=${this._showMoreInfo}
|
|
||||||
id="homeassistant_api"
|
|
||||||
label="hass"
|
|
||||||
description=""
|
|
||||||
>
|
|
||||||
<ha-svg-icon .path=${mdiHomeAssistant}></ha-svg-icon>
|
|
||||||
</ha-label-badge>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
${this._computeHassioApi
|
|
||||||
? html`
|
|
||||||
<ha-label-badge
|
|
||||||
@click=${this._showMoreInfo}
|
|
||||||
id="hassio_api"
|
|
||||||
label="hassio"
|
|
||||||
.description=${this.addon.hassio_role}
|
|
||||||
>
|
|
||||||
<ha-svg-icon .path=${mdiHomeAssistant}></ha-svg-icon>
|
|
||||||
</ha-label-badge>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
${this.addon.docker_api
|
|
||||||
? html`
|
|
||||||
<ha-label-badge
|
|
||||||
@click=${this._showMoreInfo}
|
|
||||||
id="docker_api"
|
|
||||||
label="docker"
|
|
||||||
description=""
|
|
||||||
>
|
|
||||||
<ha-svg-icon .path=${mdiDocker}></ha-svg-icon>
|
|
||||||
</ha-label-badge>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
${this.addon.host_pid
|
|
||||||
? html`
|
|
||||||
<ha-label-badge
|
|
||||||
@click=${this._showMoreInfo}
|
|
||||||
id="host_pid"
|
|
||||||
label="host pid"
|
|
||||||
description=""
|
|
||||||
>
|
|
||||||
<ha-svg-icon .path=${mdiPound}></ha-svg-icon>
|
|
||||||
</ha-label-badge>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
${this.addon.apparmor
|
|
||||||
? html`
|
|
||||||
<ha-label-badge
|
|
||||||
@click=${this._showMoreInfo}
|
|
||||||
class=${this._computeApparmorClassName}
|
|
||||||
id="apparmor"
|
|
||||||
label="apparmor"
|
|
||||||
description=""
|
|
||||||
>
|
|
||||||
<ha-svg-icon .path=${mdiShield}></ha-svg-icon>
|
|
||||||
</ha-label-badge>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
${this.addon.auth_api
|
|
||||||
? html`
|
|
||||||
<ha-label-badge
|
|
||||||
@click=${this._showMoreInfo}
|
|
||||||
id="auth_api"
|
|
||||||
label="auth"
|
|
||||||
description=""
|
|
||||||
>
|
|
||||||
<ha-svg-icon .path=${mdiKey}></ha-svg-icon>
|
|
||||||
</ha-label-badge>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
${this.addon.ingress
|
|
||||||
? html`
|
|
||||||
<ha-label-badge
|
|
||||||
@click=${this._showMoreInfo}
|
|
||||||
id="ingress"
|
|
||||||
label="ingress"
|
|
||||||
description=""
|
|
||||||
>
|
|
||||||
<ha-svg-icon
|
|
||||||
.path=${mdiCursorDefaultClickOutline}
|
|
||||||
></ha-svg-icon>
|
|
||||||
</ha-label-badge>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
${this.addon.version
|
<ha-label-badge
|
||||||
? html`
|
class=${classMap({
|
||||||
<div
|
green: [5, 6].includes(Number(this.addon.rating)),
|
||||||
class="${classMap({
|
yellow: [3, 4].includes(Number(this.addon.rating)),
|
||||||
"addon-options": true,
|
red: [1, 2].includes(Number(this.addon.rating)),
|
||||||
started: this.addon.state === "started",
|
})}
|
||||||
})}"
|
@click=${this._showMoreInfo}
|
||||||
>
|
id="rating"
|
||||||
<ha-settings-row ?three-line=${this.narrow}>
|
.value=${this.addon.rating}
|
||||||
<span slot="heading">
|
label="rating"
|
||||||
Start on boot
|
description=""
|
||||||
</span>
|
></ha-label-badge>
|
||||||
<span slot="description">
|
${this.addon.host_network
|
||||||
Make the add-on start during a system boot
|
? html`
|
||||||
</span>
|
<ha-label-badge
|
||||||
<ha-switch
|
@click=${this._showMoreInfo}
|
||||||
@change=${this._startOnBootToggled}
|
id="host_network"
|
||||||
.checked=${this.addon.boot === "auto"}
|
label="host"
|
||||||
haptic
|
description=""
|
||||||
></ha-switch>
|
>
|
||||||
</ha-settings-row>
|
<ha-svg-icon .path=${mdiNetwork}></ha-svg-icon>
|
||||||
|
</ha-label-badge>
|
||||||
${this.addon.startup !== "once"
|
`
|
||||||
? html`
|
: ""}
|
||||||
<ha-settings-row ?three-line=${this.narrow}>
|
${this.addon.full_access
|
||||||
<span slot="heading">
|
? html`
|
||||||
Watchdog
|
<ha-label-badge
|
||||||
</span>
|
@click=${this._showMoreInfo}
|
||||||
<span slot="description">
|
id="full_access"
|
||||||
This will start the add-on if it crashes
|
label="hardware"
|
||||||
</span>
|
description=""
|
||||||
<ha-switch
|
>
|
||||||
@change=${this._watchdogToggled}
|
<ha-svg-icon .path=${mdiChip}></ha-svg-icon>
|
||||||
.checked=${this.addon.watchdog}
|
</ha-label-badge>
|
||||||
haptic
|
`
|
||||||
></ha-switch>
|
: ""}
|
||||||
</ha-settings-row>
|
${this.addon.homeassistant_api
|
||||||
`
|
? html`
|
||||||
: ""}
|
<ha-label-badge
|
||||||
${this.addon.auto_update ||
|
@click=${this._showMoreInfo}
|
||||||
this.hass.userData?.showAdvanced
|
id="homeassistant_api"
|
||||||
? html`
|
label="hass"
|
||||||
<ha-settings-row ?three-line=${this.narrow}>
|
description=""
|
||||||
<span slot="heading">
|
>
|
||||||
Auto update
|
<ha-svg-icon .path=${mdiHomeAssistant}></ha-svg-icon>
|
||||||
</span>
|
</ha-label-badge>
|
||||||
<span slot="description">
|
`
|
||||||
Auto update the add-on when there is a new
|
: ""}
|
||||||
version available
|
${this._computeHassioApi
|
||||||
</span>
|
? html`
|
||||||
<ha-switch
|
<ha-label-badge
|
||||||
@change=${this._autoUpdateToggled}
|
@click=${this._showMoreInfo}
|
||||||
.checked=${this.addon.auto_update}
|
id="hassio_api"
|
||||||
haptic
|
label="hassio"
|
||||||
></ha-switch>
|
.description=${this.addon.hassio_role}
|
||||||
</ha-settings-row>
|
>
|
||||||
`
|
<ha-svg-icon .path=${mdiHomeAssistant}></ha-svg-icon>
|
||||||
: ""}
|
</ha-label-badge>
|
||||||
${this.addon.ingress
|
`
|
||||||
? html`
|
: ""}
|
||||||
<ha-settings-row ?three-line=${this.narrow}>
|
${this.addon.docker_api
|
||||||
<span slot="heading">
|
? html`
|
||||||
Show in sidebar
|
<ha-label-badge
|
||||||
</span>
|
@click=${this._showMoreInfo}
|
||||||
<span slot="description">
|
id="docker_api"
|
||||||
${this._computeCannotIngressSidebar
|
label="docker"
|
||||||
? "This option requires Home Assistant 0.92 or later."
|
description=""
|
||||||
: "Add this add-on to your sidebar"}
|
>
|
||||||
</span>
|
<ha-svg-icon .path=${mdiDocker}></ha-svg-icon>
|
||||||
<ha-switch
|
</ha-label-badge>
|
||||||
@change=${this._panelToggled}
|
`
|
||||||
.checked=${this.addon.ingress_panel}
|
: ""}
|
||||||
.disabled=${this._computeCannotIngressSidebar}
|
${this.addon.host_pid
|
||||||
haptic
|
? html`
|
||||||
></ha-switch>
|
<ha-label-badge
|
||||||
</ha-settings-row>
|
@click=${this._showMoreInfo}
|
||||||
`
|
id="host_pid"
|
||||||
: ""}
|
label="host pid"
|
||||||
${this._computeUsesProtectedOptions
|
description=""
|
||||||
? html`
|
>
|
||||||
<ha-settings-row ?three-line=${this.narrow}>
|
<ha-svg-icon .path=${mdiPound}></ha-svg-icon>
|
||||||
<span slot="heading">
|
</ha-label-badge>
|
||||||
Protection mode
|
`
|
||||||
</span>
|
: ""}
|
||||||
<span slot="description">
|
${this.addon.apparmor
|
||||||
Blocks elevated system access from the add-on
|
? html`
|
||||||
</span>
|
<ha-label-badge
|
||||||
<ha-switch
|
@click=${this._showMoreInfo}
|
||||||
@change=${this._protectionToggled}
|
class=${this._computeApparmorClassName}
|
||||||
.checked=${this.addon.protected}
|
id="apparmor"
|
||||||
haptic
|
label="apparmor"
|
||||||
></ha-switch>
|
description=""
|
||||||
</ha-settings-row>
|
>
|
||||||
`
|
<ha-svg-icon .path=${mdiShield}></ha-svg-icon>
|
||||||
: ""}
|
</ha-label-badge>
|
||||||
</div>
|
`
|
||||||
`
|
: ""}
|
||||||
: ""}
|
${this.addon.auth_api
|
||||||
</div>
|
? html`
|
||||||
<div>
|
<ha-label-badge
|
||||||
${this.addon.state === "started"
|
@click=${this._showMoreInfo}
|
||||||
? html`<ha-settings-row ?three-line=${this.narrow}>
|
id="auth_api"
|
||||||
<span slot="heading">
|
label="auth"
|
||||||
Hostname
|
description=""
|
||||||
</span>
|
>
|
||||||
<code slot="description">
|
<ha-svg-icon .path=${mdiKey}></ha-svg-icon>
|
||||||
${this.addon.hostname}
|
</ha-label-badge>
|
||||||
</code>
|
`
|
||||||
</ha-settings-row>
|
: ""}
|
||||||
${metrics.map(
|
${this.addon.ingress
|
||||||
(metric) =>
|
? html`
|
||||||
html`
|
<ha-label-badge
|
||||||
<supervisor-metric
|
@click=${this._showMoreInfo}
|
||||||
.description=${metric.description}
|
id="ingress"
|
||||||
.value=${metric.value ?? 0}
|
label="ingress"
|
||||||
.tooltip=${metric.tooltip}
|
description=""
|
||||||
></supervisor-metric>
|
>
|
||||||
`
|
<ha-svg-icon
|
||||||
)}`
|
.path=${mdiCursorDefaultClickOutline}
|
||||||
: ""}
|
></ha-svg-icon>
|
||||||
</div>
|
</ha-label-badge>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
${this.addon.version
|
||||||
|
? html`
|
||||||
|
<div class="addon-options">
|
||||||
|
<ha-settings-row ?three-line=${this.narrow}>
|
||||||
|
<span slot="heading">
|
||||||
|
Start on boot
|
||||||
|
</span>
|
||||||
|
<span slot="description">
|
||||||
|
Make the add-on start during a system boot
|
||||||
|
</span>
|
||||||
|
<ha-switch
|
||||||
|
@change=${this._startOnBootToggled}
|
||||||
|
.checked=${this.addon.boot === "auto"}
|
||||||
|
haptic
|
||||||
|
></ha-switch>
|
||||||
|
</ha-settings-row>
|
||||||
|
|
||||||
|
${this.addon.startup !== "once"
|
||||||
|
? html`
|
||||||
|
<ha-settings-row ?three-line=${this.narrow}>
|
||||||
|
<span slot="heading">
|
||||||
|
Watchdog
|
||||||
|
</span>
|
||||||
|
<span slot="description">
|
||||||
|
This will start the add-on if it crashes
|
||||||
|
</span>
|
||||||
|
<ha-switch
|
||||||
|
@change=${this._watchdogToggled}
|
||||||
|
.checked=${this.addon.watchdog}
|
||||||
|
haptic
|
||||||
|
></ha-switch>
|
||||||
|
</ha-settings-row>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
${this.addon.auto_update || this.hass.userData?.showAdvanced
|
||||||
|
? html`
|
||||||
|
<ha-settings-row ?three-line=${this.narrow}>
|
||||||
|
<span slot="heading">
|
||||||
|
Auto update
|
||||||
|
</span>
|
||||||
|
<span slot="description">
|
||||||
|
Auto update the add-on when there is a new version
|
||||||
|
available
|
||||||
|
</span>
|
||||||
|
<ha-switch
|
||||||
|
@change=${this._autoUpdateToggled}
|
||||||
|
.checked=${this.addon.auto_update}
|
||||||
|
haptic
|
||||||
|
></ha-switch>
|
||||||
|
</ha-settings-row>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
${this.addon.ingress
|
||||||
|
? html`
|
||||||
|
<ha-settings-row ?three-line=${this.narrow}>
|
||||||
|
<span slot="heading">
|
||||||
|
Show in sidebar
|
||||||
|
</span>
|
||||||
|
<span slot="description">
|
||||||
|
${this._computeCannotIngressSidebar
|
||||||
|
? "This option requires Home Assistant 0.92 or later."
|
||||||
|
: "Add this add-on to your sidebar"}
|
||||||
|
</span>
|
||||||
|
<ha-switch
|
||||||
|
@change=${this._panelToggled}
|
||||||
|
.checked=${this.addon.ingress_panel}
|
||||||
|
.disabled=${this._computeCannotIngressSidebar}
|
||||||
|
haptic
|
||||||
|
></ha-switch>
|
||||||
|
</ha-settings-row>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
${this._computeUsesProtectedOptions
|
||||||
|
? html`
|
||||||
|
<ha-settings-row ?three-line=${this.narrow}>
|
||||||
|
<span slot="heading">
|
||||||
|
Protection mode
|
||||||
|
</span>
|
||||||
|
<span slot="description">
|
||||||
|
Blocks elevated system access from the add-on
|
||||||
|
</span>
|
||||||
|
<ha-switch
|
||||||
|
@change=${this._protectionToggled}
|
||||||
|
.checked=${this.addon.protected}
|
||||||
|
haptic
|
||||||
|
></ha-switch>
|
||||||
|
</ha-settings-row>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
|
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
@@ -632,22 +579,6 @@ class HassioAddonInfo extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps) {
|
|
||||||
super.updated(changedProps);
|
|
||||||
if (changedProps.has("addon")) {
|
|
||||||
this._loadData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _loadData(): Promise<void> {
|
|
||||||
if (this.addon.state === "started") {
|
|
||||||
this._metrics = await fetchHassioStats(
|
|
||||||
this.hass,
|
|
||||||
`addons/${this.addon.slug}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private get _computeHassioApi(): boolean {
|
private get _computeHassioApi(): boolean {
|
||||||
return (
|
return (
|
||||||
this.addon.hassio_api &&
|
this.addon.hassio_api &&
|
||||||
@@ -1057,26 +988,10 @@ class HassioAddonInfo extends LitElement {
|
|||||||
.addon-options {
|
.addon-options {
|
||||||
max-width: 50%;
|
max-width: 50%;
|
||||||
}
|
}
|
||||||
.addon-options.started {
|
|
||||||
max-width: 90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.addon-container {
|
|
||||||
display: grid;
|
|
||||||
grid-auto-flow: column;
|
|
||||||
grid-template-columns: 1fr auto;
|
|
||||||
}
|
|
||||||
.addon-container div:last-of-type {
|
|
||||||
align-self: end;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 720px) {
|
@media (max-width: 720px) {
|
||||||
.addon-options {
|
.addon-options {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
.addon-container {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
|
@@ -7,8 +7,8 @@ import {
|
|||||||
property,
|
property,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import "../../../../src/components/ha-circular-progress";
|
|
||||||
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||||
|
import "../../../../src/components/ha-circular-progress";
|
||||||
import { haStyle } from "../../../../src/resources/styles";
|
import { haStyle } from "../../../../src/resources/styles";
|
||||||
import { HomeAssistant } from "../../../../src/types";
|
import { HomeAssistant } from "../../../../src/types";
|
||||||
import { hassioStyle } from "../../resources/hassio-style";
|
import { hassioStyle } from "../../resources/hassio-style";
|
||||||
|
@@ -1,87 +0,0 @@
|
|||||||
import {
|
|
||||||
css,
|
|
||||||
CSSResult,
|
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
property,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { classMap } from "lit-html/directives/class-map";
|
|
||||||
import "../../../src/components/ha-bar";
|
|
||||||
import "../../../src/components/ha-settings-row";
|
|
||||||
import { roundWithOneDecimal } from "../../../src/util/calculate";
|
|
||||||
|
|
||||||
@customElement("supervisor-metric")
|
|
||||||
class SupervisorMetric extends LitElement {
|
|
||||||
@property({ type: Number }) public value!: number;
|
|
||||||
|
|
||||||
@property({ type: String }) public description!: string;
|
|
||||||
|
|
||||||
@property({ type: String }) public tooltip?: string;
|
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
const roundedValue = roundWithOneDecimal(this.value);
|
|
||||||
return html`<ha-settings-row>
|
|
||||||
<span slot="heading">
|
|
||||||
${this.description}
|
|
||||||
</span>
|
|
||||||
<div slot="description" title="${this.tooltip ?? ""}">
|
|
||||||
<span class="value">
|
|
||||||
${roundedValue}%
|
|
||||||
</span>
|
|
||||||
<ha-bar
|
|
||||||
class="${classMap({
|
|
||||||
"target-warning": roundedValue > 50,
|
|
||||||
"target-critical": roundedValue > 85,
|
|
||||||
})}"
|
|
||||||
.value=${this.value}
|
|
||||||
></ha-bar>
|
|
||||||
</div>
|
|
||||||
</ha-settings-row>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
|
||||||
return css`
|
|
||||||
ha-settings-row {
|
|
||||||
padding: 0;
|
|
||||||
height: 54px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
ha-settings-row > div[slot="description"] {
|
|
||||||
white-space: normal;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
ha-bar {
|
|
||||||
--ha-bar-primary-color: var(
|
|
||||||
--hassio-bar-ok-color,
|
|
||||||
var(--success-color)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
.target-warning {
|
|
||||||
--ha-bar-primary-color: var(
|
|
||||||
--hassio-bar-warning-color,
|
|
||||||
var(--warning-color)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
.target-critical {
|
|
||||||
--ha-bar-primary-color: var(
|
|
||||||
--hassio-bar-critical-color,
|
|
||||||
var(--error-color)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
.value {
|
|
||||||
width: 42px;
|
|
||||||
padding-right: 4px;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HTMLElementTagNameMap {
|
|
||||||
"supervisor-metric": SupervisorMetric;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -74,7 +74,9 @@ export class HassioUpdate extends LitElement {
|
|||||||
"Supervisor",
|
"Supervisor",
|
||||||
this.supervisor.supervisor,
|
this.supervisor.supervisor,
|
||||||
"hassio/supervisor/update",
|
"hassio/supervisor/update",
|
||||||
`https://github.com//home-assistant/hassio/releases/tag/${this.supervisor.supervisor.version_latest}`
|
`https://github.com//home-assistant/hassio/releases/tag/${
|
||||||
|
this.supervisor.supervisor.version_latest
|
||||||
|
}`
|
||||||
)}
|
)}
|
||||||
${this.supervisor.host.features.includes("hassos")
|
${this.supervisor.host.features.includes("hassos")
|
||||||
? this._renderUpdateCard(
|
? this._renderUpdateCard(
|
||||||
|
@@ -3,9 +3,9 @@ import {
|
|||||||
CSSResult,
|
CSSResult,
|
||||||
customElement,
|
customElement,
|
||||||
html,
|
html,
|
||||||
internalProperty,
|
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
|
internalProperty,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { createCloseHeading } from "../../../../src/components/ha-dialog";
|
import { createCloseHeading } from "../../../../src/components/ha-dialog";
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
// Compat needs to be first import
|
|
||||||
import "../../src/resources/compatibility";
|
import "../../src/resources/compatibility";
|
||||||
import "../../src/resources/roboto";
|
|
||||||
import "../../src/resources/safari-14-attachshadow-patch";
|
import "../../src/resources/safari-14-attachshadow-patch";
|
||||||
|
import "../../src/resources/roboto";
|
||||||
import "./hassio-main";
|
import "./hassio-main";
|
||||||
|
|
||||||
const styleEl = document.createElement("style");
|
const styleEl = document.createElement("style");
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
import { customElement, html, property, PropertyValues } from "lit-element";
|
import { html, PropertyValues, customElement, property } from "lit-element";
|
||||||
import { atLeastVersion } from "../../src/common/config/version";
|
import "./hassio-router";
|
||||||
|
import { HomeAssistant, Route } from "../../src/types";
|
||||||
|
import { HassioPanelInfo } from "../../src/data/hassio/supervisor";
|
||||||
import { applyThemesOnElement } from "../../src/common/dom/apply_themes_on_element";
|
import { applyThemesOnElement } from "../../src/common/dom/apply_themes_on_element";
|
||||||
import { fireEvent } from "../../src/common/dom/fire_event";
|
import { fireEvent } from "../../src/common/dom/fire_event";
|
||||||
import { HassioPanelInfo } from "../../src/data/hassio/supervisor";
|
|
||||||
import { makeDialogManager } from "../../src/dialogs/make-dialog-manager";
|
import { makeDialogManager } from "../../src/dialogs/make-dialog-manager";
|
||||||
import { HomeAssistant, Route } from "../../src/types";
|
import { atLeastVersion } from "../../src/common/config/version";
|
||||||
import "./hassio-router";
|
|
||||||
import { SupervisorBaseElement } from "./supervisor-base-element";
|
import { SupervisorBaseElement } from "./supervisor-base-element";
|
||||||
|
|
||||||
@customElement("hassio-main")
|
@customElement("hassio-main")
|
||||||
|
@@ -1,17 +1,14 @@
|
|||||||
import { mdiMenu } from "@mdi/js";
|
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
CSSResult,
|
CSSResult,
|
||||||
customElement,
|
customElement,
|
||||||
html,
|
html,
|
||||||
internalProperty,
|
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
|
internalProperty,
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
|
||||||
import { navigate } from "../../../src/common/navigate";
|
|
||||||
import {
|
import {
|
||||||
fetchHassioAddonInfo,
|
fetchHassioAddonInfo,
|
||||||
HassioAddonDetails,
|
HassioAddonDetails,
|
||||||
@@ -20,10 +17,13 @@ import {
|
|||||||
createHassioSession,
|
createHassioSession,
|
||||||
validateHassioSession,
|
validateHassioSession,
|
||||||
} from "../../../src/data/hassio/ingress";
|
} from "../../../src/data/hassio/ingress";
|
||||||
import { showAlertDialog } from "../../../src/dialogs/generic/show-dialog-box";
|
|
||||||
import "../../../src/layouts/hass-loading-screen";
|
import "../../../src/layouts/hass-loading-screen";
|
||||||
import "../../../src/layouts/hass-subpage";
|
import "../../../src/layouts/hass-subpage";
|
||||||
import { HomeAssistant, Route } from "../../../src/types";
|
import { HomeAssistant, Route } from "../../../src/types";
|
||||||
|
import { showAlertDialog } from "../../../src/dialogs/generic/show-dialog-box";
|
||||||
|
import { navigate } from "../../../src/common/navigate";
|
||||||
|
import { mdiMenu } from "@mdi/js";
|
||||||
|
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||||
|
|
||||||
@customElement("hassio-ingress-view")
|
@customElement("hassio-ingress-view")
|
||||||
class HassioIngressView extends LitElement {
|
class HassioIngressView extends LitElement {
|
||||||
|
@@ -264,7 +264,7 @@ class HassioSnapshots extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues) {
|
protected updated(changedProps: PropertyValues) {
|
||||||
if (changedProps.has("supervisor")) {
|
if (changedProps.has("supervisorInfo")) {
|
||||||
this._addonList = this.supervisor.supervisor.addons
|
this._addonList = this.supervisor.supervisor.addons
|
||||||
.map((addon) => ({
|
.map((addon) => ({
|
||||||
slug: addon.slug,
|
slug: addon.slug,
|
||||||
|
@@ -1,246 +0,0 @@
|
|||||||
import "@material/mwc-button";
|
|
||||||
import "@material/mwc-list/mwc-list-item";
|
|
||||||
import {
|
|
||||||
css,
|
|
||||||
CSSResult,
|
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
internalProperty,
|
|
||||||
LitElement,
|
|
||||||
property,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import "../../../src/components/buttons/ha-progress-button";
|
|
||||||
import "../../../src/components/ha-button-menu";
|
|
||||||
import "../../../src/components/ha-card";
|
|
||||||
import "../../../src/components/ha-settings-row";
|
|
||||||
import {
|
|
||||||
extractApiErrorMessage,
|
|
||||||
fetchHassioStats,
|
|
||||||
HassioStats,
|
|
||||||
} from "../../../src/data/hassio/common";
|
|
||||||
import { restartCore, updateCore } from "../../../src/data/supervisor/core";
|
|
||||||
import { Supervisor } from "../../../src/data/supervisor/supervisor";
|
|
||||||
import {
|
|
||||||
showAlertDialog,
|
|
||||||
showConfirmationDialog,
|
|
||||||
} from "../../../src/dialogs/generic/show-dialog-box";
|
|
||||||
import { haStyle } from "../../../src/resources/styles";
|
|
||||||
import { HomeAssistant } from "../../../src/types";
|
|
||||||
import { bytesToString } from "../../../src/util/bytes-to-string";
|
|
||||||
import "../components/supervisor-metric";
|
|
||||||
import { hassioStyle } from "../resources/hassio-style";
|
|
||||||
|
|
||||||
@customElement("hassio-core-info")
|
|
||||||
class HassioCoreInfo extends LitElement {
|
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
|
||||||
|
|
||||||
@property({ attribute: false }) public supervisor!: Supervisor;
|
|
||||||
|
|
||||||
@internalProperty() private _metrics?: HassioStats;
|
|
||||||
|
|
||||||
protected render(): TemplateResult | void {
|
|
||||||
const metrics = [
|
|
||||||
{
|
|
||||||
description: "Core CPU Usage",
|
|
||||||
value: this._metrics?.cpu_percent,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "Core RAM Usage",
|
|
||||||
value: this._metrics?.memory_percent,
|
|
||||||
tooltip: `${bytesToString(this._metrics?.memory_usage)}/${bytesToString(
|
|
||||||
this._metrics?.memory_limit
|
|
||||||
)}`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<ha-card header="Core">
|
|
||||||
<div class="card-content">
|
|
||||||
<div>
|
|
||||||
<ha-settings-row>
|
|
||||||
<span slot="heading">
|
|
||||||
Version
|
|
||||||
</span>
|
|
||||||
<span slot="description">
|
|
||||||
core-${this.supervisor.core.version}
|
|
||||||
</span>
|
|
||||||
</ha-settings-row>
|
|
||||||
<ha-settings-row>
|
|
||||||
<span slot="heading">
|
|
||||||
Newest Version
|
|
||||||
</span>
|
|
||||||
<span slot="description">
|
|
||||||
core-${this.supervisor.core.version_latest}
|
|
||||||
</span>
|
|
||||||
${this.supervisor.core.update_available
|
|
||||||
? html`
|
|
||||||
<ha-progress-button
|
|
||||||
title="Update the core"
|
|
||||||
@click=${this._coreUpdate}
|
|
||||||
>
|
|
||||||
Update
|
|
||||||
</ha-progress-button>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
</ha-settings-row>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
${metrics.map(
|
|
||||||
(metric) =>
|
|
||||||
html`
|
|
||||||
<supervisor-metric
|
|
||||||
.description=${metric.description}
|
|
||||||
.value=${metric.value ?? 0}
|
|
||||||
.tooltip=${metric.tooltip}
|
|
||||||
></supervisor-metric>
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-actions">
|
|
||||||
<ha-progress-button
|
|
||||||
slot="primaryAction"
|
|
||||||
class="warning"
|
|
||||||
@click=${this._coreRestart}
|
|
||||||
title="Restart Home Assistant Core"
|
|
||||||
>
|
|
||||||
Restart Core
|
|
||||||
</ha-progress-button>
|
|
||||||
</div>
|
|
||||||
</ha-card>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected firstUpdated(): void {
|
|
||||||
this._loadData();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _loadData(): Promise<void> {
|
|
||||||
this._metrics = await fetchHassioStats(this.hass, "core");
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _coreRestart(ev: CustomEvent): Promise<void> {
|
|
||||||
const button = ev.currentTarget as any;
|
|
||||||
button.progress = true;
|
|
||||||
|
|
||||||
const confirmed = await showConfirmationDialog(this, {
|
|
||||||
title: "Restart Home Assistant Core",
|
|
||||||
text: "Are you sure you want to restart Home Assistant Core",
|
|
||||||
confirmText: "restart",
|
|
||||||
dismissText: "cancel",
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!confirmed) {
|
|
||||||
button.progress = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await restartCore(this.hass);
|
|
||||||
} catch (err) {
|
|
||||||
showAlertDialog(this, {
|
|
||||||
title: "Failed to restart Home Assistant Core",
|
|
||||||
text: extractApiErrorMessage(err),
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
button.progress = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _coreUpdate(ev: CustomEvent): Promise<void> {
|
|
||||||
const button = ev.currentTarget as any;
|
|
||||||
button.progress = true;
|
|
||||||
|
|
||||||
const confirmed = await showConfirmationDialog(this, {
|
|
||||||
title: "Update Home Assistant Core",
|
|
||||||
text: `Are you sure you want to update Home Assistant Core to version ${this.supervisor.core.version_latest}?`,
|
|
||||||
confirmText: "update",
|
|
||||||
dismissText: "cancel",
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!confirmed) {
|
|
||||||
button.progress = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await updateCore(this.hass);
|
|
||||||
} catch (err) {
|
|
||||||
showAlertDialog(this, {
|
|
||||||
title: "Failed to update Home Assistant Core",
|
|
||||||
text: extractApiErrorMessage(err),
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
button.progress = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
|
||||||
return [
|
|
||||||
haStyle,
|
|
||||||
hassioStyle,
|
|
||||||
css`
|
|
||||||
ha-card {
|
|
||||||
height: 100%;
|
|
||||||
justify-content: space-between;
|
|
||||||
flex-direction: column;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
.card-actions {
|
|
||||||
height: 48px;
|
|
||||||
border-top: none;
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.card-content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: calc(100% - 124px);
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
ha-settings-row {
|
|
||||||
padding: 0;
|
|
||||||
height: 54px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
ha-settings-row[three-line] {
|
|
||||||
height: 74px;
|
|
||||||
}
|
|
||||||
ha-settings-row > span[slot="description"] {
|
|
||||||
white-space: normal;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.warning {
|
|
||||||
--mdc-theme-primary: var(--error-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
ha-button-menu {
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
--mdc-menu-min-width: 200px;
|
|
||||||
}
|
|
||||||
@media (min-width: 563px) {
|
|
||||||
paper-listbox {
|
|
||||||
max-height: 150px;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
paper-item {
|
|
||||||
cursor: pointer;
|
|
||||||
min-height: 35px;
|
|
||||||
}
|
|
||||||
mwc-list-item ha-svg-icon {
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HTMLElementTagNameMap {
|
|
||||||
"hassio-core-info": HassioCoreInfo;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -43,11 +43,6 @@ import {
|
|||||||
} from "../../../src/dialogs/generic/show-dialog-box";
|
} from "../../../src/dialogs/generic/show-dialog-box";
|
||||||
import { haStyle } from "../../../src/resources/styles";
|
import { haStyle } from "../../../src/resources/styles";
|
||||||
import { HomeAssistant } from "../../../src/types";
|
import { HomeAssistant } from "../../../src/types";
|
||||||
import {
|
|
||||||
getValueInPercentage,
|
|
||||||
roundWithOneDecimal,
|
|
||||||
} from "../../../src/util/calculate";
|
|
||||||
import "../components/supervisor-metric";
|
|
||||||
import { showHassioMarkdownDialog } from "../dialogs/markdown/show-dialog-hassio-markdown";
|
import { showHassioMarkdownDialog } from "../dialogs/markdown/show-dialog-hassio-markdown";
|
||||||
import { showNetworkDialog } from "../dialogs/network/show-dialog-network";
|
import { showNetworkDialog } from "../dialogs/network/show-dialog-network";
|
||||||
import { hassioStyle } from "../resources/hassio-style";
|
import { hassioStyle } from "../resources/hassio-style";
|
||||||
@@ -62,105 +57,80 @@ class HassioHostInfo extends LitElement {
|
|||||||
const primaryIpAddress = this.supervisor.host.features.includes("network")
|
const primaryIpAddress = this.supervisor.host.features.includes("network")
|
||||||
? this._primaryIpAddress(this.supervisor.network!)
|
? this._primaryIpAddress(this.supervisor.network!)
|
||||||
: "";
|
: "";
|
||||||
|
|
||||||
const metrics = [
|
|
||||||
{
|
|
||||||
description: "Used Space",
|
|
||||||
value: this._getUsedSpace(
|
|
||||||
this.supervisor.host.disk_used,
|
|
||||||
this.supervisor.host.disk_total
|
|
||||||
),
|
|
||||||
tooltip: `${this.supervisor.host.disk_used} GB/${this.supervisor.host.disk_total} GB`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
return html`
|
return html`
|
||||||
<ha-card header="Host">
|
<ha-card header="Host System">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div>
|
${this.supervisor.host.features.includes("hostname")
|
||||||
${this.supervisor.host.features.includes("hostname")
|
? html`<ha-settings-row>
|
||||||
? html`<ha-settings-row>
|
<span slot="heading">
|
||||||
<span slot="heading">
|
Hostname
|
||||||
Hostname
|
</span>
|
||||||
</span>
|
<span slot="description">
|
||||||
<span slot="description">
|
${this.supervisor.host.hostname}
|
||||||
${this.supervisor.host.hostname}
|
</span>
|
||||||
</span>
|
<mwc-button
|
||||||
<mwc-button
|
title="Change the hostname"
|
||||||
title="Change the hostname"
|
label="Change"
|
||||||
label="Change"
|
@click=${this._changeHostnameClicked}
|
||||||
@click=${this._changeHostnameClicked}
|
>
|
||||||
>
|
</mwc-button>
|
||||||
</mwc-button>
|
</ha-settings-row>`
|
||||||
</ha-settings-row>`
|
: ""}
|
||||||
: ""}
|
${this.supervisor.host.features.includes("network")
|
||||||
${this.supervisor.host.features.includes("network")
|
? html` <ha-settings-row>
|
||||||
? html` <ha-settings-row>
|
<span slot="heading">
|
||||||
<span slot="heading">
|
IP Address
|
||||||
IP Address
|
</span>
|
||||||
</span>
|
<span slot="description">
|
||||||
<span slot="description">
|
${primaryIpAddress}
|
||||||
${primaryIpAddress}
|
</span>
|
||||||
</span>
|
<mwc-button
|
||||||
<mwc-button
|
title="Change the network"
|
||||||
title="Change the network"
|
label="Change"
|
||||||
label="Change"
|
@click=${this._changeNetworkClicked}
|
||||||
@click=${this._changeNetworkClicked}
|
>
|
||||||
>
|
</mwc-button>
|
||||||
</mwc-button>
|
</ha-settings-row>`
|
||||||
</ha-settings-row>`
|
: ""}
|
||||||
: ""}
|
|
||||||
|
|
||||||
<ha-settings-row>
|
<ha-settings-row>
|
||||||
<span slot="heading">
|
<span slot="heading">
|
||||||
Operating System
|
Operating System
|
||||||
</span>
|
</span>
|
||||||
<span slot="description">
|
<span slot="description">
|
||||||
${this.supervisor.host.operating_system}
|
${this.supervisor.host.operating_system}
|
||||||
</span>
|
</span>
|
||||||
${this.supervisor.os.update_available
|
${this.supervisor.os.update_available
|
||||||
? html`
|
? html`
|
||||||
<ha-progress-button
|
<ha-progress-button
|
||||||
title="Update the host OS"
|
title="Update the host OS"
|
||||||
@click=${this._osUpdate}
|
@click=${this._osUpdate}
|
||||||
>
|
>
|
||||||
Update
|
Update
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
</ha-settings-row>
|
|
||||||
${!this.supervisor.host.features.includes("hassos")
|
|
||||||
? html`<ha-settings-row>
|
|
||||||
<span slot="heading">
|
|
||||||
Docker version
|
|
||||||
</span>
|
|
||||||
<span slot="description">
|
|
||||||
${this.supervisor.info.docker}
|
|
||||||
</span>
|
|
||||||
</ha-settings-row>`
|
|
||||||
: ""}
|
|
||||||
${this.supervisor.host.deployment
|
|
||||||
? html`<ha-settings-row>
|
|
||||||
<span slot="heading">
|
|
||||||
Deployment
|
|
||||||
</span>
|
|
||||||
<span slot="description">
|
|
||||||
${this.supervisor.host.deployment}
|
|
||||||
</span>
|
|
||||||
</ha-settings-row>`
|
|
||||||
: ""}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
${metrics.map(
|
|
||||||
(metric) =>
|
|
||||||
html`
|
|
||||||
<supervisor-metric
|
|
||||||
.description=${metric.description}
|
|
||||||
.value=${metric.value ?? 0}
|
|
||||||
.tooltip=${metric.tooltip}
|
|
||||||
></supervisor-metric>
|
|
||||||
`
|
`
|
||||||
)}
|
: ""}
|
||||||
</div>
|
</ha-settings-row>
|
||||||
|
${!this.supervisor.host.features.includes("hassos")
|
||||||
|
? html`<ha-settings-row>
|
||||||
|
<span slot="heading">
|
||||||
|
Docker version
|
||||||
|
</span>
|
||||||
|
<span slot="description">
|
||||||
|
${this.supervisor.info.docker}
|
||||||
|
</span>
|
||||||
|
</ha-settings-row>`
|
||||||
|
: ""}
|
||||||
|
${this.supervisor.host.deployment
|
||||||
|
? html`<ha-settings-row>
|
||||||
|
<span slot="heading">
|
||||||
|
Deployment
|
||||||
|
</span>
|
||||||
|
<span slot="description">
|
||||||
|
${this.supervisor.host.deployment}
|
||||||
|
</span>
|
||||||
|
</ha-settings-row>`
|
||||||
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
${this.supervisor.host.features.includes("reboot")
|
${this.supervisor.host.features.includes("reboot")
|
||||||
@@ -170,7 +140,7 @@ class HassioHostInfo extends LitElement {
|
|||||||
class="warning"
|
class="warning"
|
||||||
@click=${this._hostReboot}
|
@click=${this._hostReboot}
|
||||||
>
|
>
|
||||||
Reboot Host
|
Reboot
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
@@ -181,7 +151,7 @@ class HassioHostInfo extends LitElement {
|
|||||||
class="warning"
|
class="warning"
|
||||||
@click=${this._hostShutdown}
|
@click=${this._hostShutdown}
|
||||||
>
|
>
|
||||||
Shutdown Host
|
Shutdown
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
@@ -213,10 +183,6 @@ class HassioHostInfo extends LitElement {
|
|||||||
this._loadData();
|
this._loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getUsedSpace = memoizeOne((used: number, total: number) =>
|
|
||||||
roundWithOneDecimal(getValueInPercentage(used, 0, total))
|
|
||||||
);
|
|
||||||
|
|
||||||
private _primaryIpAddress = memoizeOne((network_info: NetworkInfo) => {
|
private _primaryIpAddress = memoizeOne((network_info: NetworkInfo) => {
|
||||||
if (!network_info || !network_info.interfaces) {
|
if (!network_info || !network_info.interfaces) {
|
||||||
return "";
|
return "";
|
||||||
@@ -403,12 +369,6 @@ class HassioHostInfo extends LitElement {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.card-content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: calc(100% - 124px);
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
ha-settings-row {
|
ha-settings-row {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 54px;
|
height: 54px;
|
||||||
|
@@ -3,7 +3,6 @@ import {
|
|||||||
CSSResult,
|
CSSResult,
|
||||||
customElement,
|
customElement,
|
||||||
html,
|
html,
|
||||||
internalProperty,
|
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
@@ -13,11 +12,7 @@ import "../../../src/components/buttons/ha-progress-button";
|
|||||||
import "../../../src/components/ha-card";
|
import "../../../src/components/ha-card";
|
||||||
import "../../../src/components/ha-settings-row";
|
import "../../../src/components/ha-settings-row";
|
||||||
import "../../../src/components/ha-switch";
|
import "../../../src/components/ha-switch";
|
||||||
import {
|
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
|
||||||
extractApiErrorMessage,
|
|
||||||
fetchHassioStats,
|
|
||||||
HassioStats,
|
|
||||||
} from "../../../src/data/hassio/common";
|
|
||||||
import {
|
import {
|
||||||
fetchHassioSupervisorInfo,
|
fetchHassioSupervisorInfo,
|
||||||
reloadSupervisor,
|
reloadSupervisor,
|
||||||
@@ -33,9 +28,7 @@ import {
|
|||||||
} from "../../../src/dialogs/generic/show-dialog-box";
|
} from "../../../src/dialogs/generic/show-dialog-box";
|
||||||
import { haStyle } from "../../../src/resources/styles";
|
import { haStyle } from "../../../src/resources/styles";
|
||||||
import { HomeAssistant } from "../../../src/types";
|
import { HomeAssistant } from "../../../src/types";
|
||||||
import { bytesToString } from "../../../src/util/bytes-to-string";
|
|
||||||
import { documentationUrl } from "../../../src/util/documentation-url";
|
import { documentationUrl } from "../../../src/util/documentation-url";
|
||||||
import "../components/supervisor-metric";
|
|
||||||
import { hassioStyle } from "../resources/hassio-style";
|
import { hassioStyle } from "../resources/hassio-style";
|
||||||
|
|
||||||
const UNSUPPORTED_REASON = {
|
const UNSUPPORTED_REASON = {
|
||||||
@@ -94,164 +87,127 @@ class HassioSupervisorInfo extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public supervisor!: Supervisor;
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
@internalProperty() private _metrics?: HassioStats;
|
|
||||||
|
|
||||||
protected render(): TemplateResult | void {
|
protected render(): TemplateResult | void {
|
||||||
const metrics = [
|
|
||||||
{
|
|
||||||
description: "Supervisor CPU Usage",
|
|
||||||
value: this._metrics?.cpu_percent,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "Supervisor RAM Usage",
|
|
||||||
value: this._metrics?.memory_percent,
|
|
||||||
tooltip: `${bytesToString(this._metrics?.memory_usage)}/${bytesToString(
|
|
||||||
this._metrics?.memory_limit
|
|
||||||
)}`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
return html`
|
return html`
|
||||||
<ha-card header="Supervisor">
|
<ha-card header="Supervisor">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div>
|
<ha-settings-row>
|
||||||
<ha-settings-row>
|
<span slot="heading">
|
||||||
<span slot="heading">
|
Version
|
||||||
Version
|
</span>
|
||||||
</span>
|
<span slot="description">
|
||||||
<span slot="description">
|
${this.supervisor.supervisor.version}
|
||||||
supervisor-${this.supervisor.supervisor.version}
|
</span>
|
||||||
</span>
|
</ha-settings-row>
|
||||||
</ha-settings-row>
|
<ha-settings-row>
|
||||||
<ha-settings-row>
|
<span slot="heading">
|
||||||
<span slot="heading">
|
Newest Version
|
||||||
Newest Version
|
</span>
|
||||||
</span>
|
<span slot="description">
|
||||||
<span slot="description">
|
${this.supervisor.supervisor.version_latest}
|
||||||
supervisor-${this.supervisor.supervisor.version_latest}
|
</span>
|
||||||
</span>
|
${this.supervisor.supervisor.update_available
|
||||||
${this.supervisor.supervisor.update_available
|
? html`
|
||||||
? html`
|
<ha-progress-button
|
||||||
<ha-progress-button
|
title="Update the supervisor"
|
||||||
title="Update the supervisor"
|
@click=${this._supervisorUpdate}
|
||||||
@click=${this._supervisorUpdate}
|
|
||||||
>
|
|
||||||
Update
|
|
||||||
</ha-progress-button>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
</ha-settings-row>
|
|
||||||
<ha-settings-row>
|
|
||||||
<span slot="heading">
|
|
||||||
Channel
|
|
||||||
</span>
|
|
||||||
<span slot="description">
|
|
||||||
${this.supervisor.supervisor.channel}
|
|
||||||
</span>
|
|
||||||
${this.supervisor.supervisor.channel === "beta"
|
|
||||||
? html`
|
|
||||||
<ha-progress-button
|
|
||||||
@click=${this._toggleBeta}
|
|
||||||
title="Get stable updates for Home Assistant, supervisor and host"
|
|
||||||
>
|
|
||||||
Leave beta channel
|
|
||||||
</ha-progress-button>
|
|
||||||
`
|
|
||||||
: this.supervisor.supervisor.channel === "stable"
|
|
||||||
? html`
|
|
||||||
<ha-progress-button
|
|
||||||
@click=${this._toggleBeta}
|
|
||||||
title="Get beta updates for Home Assistant (RCs), supervisor and host"
|
|
||||||
>
|
|
||||||
Join beta channel
|
|
||||||
</ha-progress-button>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
</ha-settings-row>
|
|
||||||
|
|
||||||
${this.supervisor.supervisor.supported
|
|
||||||
? html` <ha-settings-row three-line>
|
|
||||||
<span slot="heading">
|
|
||||||
Share Diagnostics
|
|
||||||
</span>
|
|
||||||
<div slot="description" class="diagnostics-description">
|
|
||||||
Share crash reports and diagnostic information.
|
|
||||||
<button
|
|
||||||
class="link"
|
|
||||||
title="Show more information about this"
|
|
||||||
@click=${this._diagnosticsInformationDialog}
|
|
||||||
>
|
|
||||||
Learn more
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<ha-switch
|
|
||||||
haptic
|
|
||||||
.checked=${this.supervisor.supervisor.diagnostics}
|
|
||||||
@change=${this._toggleDiagnostics}
|
|
||||||
></ha-switch>
|
|
||||||
</ha-settings-row>`
|
|
||||||
: html`<div class="error">
|
|
||||||
You are running an unsupported installation.
|
|
||||||
<button
|
|
||||||
class="link"
|
|
||||||
title="Learn more about how you can make your system compliant"
|
|
||||||
@click=${this._unsupportedDialog}
|
|
||||||
>
|
>
|
||||||
Learn more
|
Update
|
||||||
</button>
|
</ha-progress-button>
|
||||||
</div>`}
|
|
||||||
${!this.supervisor.supervisor.healthy
|
|
||||||
? html`<div class="error">
|
|
||||||
Your installation is running in an unhealthy state.
|
|
||||||
<button
|
|
||||||
class="link"
|
|
||||||
title="Learn more about why your system is marked as unhealthy"
|
|
||||||
@click=${this._unhealthyDialog}
|
|
||||||
>
|
|
||||||
Learn more
|
|
||||||
</button>
|
|
||||||
</div>`
|
|
||||||
: ""}
|
|
||||||
</div>
|
|
||||||
<div class="metrics-block">
|
|
||||||
${metrics.map(
|
|
||||||
(metric) =>
|
|
||||||
html`
|
|
||||||
<supervisor-metric
|
|
||||||
.description=${metric.description}
|
|
||||||
.value=${metric.value ?? 0}
|
|
||||||
.tooltip=${metric.tooltip}
|
|
||||||
></supervisor-metric>
|
|
||||||
`
|
`
|
||||||
)}
|
: ""}
|
||||||
</div>
|
</ha-settings-row>
|
||||||
|
<ha-settings-row>
|
||||||
|
<span slot="heading">
|
||||||
|
Channel
|
||||||
|
</span>
|
||||||
|
<span slot="description">
|
||||||
|
${this.supervisor.supervisor.channel}
|
||||||
|
</span>
|
||||||
|
${this.supervisor.supervisor.channel === "beta"
|
||||||
|
? html`
|
||||||
|
<ha-progress-button
|
||||||
|
@click=${this._toggleBeta}
|
||||||
|
title="Get stable updates for Home Assistant, supervisor and host"
|
||||||
|
>
|
||||||
|
Leave beta channel
|
||||||
|
</ha-progress-button>
|
||||||
|
`
|
||||||
|
: this.supervisor.supervisor.channel === "stable"
|
||||||
|
? html`
|
||||||
|
<ha-progress-button
|
||||||
|
@click=${this._toggleBeta}
|
||||||
|
title="Get beta updates for Home Assistant (RCs), supervisor and host"
|
||||||
|
>
|
||||||
|
Join beta channel
|
||||||
|
</ha-progress-button>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
</ha-settings-row>
|
||||||
|
|
||||||
|
${this.supervisor.supervisor.supported
|
||||||
|
? html` <ha-settings-row three-line>
|
||||||
|
<span slot="heading">
|
||||||
|
Share Diagnostics
|
||||||
|
</span>
|
||||||
|
<div slot="description" class="diagnostics-description">
|
||||||
|
Share crash reports and diagnostic information.
|
||||||
|
<button
|
||||||
|
class="link"
|
||||||
|
title="Show more information about this"
|
||||||
|
@click=${this._diagnosticsInformationDialog}
|
||||||
|
>
|
||||||
|
Learn more
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<ha-switch
|
||||||
|
haptic
|
||||||
|
.checked=${this.supervisor.supervisor.diagnostics}
|
||||||
|
@change=${this._toggleDiagnostics}
|
||||||
|
></ha-switch>
|
||||||
|
</ha-settings-row>`
|
||||||
|
: html`<div class="error">
|
||||||
|
You are running an unsupported installation.
|
||||||
|
<button
|
||||||
|
class="link"
|
||||||
|
title="Learn more about how you can make your system compliant"
|
||||||
|
@click=${this._unsupportedDialog}
|
||||||
|
>
|
||||||
|
Learn more
|
||||||
|
</button>
|
||||||
|
</div>`}
|
||||||
|
${!this.supervisor.supervisor.healthy
|
||||||
|
? html`<div class="error">
|
||||||
|
Your installtion is running in an unhealthy state.
|
||||||
|
<button
|
||||||
|
class="link"
|
||||||
|
title="Learn more about why your system is marked as unhealthy"
|
||||||
|
@click=${this._unhealthyDialog}
|
||||||
|
>
|
||||||
|
Learn more
|
||||||
|
</button>
|
||||||
|
</div>`
|
||||||
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<ha-progress-button
|
<ha-progress-button
|
||||||
@click=${this._supervisorReload}
|
@click=${this._supervisorReload}
|
||||||
title="Reload parts of the Supervisor"
|
title="Reload parts of the Supervisor"
|
||||||
>
|
>
|
||||||
Reload Supervisor
|
Reload
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
<ha-progress-button
|
<ha-progress-button
|
||||||
class="warning"
|
class="warning"
|
||||||
@click=${this._supervisorRestart}
|
@click=${this._supervisorRestart}
|
||||||
title="Restart the Supervisor"
|
title="Restart the Supervisor"
|
||||||
>
|
>
|
||||||
Restart Supervisor
|
Restart
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
</div>
|
</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(): void {
|
|
||||||
this._loadData();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _loadData(): Promise<void> {
|
|
||||||
this._metrics = await fetchHassioStats(this.hass, "supervisor");
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _toggleBeta(ev: CustomEvent): Promise<void> {
|
private async _toggleBeta(ev: CustomEvent): Promise<void> {
|
||||||
const button = ev.currentTarget as any;
|
const button = ev.currentTarget as any;
|
||||||
button.progress = true;
|
button.progress = true;
|
||||||
@@ -326,18 +282,6 @@ class HassioSupervisorInfo extends LitElement {
|
|||||||
const button = ev.currentTarget as any;
|
const button = ev.currentTarget as any;
|
||||||
button.progress = true;
|
button.progress = true;
|
||||||
|
|
||||||
const confirmed = await showConfirmationDialog(this, {
|
|
||||||
title: "Restart the Supervisor",
|
|
||||||
text: "Are you sure you want to restart the Supervisor",
|
|
||||||
confirmText: "restart",
|
|
||||||
dismissText: "cancel",
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!confirmed) {
|
|
||||||
button.progress = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await restartSupervisor(this.hass);
|
await restartSupervisor(this.hass);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -482,15 +426,6 @@ class HassioSupervisorInfo extends LitElement {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.card-content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: calc(100% - 124px);
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
.metrics-block {
|
|
||||||
margin-top: 16px;
|
|
||||||
}
|
|
||||||
button.link {
|
button.link {
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
185
hassio/src/system/hassio-system-metrics.ts
Normal file
185
hassio/src/system/hassio-system-metrics.ts
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
import "@material/mwc-button";
|
||||||
|
import "@material/mwc-list/mwc-list-item";
|
||||||
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
internalProperty,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
|
TemplateResult,
|
||||||
|
} from "lit-element";
|
||||||
|
import { classMap } from "lit-html/directives/class-map";
|
||||||
|
import memoizeOne from "memoize-one";
|
||||||
|
import "../../../src/components/buttons/ha-progress-button";
|
||||||
|
import "../../../src/components/ha-bar";
|
||||||
|
import "../../../src/components/ha-button-menu";
|
||||||
|
import "../../../src/components/ha-card";
|
||||||
|
import "../../../src/components/ha-settings-row";
|
||||||
|
import { fetchHassioStats, HassioStats } from "../../../src/data/hassio/common";
|
||||||
|
import { HassioHostInfo } from "../../../src/data/hassio/host";
|
||||||
|
import { Supervisor } from "../../../src/data/supervisor/supervisor";
|
||||||
|
import { haStyle } from "../../../src/resources/styles";
|
||||||
|
import { HomeAssistant } from "../../../src/types";
|
||||||
|
import { bytesToString } from "../../../src/util/bytes-to-string";
|
||||||
|
import {
|
||||||
|
getValueInPercentage,
|
||||||
|
roundWithOneDecimal,
|
||||||
|
} from "../../../src/util/calculate";
|
||||||
|
import { hassioStyle } from "../resources/hassio-style";
|
||||||
|
|
||||||
|
@customElement("hassio-system-metrics")
|
||||||
|
class HassioSystemMetrics extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
|
@internalProperty() private _supervisorMetrics?: HassioStats;
|
||||||
|
|
||||||
|
@internalProperty() private _coreMetrics?: HassioStats;
|
||||||
|
|
||||||
|
protected render(): TemplateResult | void {
|
||||||
|
const metrics = [
|
||||||
|
{
|
||||||
|
description: "Core CPU Usage",
|
||||||
|
value: this._coreMetrics?.cpu_percent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Core RAM Usage",
|
||||||
|
value: this._coreMetrics?.memory_percent,
|
||||||
|
tooltip: `${bytesToString(
|
||||||
|
this._coreMetrics?.memory_usage
|
||||||
|
)}/${bytesToString(this._coreMetrics?.memory_limit)}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Supervisor CPU Usage",
|
||||||
|
value: this._supervisorMetrics?.cpu_percent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Supervisor RAM Usage",
|
||||||
|
value: this._supervisorMetrics?.memory_percent,
|
||||||
|
tooltip: `${bytesToString(
|
||||||
|
this._supervisorMetrics?.memory_usage
|
||||||
|
)}/${bytesToString(this._supervisorMetrics?.memory_limit)}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Used Space",
|
||||||
|
value: this._getUsedSpace(this.supervisor.host),
|
||||||
|
tooltip: `${this.supervisor.host.disk_used} GB/${this.supervisor.host.disk_total} GB`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-card header="System Metrics">
|
||||||
|
<div class="card-content">
|
||||||
|
${metrics.map((metric) =>
|
||||||
|
this._renderMetric(
|
||||||
|
metric.description,
|
||||||
|
metric.value ?? 0,
|
||||||
|
metric.tooltip
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected firstUpdated(): void {
|
||||||
|
this._loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private _renderMetric(
|
||||||
|
description: string,
|
||||||
|
value: number,
|
||||||
|
tooltip?: string
|
||||||
|
): TemplateResult {
|
||||||
|
const roundedValue = roundWithOneDecimal(value);
|
||||||
|
return html`<ha-settings-row>
|
||||||
|
<span slot="heading">
|
||||||
|
${description}
|
||||||
|
</span>
|
||||||
|
<div slot="description" title="${tooltip ?? ""}">
|
||||||
|
<span class="value">
|
||||||
|
${roundedValue}%
|
||||||
|
</span>
|
||||||
|
<ha-bar
|
||||||
|
class="${classMap({
|
||||||
|
"target-warning": roundedValue > 50,
|
||||||
|
"target-critical": roundedValue > 85,
|
||||||
|
})}"
|
||||||
|
.value=${value}
|
||||||
|
></ha-bar>
|
||||||
|
</div>
|
||||||
|
</ha-settings-row>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getUsedSpace = memoizeOne((hostInfo: HassioHostInfo) =>
|
||||||
|
roundWithOneDecimal(
|
||||||
|
getValueInPercentage(hostInfo.disk_used, 0, hostInfo.disk_total)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
private async _loadData(): Promise<void> {
|
||||||
|
const [supervisor, core] = await Promise.all([
|
||||||
|
fetchHassioStats(this.hass, "supervisor"),
|
||||||
|
fetchHassioStats(this.hass, "core"),
|
||||||
|
]);
|
||||||
|
this._supervisorMetrics = supervisor;
|
||||||
|
this._coreMetrics = core;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResult[] {
|
||||||
|
return [
|
||||||
|
haStyle,
|
||||||
|
hassioStyle,
|
||||||
|
css`
|
||||||
|
ha-card {
|
||||||
|
height: 100%;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-direction: column;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
ha-settings-row {
|
||||||
|
padding: 0;
|
||||||
|
height: 54px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
ha-settings-row > div[slot="description"] {
|
||||||
|
white-space: normal;
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
ha-bar {
|
||||||
|
--ha-bar-primary-color: var(
|
||||||
|
--hassio-bar-ok-color,
|
||||||
|
var(--success-color)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.target-warning {
|
||||||
|
--ha-bar-primary-color: var(
|
||||||
|
--hassio-bar-warning-color,
|
||||||
|
var(--warning-color)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.target-critical {
|
||||||
|
--ha-bar-primary-color: var(
|
||||||
|
--hassio-bar-critical-color,
|
||||||
|
var(--error-color)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.value {
|
||||||
|
width: 42px;
|
||||||
|
padding-right: 4px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"hassio-system-metrics": HassioSystemMetrics;
|
||||||
|
}
|
||||||
|
}
|
@@ -13,10 +13,10 @@ import { haStyle } from "../../../src/resources/styles";
|
|||||||
import { HomeAssistant, Route } from "../../../src/types";
|
import { HomeAssistant, Route } from "../../../src/types";
|
||||||
import { supervisorTabs } from "../hassio-tabs";
|
import { supervisorTabs } from "../hassio-tabs";
|
||||||
import { hassioStyle } from "../resources/hassio-style";
|
import { hassioStyle } from "../resources/hassio-style";
|
||||||
import "./hassio-core-info";
|
|
||||||
import "./hassio-host-info";
|
import "./hassio-host-info";
|
||||||
import "./hassio-supervisor-info";
|
import "./hassio-supervisor-info";
|
||||||
import "./hassio-supervisor-log";
|
import "./hassio-supervisor-log";
|
||||||
|
import "./hassio-system-metrics";
|
||||||
|
|
||||||
@customElement("hassio-system")
|
@customElement("hassio-system")
|
||||||
class HassioSystem extends LitElement {
|
class HassioSystem extends LitElement {
|
||||||
@@ -41,10 +41,6 @@ class HassioSystem extends LitElement {
|
|||||||
<span slot="header">System</span>
|
<span slot="header">System</span>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="card-group">
|
<div class="card-group">
|
||||||
<hassio-core-info
|
|
||||||
.hass=${this.hass}
|
|
||||||
.supervisor=${this.supervisor}
|
|
||||||
></hassio-core-info>
|
|
||||||
<hassio-supervisor-info
|
<hassio-supervisor-info
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.supervisor=${this.supervisor}
|
.supervisor=${this.supervisor}
|
||||||
@@ -53,6 +49,10 @@ class HassioSystem extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.supervisor=${this.supervisor}
|
.supervisor=${this.supervisor}
|
||||||
></hassio-host-info>
|
></hassio-host-info>
|
||||||
|
<hassio-system-metrics
|
||||||
|
.hass=${this.hass}
|
||||||
|
.supervisor=${this.supervisor}
|
||||||
|
></hassio-system-metrics>
|
||||||
</div>
|
</div>
|
||||||
<hassio-supervisor-log .hass=${this.hass}></hassio-supervisor-log>
|
<hassio-supervisor-log .hass=${this.hass}></hassio-supervisor-log>
|
||||||
</div>
|
</div>
|
||||||
|
34
package.json
34
package.json
@@ -29,22 +29,22 @@
|
|||||||
"@fullcalendar/daygrid": "5.1.0",
|
"@fullcalendar/daygrid": "5.1.0",
|
||||||
"@fullcalendar/interaction": "5.1.0",
|
"@fullcalendar/interaction": "5.1.0",
|
||||||
"@fullcalendar/list": "5.1.0",
|
"@fullcalendar/list": "5.1.0",
|
||||||
"@material/chips": "=9.0.0-canary.1c156d69d.0",
|
"@material/chips": "=8.0.0-canary.774dcfc8e.0",
|
||||||
"@material/mwc-button": "^0.20.0",
|
"@material/mwc-button": "^0.19.0",
|
||||||
"@material/mwc-checkbox": "^0.20.0",
|
"@material/mwc-checkbox": "^0.19.0",
|
||||||
"@material/mwc-circular-progress": "^0.20.0",
|
"@material/mwc-circular-progress": "^0.19.0",
|
||||||
"@material/mwc-dialog": "^0.20.0",
|
"@material/mwc-dialog": "^0.19.0",
|
||||||
"@material/mwc-fab": "^0.20.0",
|
"@material/mwc-fab": "^0.19.0",
|
||||||
"@material/mwc-formfield": "^0.20.0",
|
"@material/mwc-formfield": "^0.19.0",
|
||||||
"@material/mwc-icon-button": "^0.20.0",
|
"@material/mwc-icon-button": "^0.19.0",
|
||||||
"@material/mwc-list": "^0.20.0",
|
"@material/mwc-list": "^0.19.0",
|
||||||
"@material/mwc-menu": "^0.20.0",
|
"@material/mwc-menu": "^0.19.0",
|
||||||
"@material/mwc-radio": "^0.20.0",
|
"@material/mwc-radio": "^0.19.0",
|
||||||
"@material/mwc-ripple": "^0.20.0",
|
"@material/mwc-ripple": "^0.19.0",
|
||||||
"@material/mwc-switch": "^0.20.0",
|
"@material/mwc-switch": "^0.19.0",
|
||||||
"@material/mwc-tab": "^0.20.0",
|
"@material/mwc-tab": "^0.19.0",
|
||||||
"@material/mwc-tab-bar": "^0.20.0",
|
"@material/mwc-tab-bar": "^0.19.0",
|
||||||
"@material/top-app-bar": "=9.0.0-canary.1c156d69d.0",
|
"@material/top-app-bar": "=8.0.0-canary.774dcfc8e.0",
|
||||||
"@mdi/js": "5.6.55",
|
"@mdi/js": "5.6.55",
|
||||||
"@mdi/svg": "5.6.55",
|
"@mdi/svg": "5.6.55",
|
||||||
"@polymer/app-layout": "^3.0.2",
|
"@polymer/app-layout": "^3.0.2",
|
||||||
@@ -120,7 +120,7 @@
|
|||||||
"resize-observer-polyfill": "^1.5.1",
|
"resize-observer-polyfill": "^1.5.1",
|
||||||
"roboto-fontface": "^0.10.0",
|
"roboto-fontface": "^0.10.0",
|
||||||
"sortablejs": "^1.10.2",
|
"sortablejs": "^1.10.2",
|
||||||
"superstruct": "^0.10.13",
|
"superstruct": "^0.10.12",
|
||||||
"tinykeys": "^1.1.1",
|
"tinykeys": "^1.1.1",
|
||||||
"unfetch": "^4.1.0",
|
"unfetch": "^4.1.0",
|
||||||
"vis-data": "^7.1.1",
|
"vis-data": "^7.1.1",
|
||||||
|
2
setup.py
2
setup.py
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="home-assistant-frontend",
|
name="home-assistant-frontend",
|
||||||
version="20210127.1",
|
version="20201126.0",
|
||||||
description="The Home Assistant frontend",
|
description="The Home Assistant frontend",
|
||||||
url="https://github.com/home-assistant/home-assistant-polymer",
|
url="https://github.com/home-assistant/home-assistant-polymer",
|
||||||
author="The Home Assistant Authors",
|
author="The Home Assistant Authors",
|
||||||
|
@@ -3,9 +3,9 @@ import {
|
|||||||
css,
|
css,
|
||||||
CSSResult,
|
CSSResult,
|
||||||
html,
|
html,
|
||||||
internalProperty,
|
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
|
internalProperty,
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
|
@@ -2,25 +2,21 @@ import {
|
|||||||
css,
|
css,
|
||||||
CSSResult,
|
CSSResult,
|
||||||
html,
|
html,
|
||||||
internalProperty,
|
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
|
internalProperty,
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import punycode from "punycode";
|
|
||||||
import { extractSearchParamsObject } from "../common/url/search-params";
|
|
||||||
import {
|
import {
|
||||||
AuthProvider,
|
AuthProvider,
|
||||||
AuthUrlSearchParams,
|
|
||||||
fetchAuthProviders,
|
fetchAuthProviders,
|
||||||
|
AuthUrlSearchParams,
|
||||||
} from "../data/auth";
|
} from "../data/auth";
|
||||||
import {
|
|
||||||
DiscoveryInformation,
|
|
||||||
fetchDiscoveryInformation,
|
|
||||||
} from "../data/discovery";
|
|
||||||
import { litLocalizeLiteMixin } from "../mixins/lit-localize-lite-mixin";
|
import { litLocalizeLiteMixin } from "../mixins/lit-localize-lite-mixin";
|
||||||
import { registerServiceWorker } from "../util/register-service-worker";
|
import { registerServiceWorker } from "../util/register-service-worker";
|
||||||
import "./ha-auth-flow";
|
import "./ha-auth-flow";
|
||||||
|
import { extractSearchParamsObject } from "../common/url/search-params";
|
||||||
|
import punycode from "punycode";
|
||||||
|
|
||||||
import("./ha-pick-auth-provider");
|
import("./ha-pick-auth-provider");
|
||||||
|
|
||||||
@@ -35,8 +31,6 @@ class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
|||||||
|
|
||||||
@internalProperty() private _authProviders?: AuthProvider[];
|
@internalProperty() private _authProviders?: AuthProvider[];
|
||||||
|
|
||||||
@internalProperty() private _discovery?: DiscoveryInformation;
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.translationFragment = "page-authorize";
|
this.translationFragment = "page-authorize";
|
||||||
@@ -64,17 +58,14 @@ class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
|||||||
// the name with a bold tag.
|
// the name with a bold tag.
|
||||||
const loggingInWith = document.createElement("div");
|
const loggingInWith = document.createElement("div");
|
||||||
loggingInWith.innerText = this.localize(
|
loggingInWith.innerText = this.localize(
|
||||||
this._discovery?.location_name
|
"ui.panel.page-authorize.logging_in_with",
|
||||||
? "ui.panel.page-authorize.logging_in_to_with"
|
|
||||||
: "ui.panel.page-authorize.logging_in_with",
|
|
||||||
"locationName",
|
|
||||||
"LOCATION",
|
|
||||||
"authProviderName",
|
"authProviderName",
|
||||||
"NAME"
|
"NAME"
|
||||||
);
|
);
|
||||||
loggingInWith.innerHTML = loggingInWith.innerHTML
|
loggingInWith.innerHTML = loggingInWith.innerHTML.replace(
|
||||||
.replace("**LOCATION**", `<b>${this._discovery?.location_name}</b>`)
|
"**NAME**",
|
||||||
.replace("**NAME**", `<b>${this._authProvider!.name}</b>`);
|
`<b>${this._authProvider!.name}</b>`
|
||||||
|
);
|
||||||
|
|
||||||
const inactiveProviders = this._authProviders.filter(
|
const inactiveProviders = this._authProviders.filter(
|
||||||
(prv) => prv !== this._authProvider
|
(prv) => prv !== this._authProvider
|
||||||
@@ -114,7 +105,6 @@ class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
|||||||
protected firstUpdated(changedProps: PropertyValues) {
|
protected firstUpdated(changedProps: PropertyValues) {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
this._fetchAuthProviders();
|
this._fetchAuthProviders();
|
||||||
this._fetchDiscoveryInfo();
|
|
||||||
|
|
||||||
if (!this.redirectUri) {
|
if (!this.redirectUri) {
|
||||||
return;
|
return;
|
||||||
@@ -136,10 +126,6 @@ class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _fetchDiscoveryInfo() {
|
|
||||||
this._discovery = await fetchDiscoveryInformation();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _fetchAuthProviders() {
|
private async _fetchAuthProviders() {
|
||||||
// Fetch auth providers
|
// Fetch auth providers
|
||||||
try {
|
try {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
|
import { isComponentLoaded } from "./is_component_loaded";
|
||||||
import { PageNavigation } from "../../layouts/hass-tabs-subpage";
|
import { PageNavigation } from "../../layouts/hass-tabs-subpage";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { isComponentLoaded } from "./is_component_loaded";
|
|
||||||
|
|
||||||
export const canShowPage = (hass: HomeAssistant, page: PageNavigation) => {
|
export const canShowPage = (hass: HomeAssistant, page: PageNavigation) => {
|
||||||
return (
|
return (
|
||||||
|
@@ -4,4 +4,4 @@ import { HomeAssistant } from "../../types";
|
|||||||
export const isComponentLoaded = (
|
export const isComponentLoaded = (
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
component: string
|
component: string
|
||||||
): boolean => hass && hass.config.components.includes(component);
|
): boolean => hass && hass.config.components.indexOf(component) !== -1;
|
||||||
|
@@ -34,7 +34,6 @@ export const FIXED_DOMAIN_ICONS = {
|
|||||||
light: "hass:lightbulb",
|
light: "hass:lightbulb",
|
||||||
mailbox: "hass:mailbox",
|
mailbox: "hass:mailbox",
|
||||||
notify: "hass:comment-alert",
|
notify: "hass:comment-alert",
|
||||||
number: "hass:ray-vertex",
|
|
||||||
persistent_notification: "hass:bell",
|
persistent_notification: "hass:bell",
|
||||||
person: "hass:account",
|
person: "hass:account",
|
||||||
plant: "hass:flower",
|
plant: "hass:flower",
|
||||||
@@ -78,7 +77,6 @@ export const DOMAINS_WITH_CARD = [
|
|||||||
"input_text",
|
"input_text",
|
||||||
"lock",
|
"lock",
|
||||||
"media_player",
|
"media_player",
|
||||||
"number",
|
|
||||||
"scene",
|
"scene",
|
||||||
"script",
|
"script",
|
||||||
"timer",
|
"timer",
|
||||||
@@ -116,7 +114,6 @@ export const DOMAINS_HIDE_MORE_INFO = [
|
|||||||
"input_number",
|
"input_number",
|
||||||
"input_select",
|
"input_select",
|
||||||
"input_text",
|
"input_text",
|
||||||
"number",
|
|
||||||
"scene",
|
"scene",
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -141,9 +138,6 @@ export const DOMAINS_TOGGLE = new Set([
|
|||||||
"humidifier",
|
"humidifier",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/** Domains that have a dynamic entity image / picture. */
|
|
||||||
export const DOMAINS_WITH_DYNAMIC_PICTURE = new Set(["camera", "media_player"]);
|
|
||||||
|
|
||||||
/** Temperature units. */
|
/** Temperature units. */
|
||||||
export const UNIT_C = "°C";
|
export const UNIT_C = "°C";
|
||||||
export const UNIT_F = "°F";
|
export const UNIT_F = "°F";
|
||||||
|
@@ -1,7 +0,0 @@
|
|||||||
export default function checkValidDate(date?: Date): boolean {
|
|
||||||
if (!date) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return date instanceof Date && !isNaN(date.valueOf());
|
|
||||||
}
|
|
@@ -9,12 +9,3 @@ export const formatDate = toLocaleDateStringSupportsOptions
|
|||||||
day: "numeric",
|
day: "numeric",
|
||||||
})
|
})
|
||||||
: (dateObj: Date) => format(dateObj, "longDate");
|
: (dateObj: Date) => format(dateObj, "longDate");
|
||||||
|
|
||||||
export const formatDateWeekday = toLocaleDateStringSupportsOptions
|
|
||||||
? (dateObj: Date, locales: string) =>
|
|
||||||
dateObj.toLocaleDateString(locales, {
|
|
||||||
weekday: "long",
|
|
||||||
month: "short",
|
|
||||||
day: "numeric",
|
|
||||||
})
|
|
||||||
: (dateObj: Date) => format(dateObj, "dddd, MMM D");
|
|
||||||
|
@@ -17,12 +17,3 @@ export const formatTimeWithSeconds = toLocaleTimeStringSupportsOptions
|
|||||||
second: "2-digit",
|
second: "2-digit",
|
||||||
})
|
})
|
||||||
: (dateObj: Date) => format(dateObj, "mediumTime");
|
: (dateObj: Date) => format(dateObj, "mediumTime");
|
||||||
|
|
||||||
export const formatTimeWeekday = toLocaleTimeStringSupportsOptions
|
|
||||||
? (dateObj: Date, locales: string) =>
|
|
||||||
dateObj.toLocaleTimeString(locales, {
|
|
||||||
weekday: "long",
|
|
||||||
hour: "numeric",
|
|
||||||
minute: "2-digit",
|
|
||||||
})
|
|
||||||
: (dateObj: Date) => format(dateObj, "dddd, HH:mm");
|
|
||||||
|
@@ -1,6 +0,0 @@
|
|||||||
export const ensureArray = (value?: any) => {
|
|
||||||
if (!value || Array.isArray(value)) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
return [value];
|
|
||||||
};
|
|
@@ -3,9 +3,9 @@ import { UNAVAILABLE, UNKNOWN } from "../../data/entity";
|
|||||||
import { formatDate } from "../datetime/format_date";
|
import { formatDate } from "../datetime/format_date";
|
||||||
import { formatDateTime } from "../datetime/format_date_time";
|
import { formatDateTime } from "../datetime/format_date_time";
|
||||||
import { formatTime } from "../datetime/format_time";
|
import { formatTime } from "../datetime/format_time";
|
||||||
import { formatNumber } from "../string/format_number";
|
|
||||||
import { LocalizeFunc } from "../translations/localize";
|
import { LocalizeFunc } from "../translations/localize";
|
||||||
import { computeStateDomain } from "./compute_state_domain";
|
import { computeStateDomain } from "./compute_state_domain";
|
||||||
|
import { formatNumber } from "../string/format_number";
|
||||||
|
|
||||||
export const computeStateDisplay = (
|
export const computeStateDisplay = (
|
||||||
localize: LocalizeFunc,
|
localize: LocalizeFunc,
|
||||||
@@ -63,14 +63,10 @@ export const computeStateDisplay = (
|
|||||||
|
|
||||||
if (domain === "humidifier") {
|
if (domain === "humidifier") {
|
||||||
if (compareState === "on" && stateObj.attributes.humidity) {
|
if (compareState === "on" && stateObj.attributes.humidity) {
|
||||||
return `${stateObj.attributes.humidity} %`;
|
return `${stateObj.attributes.humidity}%`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (domain === "counter") {
|
|
||||||
return formatNumber(compareState, language);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// Return device class translation
|
// Return device class translation
|
||||||
(stateObj.attributes.device_class &&
|
(stateObj.attributes.device_class &&
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
import { HassEntity } from "home-assistant-js-websocket";
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
import { UNAVAILABLE } from "../../data/entity";
|
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { DOMAINS_WITH_CARD } from "../const";
|
import { DOMAINS_WITH_CARD } from "../const";
|
||||||
import { canToggleState } from "./can_toggle_state";
|
import { canToggleState } from "./can_toggle_state";
|
||||||
import { computeStateDomain } from "./compute_state_domain";
|
import { computeStateDomain } from "./compute_state_domain";
|
||||||
|
import { UNAVAILABLE } from "../../data/entity";
|
||||||
|
|
||||||
export const stateCardType = (hass: HomeAssistant, stateObj: HassEntity) => {
|
export const stateCardType = (hass: HomeAssistant, stateObj: HassEntity) => {
|
||||||
if (stateObj.state === UNAVAILABLE) {
|
if (stateObj.state === UNAVAILABLE) {
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// We import the minified bundle because the unminified bundle
|
import Vibrant from "node-vibrant/lib/browser";
|
||||||
// has some quirks that break wds. See #7784 for unminified version.
|
import MMCQ from "@vibrant/quantizer-mmcq";
|
||||||
import Vibrant from "node-vibrant/dist/vibrant";
|
import { BasicPipeline } from "@vibrant/core/lib/pipeline";
|
||||||
import type { Swatch, Vec3 } from "@vibrant/color";
|
import { Swatch, Vec3 } from "@vibrant/color";
|
||||||
import { getRGBContrastRatio } from "../color/rgb";
|
import { getRGBContrastRatio } from "../color/rgb";
|
||||||
|
|
||||||
const CONTRAST_RATIO = 4.5;
|
const CONTRAST_RATIO = 4.5;
|
||||||
@@ -104,15 +104,23 @@ const customGenerator = (colors: Swatch[]) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// We can't import Swatch constructor from the minified bundle, take it from background color.
|
foreground: new Swatch(foregroundColor, 0),
|
||||||
// @ts-expect-error
|
|
||||||
foreground: new backgroundColor.constructor(foregroundColor, 0),
|
|
||||||
background: backgroundColor,
|
background: backgroundColor,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set our custom generator as the default.
|
Vibrant.use(
|
||||||
Vibrant._pipeline.generator.register("default", customGenerator);
|
new BasicPipeline().filter
|
||||||
|
.register(
|
||||||
|
"default",
|
||||||
|
(r: number, g: number, b: number, a: number) =>
|
||||||
|
a >= 125 && !(r > 250 && g > 250 && b > 250)
|
||||||
|
)
|
||||||
|
.quantizer.register("mmcq", MMCQ)
|
||||||
|
// Our generator has different output
|
||||||
|
// @ts-expect-error
|
||||||
|
.generator.register("default", customGenerator)
|
||||||
|
);
|
||||||
|
|
||||||
export const extractColors = (url: string, downsampleColors = 16) =>
|
export const extractColors = (url: string, downsampleColors = 16) =>
|
||||||
new Vibrant(url, {
|
new Vibrant(url, {
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
import "@material/mwc-icon-button/mwc-icon-button";
|
|
||||||
import { mdiClose, mdiMagnify } from "@mdi/js";
|
|
||||||
import "@polymer/paper-input/paper-input";
|
import "@polymer/paper-input/paper-input";
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
@@ -12,6 +10,8 @@ import { html, TemplateResult } from "lit-html";
|
|||||||
import { classMap } from "lit-html/directives/class-map";
|
import { classMap } from "lit-html/directives/class-map";
|
||||||
import "../../components/ha-svg-icon";
|
import "../../components/ha-svg-icon";
|
||||||
import { fireEvent } from "../dom/fire_event";
|
import { fireEvent } from "../dom/fire_event";
|
||||||
|
import { mdiMagnify, mdiClose } from "@mdi/js";
|
||||||
|
import "@material/mwc-icon-button/mwc-icon-button";
|
||||||
|
|
||||||
@customElement("search-input")
|
@customElement("search-input")
|
||||||
class SearchInput extends LitElement {
|
class SearchInput extends LitElement {
|
||||||
|
@@ -1,45 +0,0 @@
|
|||||||
import { StructError } from "superstruct";
|
|
||||||
import type { HomeAssistant } from "../../types";
|
|
||||||
|
|
||||||
export const handleStructError = (
|
|
||||||
hass: HomeAssistant,
|
|
||||||
err: Error
|
|
||||||
): { warnings: string[]; errors?: string[] } => {
|
|
||||||
if (!(err instanceof StructError)) {
|
|
||||||
return { warnings: [err.message], errors: undefined };
|
|
||||||
}
|
|
||||||
const errors: string[] = [];
|
|
||||||
const warnings: string[] = [];
|
|
||||||
for (const failure of err.failures()) {
|
|
||||||
if (failure.value === undefined) {
|
|
||||||
errors.push(
|
|
||||||
hass.localize(
|
|
||||||
"ui.errors.config.key_missing",
|
|
||||||
"key",
|
|
||||||
failure.path.join(".")
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else if (failure.type === "never") {
|
|
||||||
warnings.push(
|
|
||||||
hass.localize(
|
|
||||||
"ui.errors.config.key_not_expected",
|
|
||||||
"key",
|
|
||||||
failure.path.join(".")
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
warnings.push(
|
|
||||||
hass.localize(
|
|
||||||
"ui.errors.config.key_wrong_type",
|
|
||||||
"key",
|
|
||||||
failure.path.join("."),
|
|
||||||
"type_correct",
|
|
||||||
failure.type,
|
|
||||||
"type_wrong",
|
|
||||||
JSON.stringify(failure.value)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return { warnings, errors };
|
|
||||||
};
|
|
@@ -1,30 +0,0 @@
|
|||||||
import { struct, StructContext, StructResult } from "superstruct";
|
|
||||||
|
|
||||||
const isEntityId = (value: unknown, context: StructContext): StructResult => {
|
|
||||||
if (typeof value !== "string") {
|
|
||||||
return [context.fail({ type: "string" })];
|
|
||||||
}
|
|
||||||
if (!value.includes(".")) {
|
|
||||||
return [
|
|
||||||
context.fail({
|
|
||||||
type: "Entity ID should be in the format 'domain.entity'",
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const EntityId = struct("entity-id", isEntityId);
|
|
||||||
|
|
||||||
const isEntityIdOrAll = (
|
|
||||||
value: unknown,
|
|
||||||
context: StructContext
|
|
||||||
): StructResult => {
|
|
||||||
if (typeof value === "string" && value === "all") {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return isEntityId(value, context);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const EntityIdOrAll = struct("entity-id-all", isEntityIdOrAll);
|
|
@@ -1,5 +1,5 @@
|
|||||||
import { shouldPolyfill } from "@formatjs/intl-pluralrules/should-polyfill";
|
|
||||||
import IntlMessageFormat from "intl-messageformat";
|
import IntlMessageFormat from "intl-messageformat";
|
||||||
|
import { shouldPolyfill } from "@formatjs/intl-pluralrules/should-polyfill";
|
||||||
import { Resources } from "../../types";
|
import { Resources } from "../../types";
|
||||||
|
|
||||||
export type LocalizeFunc = (key: string, ...args: any[]) => string;
|
export type LocalizeFunc = (key: string, ...args: any[]) => string;
|
||||||
|
@@ -1,13 +1,4 @@
|
|||||||
export const copyToClipboard = async (str) => {
|
export const copyToClipboard = (str) => {
|
||||||
if (navigator.clipboard) {
|
|
||||||
try {
|
|
||||||
await navigator.clipboard.writeText(str);
|
|
||||||
return;
|
|
||||||
} catch {
|
|
||||||
// just continue with the fallback coding below
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const el = document.createElement("textarea");
|
const el = document.createElement("textarea");
|
||||||
el.value = str;
|
el.value = str;
|
||||||
document.body.appendChild(el);
|
document.body.appendChild(el);
|
||||||
|
@@ -7,9 +7,10 @@ import {
|
|||||||
html,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
query,
|
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
|
query,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
|
|
||||||
import "../ha-circular-progress";
|
import "../ha-circular-progress";
|
||||||
|
|
||||||
@customElement("ha-progress-button")
|
@customElement("ha-progress-button")
|
||||||
|
@@ -98,12 +98,6 @@ export class HaDataTable extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public hasFab = false;
|
@property({ type: Boolean }) public hasFab = false;
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an extra row at the bottom of the data table
|
|
||||||
* @type {TemplateResult}
|
|
||||||
*/
|
|
||||||
@property({ attribute: false }) public appendRow?;
|
|
||||||
|
|
||||||
@property({ type: Boolean, attribute: "auto-height" })
|
@property({ type: Boolean, attribute: "auto-height" })
|
||||||
public autoHeight = false;
|
public autoHeight = false;
|
||||||
|
|
||||||
@@ -132,8 +126,6 @@ export class HaDataTable extends LitElement {
|
|||||||
|
|
||||||
@query("slot[name='header']") private _header!: HTMLSlotElement;
|
@query("slot[name='header']") private _header!: HTMLSlotElement;
|
||||||
|
|
||||||
private _items: DataTableRowData[] = [];
|
|
||||||
|
|
||||||
private _checkableRowsCount?: number;
|
private _checkableRowsCount?: number;
|
||||||
|
|
||||||
private _checkedRows: string[] = [];
|
private _checkedRows: string[] = [];
|
||||||
@@ -326,13 +318,10 @@ export class HaDataTable extends LitElement {
|
|||||||
@scroll=${this._saveScrollPos}
|
@scroll=${this._saveScrollPos}
|
||||||
>
|
>
|
||||||
${scroll({
|
${scroll({
|
||||||
items: this._items,
|
items: !this.hasFab
|
||||||
|
? this._filteredData
|
||||||
|
: [...this._filteredData, ...[{ empty: true }]],
|
||||||
renderItem: (row: DataTableRowData, index) => {
|
renderItem: (row: DataTableRowData, index) => {
|
||||||
if (row.append) {
|
|
||||||
return html`
|
|
||||||
<div class="mdc-data-table__row">${row.content}</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
if (row.empty) {
|
if (row.empty) {
|
||||||
return html` <div class="mdc-data-table__row"></div> `;
|
return html` <div class="mdc-data-table__row"></div> `;
|
||||||
}
|
}
|
||||||
@@ -458,20 +447,6 @@ export class HaDataTable extends LitElement {
|
|||||||
if (this.curRequest !== curRequest) {
|
if (this.curRequest !== curRequest) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.appendRow || this.hasFab) {
|
|
||||||
this._items = [...data];
|
|
||||||
|
|
||||||
if (this.appendRow) {
|
|
||||||
this._items.push({ append: true, content: this.appendRow });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.hasFab) {
|
|
||||||
this._items.push({ empty: true });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this._items = data;
|
|
||||||
}
|
|
||||||
this._filteredData = data;
|
this._filteredData = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import { wrap } from "comlink";
|
import { wrap } from "comlink";
|
||||||
|
|
||||||
import type { api } from "./sort_filter_worker";
|
import type { api } from "./sort_filter_worker";
|
||||||
|
|
||||||
type FilterDataType = api["filterData"];
|
type FilterDataType = api["filterData"];
|
||||||
|
@@ -58,14 +58,6 @@ const sortData = (
|
|||||||
valB = valB.toUpperCase();
|
valB = valB.toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure "undefined" is always sorted to the bottom
|
|
||||||
if (valA === undefined && valB !== undefined) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (valB === undefined && valA !== undefined) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valA < valB) {
|
if (valA < valB) {
|
||||||
return sort * -1;
|
return sort * -1;
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import wrap from "@vue/web-component-wrapper";
|
|
||||||
import { customElement } from "lit-element/lib/decorators";
|
|
||||||
import Vue from "vue";
|
import Vue from "vue";
|
||||||
|
import wrap from "@vue/web-component-wrapper";
|
||||||
import DateRangePicker from "vue2-daterange-picker";
|
import DateRangePicker from "vue2-daterange-picker";
|
||||||
import dateRangePickerStyles from "vue2-daterange-picker/dist/vue2-daterange-picker.css";
|
import dateRangePickerStyles from "vue2-daterange-picker/dist/vue2-daterange-picker.css";
|
||||||
import { fireEvent } from "../common/dom/fire_event";
|
import { fireEvent } from "../common/dom/fire_event";
|
||||||
import { Constructor } from "../types";
|
import { Constructor } from "../types";
|
||||||
|
import { customElement } from "lit-element/lib/decorators";
|
||||||
|
|
||||||
const Component = Vue.extend({
|
const Component = Vue.extend({
|
||||||
props: {
|
props: {
|
||||||
@@ -210,7 +210,7 @@ class DateRangePickerElement extends WrappedElement {
|
|||||||
}
|
}
|
||||||
.calendar-table {
|
.calendar-table {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const shadowRoot = this.shadowRoot!;
|
const shadowRoot = this.shadowRoot!;
|
||||||
shadowRoot.appendChild(style);
|
shadowRoot.appendChild(style);
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import "@material/mwc-button/mwc-button";
|
|
||||||
import "@material/mwc-icon-button/mwc-icon-button";
|
import "@material/mwc-icon-button/mwc-icon-button";
|
||||||
import { mdiClose, mdiMenuDown, mdiMenuUp } from "@mdi/js";
|
import "@material/mwc-button/mwc-button";
|
||||||
import "@polymer/paper-input/paper-input";
|
import "@polymer/paper-input/paper-input";
|
||||||
import "@polymer/paper-item/paper-item";
|
import "@polymer/paper-item/paper-item";
|
||||||
import "@polymer/paper-item/paper-item-body";
|
import "@polymer/paper-item/paper-item-body";
|
||||||
@@ -12,9 +11,9 @@ import {
|
|||||||
CSSResult,
|
CSSResult,
|
||||||
customElement,
|
customElement,
|
||||||
html,
|
html,
|
||||||
internalProperty,
|
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
|
internalProperty,
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
@@ -38,8 +37,9 @@ import {
|
|||||||
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
|
||||||
import { PolymerChangedEvent } from "../../polymer-types";
|
import { PolymerChangedEvent } from "../../polymer-types";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import "../ha-svg-icon";
|
|
||||||
import "./ha-devices-picker";
|
import "./ha-devices-picker";
|
||||||
|
import "../ha-svg-icon";
|
||||||
|
import { mdiClose, mdiMenuDown, mdiMenuUp } from "@mdi/js";
|
||||||
|
|
||||||
interface DevicesByArea {
|
interface DevicesByArea {
|
||||||
[areaId: string]: AreaDevices;
|
[areaId: string]: AreaDevices;
|
||||||
@@ -139,7 +139,7 @@ export class HaAreaDevicesPicker extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
private _filteredDevices: DeviceRegistryEntry[] = [];
|
private _filteredDevices: DeviceRegistryEntry[] = [];
|
||||||
|
|
||||||
private _getAreasWithDevices = memoizeOne(
|
private _getDevices = memoizeOne(
|
||||||
(
|
(
|
||||||
devices: DeviceRegistryEntry[],
|
devices: DeviceRegistryEntry[],
|
||||||
areas: AreaRegistryEntry[],
|
areas: AreaRegistryEntry[],
|
||||||
@@ -277,7 +277,7 @@ export class HaAreaDevicesPicker extends SubscribeMixin(LitElement) {
|
|||||||
if (!this._devices || !this._areas || !this._entities) {
|
if (!this._devices || !this._areas || !this._entities) {
|
||||||
return html``;
|
return html``;
|
||||||
}
|
}
|
||||||
const areas = this._getAreasWithDevices(
|
const areas = this._getDevices(
|
||||||
this._devices,
|
this._devices,
|
||||||
this._areas,
|
this._areas,
|
||||||
this._entities,
|
this._entities,
|
||||||
|
@@ -6,9 +6,9 @@ import {
|
|||||||
css,
|
css,
|
||||||
CSSResult,
|
CSSResult,
|
||||||
html,
|
html,
|
||||||
internalProperty,
|
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
|
internalProperty,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { fireEvent } from "../../common/dom/fire_event";
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
import "@material/mwc-icon-button/mwc-icon-button";
|
import "../ha-icon-button";
|
||||||
import { mdiClose, mdiMenuDown, mdiMenuUp } from "@mdi/js";
|
|
||||||
import "@polymer/paper-input/paper-input";
|
import "@polymer/paper-input/paper-input";
|
||||||
import "@polymer/paper-item/paper-item";
|
import "@polymer/paper-item/paper-item";
|
||||||
import "@polymer/paper-item/paper-item-body";
|
import "@polymer/paper-item/paper-item-body";
|
||||||
@@ -13,8 +12,6 @@ import {
|
|||||||
html,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
PropertyValues,
|
|
||||||
query,
|
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
@@ -38,7 +35,6 @@ import {
|
|||||||
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
|
||||||
import { PolymerChangedEvent } from "../../polymer-types";
|
import { PolymerChangedEvent } from "../../polymer-types";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import "../ha-svg-icon";
|
|
||||||
|
|
||||||
interface Device {
|
interface Device {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -115,10 +111,6 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
|
|||||||
@property({ type: Boolean })
|
@property({ type: Boolean })
|
||||||
private _opened?: boolean;
|
private _opened?: boolean;
|
||||||
|
|
||||||
@query("vaadin-combo-box-light", true) private _comboBox!: HTMLElement;
|
|
||||||
|
|
||||||
private _init = false;
|
|
||||||
|
|
||||||
private _getDevices = memoizeOne(
|
private _getDevices = memoizeOne(
|
||||||
(
|
(
|
||||||
devices: DeviceRegistryEntry[],
|
devices: DeviceRegistryEntry[],
|
||||||
@@ -130,27 +122,18 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
|
|||||||
deviceFilter: this["deviceFilter"]
|
deviceFilter: this["deviceFilter"]
|
||||||
): Device[] => {
|
): Device[] => {
|
||||||
if (!devices.length) {
|
if (!devices.length) {
|
||||||
return [
|
return [];
|
||||||
{
|
|
||||||
id: "",
|
|
||||||
area: "",
|
|
||||||
name: this.hass.localize("ui.components.device-picker.no_devices"),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const deviceEntityLookup: DeviceEntityLookup = {};
|
const deviceEntityLookup: DeviceEntityLookup = {};
|
||||||
|
for (const entity of entities) {
|
||||||
if (includeDomains || excludeDomains || includeDeviceClasses) {
|
if (!entity.device_id) {
|
||||||
for (const entity of entities) {
|
continue;
|
||||||
if (!entity.device_id) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!(entity.device_id in deviceEntityLookup)) {
|
|
||||||
deviceEntityLookup[entity.device_id] = [];
|
|
||||||
}
|
|
||||||
deviceEntityLookup[entity.device_id].push(entity);
|
|
||||||
}
|
}
|
||||||
|
if (!(entity.device_id in deviceEntityLookup)) {
|
||||||
|
deviceEntityLookup[entity.device_id] = [];
|
||||||
|
}
|
||||||
|
deviceEntityLookup[entity.device_id].push(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
const areaLookup: { [areaId: string]: AreaRegistryEntry } = {};
|
const areaLookup: { [areaId: string]: AreaRegistryEntry } = {};
|
||||||
@@ -158,9 +141,7 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
|
|||||||
areaLookup[area.area_id] = area;
|
areaLookup[area.area_id] = area;
|
||||||
}
|
}
|
||||||
|
|
||||||
let inputDevices = devices.filter(
|
let inputDevices = [...devices];
|
||||||
(device) => device.id === this.value || !device.disabled_by
|
|
||||||
);
|
|
||||||
|
|
||||||
if (includeDomains) {
|
if (includeDomains) {
|
||||||
inputDevices = inputDevices.filter((device) => {
|
inputDevices = inputDevices.filter((device) => {
|
||||||
@@ -227,15 +208,6 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
|
|||||||
: this.hass.localize("ui.components.device-picker.no_area"),
|
: this.hass.localize("ui.components.device-picker.no_area"),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
if (!outputDevices.length) {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
id: "",
|
|
||||||
area: "",
|
|
||||||
name: this.hass.localize("ui.components.device-picker.no_match"),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
if (outputDevices.length === 1) {
|
if (outputDevices.length === 1) {
|
||||||
return outputDevices;
|
return outputDevices;
|
||||||
}
|
}
|
||||||
@@ -243,18 +215,6 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
public open() {
|
|
||||||
this.updateComplete.then(() => {
|
|
||||||
(this.shadowRoot?.querySelector("vaadin-combo-box-light") as any)?.open();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public focus() {
|
|
||||||
this.updateComplete.then(() => {
|
|
||||||
this.shadowRoot?.querySelector("paper-input")?.focus();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public hassSubscribe(): UnsubscribeFunc[] {
|
public hassSubscribe(): UnsubscribeFunc[] {
|
||||||
return [
|
return [
|
||||||
subscribeDeviceRegistry(this.hass.connection!, (devices) => {
|
subscribeDeviceRegistry(this.hass.connection!, (devices) => {
|
||||||
@@ -269,33 +229,25 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues) {
|
|
||||||
if (
|
|
||||||
(!this._init && this.devices && this.areas && this.entities) ||
|
|
||||||
(changedProps.has("_opened") && this._opened)
|
|
||||||
) {
|
|
||||||
this._init = true;
|
|
||||||
(this._comboBox as any).items = this._getDevices(
|
|
||||||
this.devices!,
|
|
||||||
this.areas!,
|
|
||||||
this.entities!,
|
|
||||||
this.includeDomains,
|
|
||||||
this.excludeDomains,
|
|
||||||
this.includeDeviceClasses,
|
|
||||||
this.deviceFilter
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (!this.devices || !this.areas || !this.entities) {
|
if (!this.devices || !this.areas || !this.entities) {
|
||||||
return html``;
|
return html``;
|
||||||
}
|
}
|
||||||
|
const devices = this._getDevices(
|
||||||
|
this.devices,
|
||||||
|
this.areas,
|
||||||
|
this.entities,
|
||||||
|
this.includeDomains,
|
||||||
|
this.excludeDomains,
|
||||||
|
this.includeDeviceClasses,
|
||||||
|
this.deviceFilter
|
||||||
|
);
|
||||||
return html`
|
return html`
|
||||||
<vaadin-combo-box-light
|
<vaadin-combo-box-light
|
||||||
item-value-path="id"
|
item-value-path="id"
|
||||||
item-id-path="id"
|
item-id-path="id"
|
||||||
item-label-path="name"
|
item-label-path="name"
|
||||||
|
.items=${devices}
|
||||||
.value=${this._value}
|
.value=${this._value}
|
||||||
.renderer=${rowRenderer}
|
.renderer=${rowRenderer}
|
||||||
@opened-changed=${this._openedChanged}
|
@opened-changed=${this._openedChanged}
|
||||||
@@ -313,30 +265,34 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
|
|||||||
>
|
>
|
||||||
${this.value
|
${this.value
|
||||||
? html`
|
? html`
|
||||||
<mwc-icon-button
|
<ha-icon-button
|
||||||
.label=${this.hass.localize(
|
aria-label=${this.hass.localize(
|
||||||
"ui.components.device-picker.clear"
|
"ui.components.device-picker.clear"
|
||||||
)}
|
)}
|
||||||
slot="suffix"
|
slot="suffix"
|
||||||
class="clear-button"
|
class="clear-button"
|
||||||
|
icon="hass:close"
|
||||||
@click=${this._clearValue}
|
@click=${this._clearValue}
|
||||||
|
no-ripple
|
||||||
>
|
>
|
||||||
<ha-svg-icon .path=${mdiClose}></ha-svg-icon>
|
Clear
|
||||||
</mwc-icon-button>
|
</ha-icon-button>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
${devices.length > 0
|
||||||
|
? html`
|
||||||
|
<ha-icon-button
|
||||||
|
aria-label=${this.hass.localize(
|
||||||
|
"ui.components.device-picker.show_devices"
|
||||||
|
)}
|
||||||
|
slot="suffix"
|
||||||
|
class="toggle-button"
|
||||||
|
.icon=${this._opened ? "hass:menu-up" : "hass:menu-down"}
|
||||||
|
>
|
||||||
|
Toggle
|
||||||
|
</ha-icon-button>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
|
|
||||||
<mwc-icon-button
|
|
||||||
.label=${this.hass.localize(
|
|
||||||
"ui.components.device-picker.show_devices"
|
|
||||||
)}
|
|
||||||
slot="suffix"
|
|
||||||
class="toggle-button"
|
|
||||||
>
|
|
||||||
<ha-svg-icon
|
|
||||||
.path=${this._opened ? mdiMenuUp : mdiMenuDown}
|
|
||||||
></ha-svg-icon>
|
|
||||||
</mwc-icon-button>
|
|
||||||
</paper-input>
|
</paper-input>
|
||||||
</vaadin-combo-box-light>
|
</vaadin-combo-box-light>
|
||||||
`;
|
`;
|
||||||
@@ -373,7 +329,7 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult {
|
||||||
return css`
|
return css`
|
||||||
paper-input > mwc-icon-button {
|
paper-input > ha-icon-button {
|
||||||
--mdc-icon-button-size: 24px;
|
--mdc-icon-button-size: 24px;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { customElement, html, LitElement, property } from "lit-element";
|
|
||||||
import { batteryIcon } from "../../common/entity/battery_icon";
|
import { batteryIcon } from "../../common/entity/battery_icon";
|
||||||
import "../ha-icon";
|
import "../ha-icon";
|
||||||
|
import { customElement, html, property, LitElement } from "lit-element";
|
||||||
|
|
||||||
@customElement("ha-battery-icon")
|
@customElement("ha-battery-icon")
|
||||||
export class HaBatteryIcon extends LitElement {
|
export class HaBatteryIcon extends LitElement {
|
||||||
|
@@ -638,14 +638,8 @@ class HaChartBase extends mixinBehaviors(
|
|||||||
const name = data[3];
|
const name = data[3];
|
||||||
if (name === null) return Color().hsl(0, 40, 38);
|
if (name === null) return Color().hsl(0, 40, 38);
|
||||||
if (name === undefined) return Color().hsl(120, 40, 38);
|
if (name === undefined) return Color().hsl(120, 40, 38);
|
||||||
let name1 = name.toLowerCase();
|
const name1 = name.toLowerCase();
|
||||||
if (ret === undefined) {
|
if (ret === undefined) {
|
||||||
if (data[4]) {
|
|
||||||
// Invert on/off if data[4] is true. Required for some binary_sensor device classes
|
|
||||||
// (BINARY_SENSOR_DEVICE_CLASS_COLOR_INVERTED) where "off" is the good (= green color) value.
|
|
||||||
name1 = name1 === "on" ? "off" : name1 === "off" ? "on" : name1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = colorDict[name1];
|
ret = colorDict[name1];
|
||||||
}
|
}
|
||||||
if (ret === undefined) {
|
if (ret === undefined) {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user