mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-12 02:39:26 +00:00
Compare commits
829 Commits
layout-str
...
thomaslove
Author | SHA1 | Date | |
---|---|---|---|
![]() |
813c9014e5 | ||
![]() |
87e4c209f4 | ||
![]() |
3d0a5642cc | ||
![]() |
e211d812ad | ||
![]() |
0dcf673b87 | ||
![]() |
cb14e1f20c | ||
![]() |
52087c0e30 | ||
![]() |
1b9286db76 | ||
![]() |
bc92c0b052 | ||
![]() |
245bb639f2 | ||
![]() |
8d81ed58c8 | ||
![]() |
7890ca85a8 | ||
![]() |
07bab7b264 | ||
![]() |
5730c14dc1 | ||
![]() |
f8e8b5ad18 | ||
![]() |
fd2728c02c | ||
![]() |
7e2bf920e1 | ||
![]() |
1f65328f2d | ||
![]() |
4f731baa00 | ||
![]() |
5abb3dd8c1 | ||
![]() |
0a672c55c5 | ||
![]() |
a6b2299c74 | ||
![]() |
37cc6709d4 | ||
![]() |
f4ffbe67e2 | ||
![]() |
9f32d72a41 | ||
![]() |
64a117d8ac | ||
![]() |
ebf0bdc840 | ||
![]() |
cc0a120bf6 | ||
![]() |
fe2fe7468f | ||
![]() |
b12a10ccb5 | ||
![]() |
2ad2a4b198 | ||
![]() |
6a62f05657 | ||
![]() |
4910f60ec4 | ||
![]() |
d35168e88f | ||
![]() |
01b3d2aca9 | ||
![]() |
29e8d1cff0 | ||
![]() |
4e1d10cc08 | ||
![]() |
3575d94ca1 | ||
![]() |
d91546b532 | ||
![]() |
9f554f4917 | ||
![]() |
d4720a9244 | ||
![]() |
5c466712db | ||
![]() |
6dc7e852ae | ||
![]() |
785f614bd9 | ||
![]() |
0a8e27249d | ||
![]() |
15ee87ee67 | ||
![]() |
12612a16df | ||
![]() |
4f449e2600 | ||
![]() |
7f49f039fd | ||
![]() |
88dc65bc4e | ||
![]() |
6edebe18ad | ||
![]() |
38b3a9205d | ||
![]() |
4b796b4929 | ||
![]() |
83cabcac28 | ||
![]() |
d308c5d9b9 | ||
![]() |
9f032a61a9 | ||
![]() |
0f58214ba1 | ||
![]() |
c48a60cce6 | ||
![]() |
cd3ffceeff | ||
![]() |
9be4a00169 | ||
![]() |
a9c7a39a47 | ||
![]() |
abcdd60a21 | ||
![]() |
a94f85a100 | ||
![]() |
9755bf723f | ||
![]() |
a71ebcf47e | ||
![]() |
72695631cd | ||
![]() |
2af211b543 | ||
![]() |
6e5e2625d6 | ||
![]() |
23c1c2f5eb | ||
![]() |
da85ee5d01 | ||
![]() |
d408e8653c | ||
![]() |
cc76ccc3c9 | ||
![]() |
105a00d3e4 | ||
![]() |
2c08cba8cc | ||
![]() |
344b11a204 | ||
![]() |
1ff5bf0fd5 | ||
![]() |
c29cf7f77c | ||
![]() |
193cb46d60 | ||
![]() |
9dc864d486 | ||
![]() |
cee166839a | ||
![]() |
1a60a3c728 | ||
![]() |
5d946778cb | ||
![]() |
ac5f85820f | ||
![]() |
716e100a28 | ||
![]() |
7b8cb16c12 | ||
![]() |
00d46424a3 | ||
![]() |
2a5f940744 | ||
![]() |
13cc016b36 | ||
![]() |
a8d49c27c8 | ||
![]() |
a8522e91b5 | ||
![]() |
5754f4463d | ||
![]() |
d4118ade0f | ||
![]() |
6d80f15a98 | ||
![]() |
f8aa472409 | ||
![]() |
df22fd00ca | ||
![]() |
ce2743a982 | ||
![]() |
92b32458ad | ||
![]() |
d57e8a45d3 | ||
![]() |
551d3ffdf3 | ||
![]() |
7add6eb736 | ||
![]() |
a28616d535 | ||
![]() |
a288fd370f | ||
![]() |
acd335e249 | ||
![]() |
da0bfa1945 | ||
![]() |
3c61d709b5 | ||
![]() |
ffc92a7b63 | ||
![]() |
af0c7b5a50 | ||
![]() |
1904c4d057 | ||
![]() |
542f169b36 | ||
![]() |
65a30bf60c | ||
![]() |
2e51da32f0 | ||
![]() |
0562242043 | ||
![]() |
debcdefc21 | ||
![]() |
0de3f3a332 | ||
![]() |
4fcb4d449e | ||
![]() |
408fe25abd | ||
![]() |
236e5e0b25 | ||
![]() |
ebe0caba83 | ||
![]() |
9d33c0cfaf | ||
![]() |
7962130a0c | ||
![]() |
9690434cac | ||
![]() |
7304544c37 | ||
![]() |
5a3408c242 | ||
![]() |
16996f25af | ||
![]() |
0c12586019 | ||
![]() |
93a1adaa56 | ||
![]() |
83e65e2cc6 | ||
![]() |
36586b798e | ||
![]() |
20c351949f | ||
![]() |
b63bd92d81 | ||
![]() |
9f3bb7f4d6 | ||
![]() |
73bb346c00 | ||
![]() |
33703a3b53 | ||
![]() |
b7a4f97eca | ||
![]() |
dd4efe0f51 | ||
![]() |
7e0522c3b3 | ||
![]() |
e682abfb75 | ||
![]() |
24e202a3d7 | ||
![]() |
ac9a881ab5 | ||
![]() |
4d287a1f83 | ||
![]() |
b8d6b1ebdd | ||
![]() |
8ca1b9320d | ||
![]() |
cba3992d2b | ||
![]() |
96d6e337be | ||
![]() |
959f7ae046 | ||
![]() |
9572a58764 | ||
![]() |
393ae9e5dc | ||
![]() |
63e10314bd | ||
![]() |
b599417a37 | ||
![]() |
899eab4e5c | ||
![]() |
3f21c87a3d | ||
![]() |
c296a60bab | ||
![]() |
5f78f18cb4 | ||
![]() |
0b8d356865 | ||
![]() |
e8d1318a5b | ||
![]() |
07ce07c4a5 | ||
![]() |
a07220f383 | ||
![]() |
f21ed24a49 | ||
![]() |
e3c38b93f4 | ||
![]() |
b398727413 | ||
![]() |
9bc2ab29a1 | ||
![]() |
51f1ff26f1 | ||
![]() |
97d5e6512d | ||
![]() |
b76c67fc9b | ||
![]() |
b96a70cd55 | ||
![]() |
982ab93cdb | ||
![]() |
c7f4e1152d | ||
![]() |
519988326b | ||
![]() |
b518f4b03c | ||
![]() |
5493fdfcb7 | ||
![]() |
179767e9f8 | ||
![]() |
25b3bb1285 | ||
![]() |
841c8ab1f1 | ||
![]() |
1ce17e2847 | ||
![]() |
a09b206b0e | ||
![]() |
bb4617c53b | ||
![]() |
cfd18bfb74 | ||
![]() |
e225d6f546 | ||
![]() |
60fe48d355 | ||
![]() |
2dcd0d2b0a | ||
![]() |
8e11aa9130 | ||
![]() |
f6e223c18d | ||
![]() |
9d29b55bee | ||
![]() |
92aa8580db | ||
![]() |
538028a003 | ||
![]() |
c53575a74f | ||
![]() |
193016a46a | ||
![]() |
aaa50b4d1d | ||
![]() |
a43120320e | ||
![]() |
b8bb0c038d | ||
![]() |
dc79fc2919 | ||
![]() |
30787fef60 | ||
![]() |
445ae156ef | ||
![]() |
62a0cfb0f6 | ||
![]() |
96bc3ef99a | ||
![]() |
1d3b95d24f | ||
![]() |
56fe4b07f3 | ||
![]() |
ea60f7005b | ||
![]() |
9eb59062aa | ||
![]() |
d00927c31f | ||
![]() |
c03017208d | ||
![]() |
73f945458a | ||
![]() |
db12234611 | ||
![]() |
ed1cd4632f | ||
![]() |
17d3755152 | ||
![]() |
d7c0c2ea72 | ||
![]() |
7c823c98ae | ||
![]() |
97508a6f31 | ||
![]() |
2507a41b6e | ||
![]() |
9833accc79 | ||
![]() |
d46123771a | ||
![]() |
87fe84b1ac | ||
![]() |
21140f437e | ||
![]() |
ba9e410393 | ||
![]() |
9b628546c1 | ||
![]() |
d0837fada8 | ||
![]() |
520647d72f | ||
![]() |
51c888845c | ||
![]() |
e4606219bc | ||
![]() |
716335df2c | ||
![]() |
ad4f90c502 | ||
![]() |
a1bdfa7560 | ||
![]() |
587fb2a170 | ||
![]() |
7d801ff84c | ||
![]() |
d69accd9a5 | ||
![]() |
1127750c5e | ||
![]() |
7758bd89c1 | ||
![]() |
de7264327a | ||
![]() |
c3f0932794 | ||
![]() |
367907e037 | ||
![]() |
2d15bd651e | ||
![]() |
4b1d7863f8 | ||
![]() |
e425d768dd | ||
![]() |
34ca807044 | ||
![]() |
9075146b47 | ||
![]() |
26c4591baa | ||
![]() |
2aac8c55e7 | ||
![]() |
8af55efdb3 | ||
![]() |
9d6e07ff96 | ||
![]() |
8f58eee6af | ||
![]() |
8dd3d78f21 | ||
![]() |
48161fd02f | ||
![]() |
b61410826d | ||
![]() |
2f0188b280 | ||
![]() |
3a4fffdb0b | ||
![]() |
6393072e68 | ||
![]() |
109910d18f | ||
![]() |
8874aaabe9 | ||
![]() |
cafbea9c42 | ||
![]() |
4843ee80a7 | ||
![]() |
4511c8f30c | ||
![]() |
4cf1e52ac0 | ||
![]() |
b501b7f47c | ||
![]() |
cc275f9877 | ||
![]() |
7aae55cde7 | ||
![]() |
85eaa219c6 | ||
![]() |
7d5ecb8ba4 | ||
![]() |
1fd142d337 | ||
![]() |
d75c6aecbe | ||
![]() |
dffe0f656d | ||
![]() |
890639436b | ||
![]() |
99f66d7c5d | ||
![]() |
05faa52425 | ||
![]() |
9e1a8b646b | ||
![]() |
8f6ec03446 | ||
![]() |
c56b4fade3 | ||
![]() |
61aaaabcb5 | ||
![]() |
d57cf93580 | ||
![]() |
82ad5c103d | ||
![]() |
a0b5bc5456 | ||
![]() |
c810e541ea | ||
![]() |
05ea3b8187 | ||
![]() |
8301dffb21 | ||
![]() |
01be5243de | ||
![]() |
334196799a | ||
![]() |
c11bbcf442 | ||
![]() |
8e3a7576ea | ||
![]() |
deca6f03ba | ||
![]() |
401064d3c8 | ||
![]() |
b6f59d3c98 | ||
![]() |
1fb3663398 | ||
![]() |
5c1604e959 | ||
![]() |
17b1f3e465 | ||
![]() |
9a68bdeec1 | ||
![]() |
9b947ef734 | ||
![]() |
66432608ed | ||
![]() |
d8153ac8fc | ||
![]() |
27d9f82f7d | ||
![]() |
5b55bcd879 | ||
![]() |
5cfd28881b | ||
![]() |
bc54a42e01 | ||
![]() |
03f9964c59 | ||
![]() |
f159219d2c | ||
![]() |
e714f32737 | ||
![]() |
20858db96d | ||
![]() |
89b82bb778 | ||
![]() |
2c886d739f | ||
![]() |
1ccf4e49bc | ||
![]() |
7d63e3e088 | ||
![]() |
828523f281 | ||
![]() |
afe3831f25 | ||
![]() |
3888c56f1a | ||
![]() |
6f07966ef8 | ||
![]() |
09eafe8abd | ||
![]() |
6719a42e27 | ||
![]() |
4b98a70ee8 | ||
![]() |
db3f5447ca | ||
![]() |
fed63f645d | ||
![]() |
e7315bb570 | ||
![]() |
cd2404f26a | ||
![]() |
b866166425 | ||
![]() |
46580376dd | ||
![]() |
b8bfb44aec | ||
![]() |
a153f572d0 | ||
![]() |
66c30a59e7 | ||
![]() |
10b8efc5cb | ||
![]() |
c65d414b7b | ||
![]() |
7f7d89c745 | ||
![]() |
742028b691 | ||
![]() |
62f685bac2 | ||
![]() |
0b3333e88c | ||
![]() |
c341a99b83 | ||
![]() |
f43c420d59 | ||
![]() |
0393970a80 | ||
![]() |
1865e0661f | ||
![]() |
c07b1194b3 | ||
![]() |
bf802628b9 | ||
![]() |
36020373cd | ||
![]() |
43e73d69de | ||
![]() |
47a3f649d2 | ||
![]() |
5c63f8e52a | ||
![]() |
01c553ef13 | ||
![]() |
f229e4e12a | ||
![]() |
40cf4c8d32 | ||
![]() |
ee38c419de | ||
![]() |
10baa34c18 | ||
![]() |
343b67fa7f | ||
![]() |
6de8b4e35f | ||
![]() |
57e535c2c8 | ||
![]() |
af5b22a265 | ||
![]() |
77972c961b | ||
![]() |
a3efa5676b | ||
![]() |
014dbc2a86 | ||
![]() |
226a2941d6 | ||
![]() |
c269c8fd3f | ||
![]() |
d8fc3c1ebf | ||
![]() |
a5c6ffd1b9 | ||
![]() |
9aaaaae175 | ||
![]() |
7d39b69540 | ||
![]() |
09bad14c3d | ||
![]() |
369c9dc6e2 | ||
![]() |
9676d2cee7 | ||
![]() |
5156c67226 | ||
![]() |
4d48fc3d85 | ||
![]() |
20da329a21 | ||
![]() |
4b664cc142 | ||
![]() |
c9b620fdb2 | ||
![]() |
25c886d401 | ||
![]() |
740805356f | ||
![]() |
ce5fb57577 | ||
![]() |
3e20d2b454 | ||
![]() |
a9e8186491 | ||
![]() |
3bb909b026 | ||
![]() |
b921d91aeb | ||
![]() |
05790954c6 | ||
![]() |
13014c1351 | ||
![]() |
e34c63b830 | ||
![]() |
943100d758 | ||
![]() |
55f40d66f2 | ||
![]() |
593e5ac79c | ||
![]() |
ef31bce5ee | ||
![]() |
3c75eb96f1 | ||
![]() |
f34dfde925 | ||
![]() |
e3b72fe0aa | ||
![]() |
60de74a375 | ||
![]() |
55e58f8d35 | ||
![]() |
a465254418 | ||
![]() |
5d27a138cf | ||
![]() |
22f4b036df | ||
![]() |
03f694922d | ||
![]() |
a841e287e5 | ||
![]() |
5d2afdd825 | ||
![]() |
67240e2339 | ||
![]() |
f84a8eccfa | ||
![]() |
68a058e4f1 | ||
![]() |
d678b42ece | ||
![]() |
2cf63cda08 | ||
![]() |
7bd4eeb0df | ||
![]() |
dc3ee7c779 | ||
![]() |
e8cc97a8e5 | ||
![]() |
3b837e1d54 | ||
![]() |
bb6c2050bc | ||
![]() |
082d4f9691 | ||
![]() |
153d68a9cd | ||
![]() |
0404faa856 | ||
![]() |
afbc2d6b8f | ||
![]() |
89ecc8bd2f | ||
![]() |
7f21a2b319 | ||
![]() |
e2f07f6723 | ||
![]() |
a475e143b7 | ||
![]() |
e50fd80b2e | ||
![]() |
68ea1abc05 | ||
![]() |
2e76b306c4 | ||
![]() |
ca3cac4ed3 | ||
![]() |
41852460e1 | ||
![]() |
9ec4e083d9 | ||
![]() |
9560a1c4a7 | ||
![]() |
4f5a47ace7 | ||
![]() |
01c4d662f2 | ||
![]() |
9bdda77e89 | ||
![]() |
194024edb9 | ||
![]() |
bef0d3a6a1 | ||
![]() |
47a024b795 | ||
![]() |
39847f9c9d | ||
![]() |
fa7bd28c92 | ||
![]() |
279f78e4a8 | ||
![]() |
8ec3cbdb33 | ||
![]() |
7449f7e73f | ||
![]() |
d680fde759 | ||
![]() |
f24f21ca91 | ||
![]() |
c8ea37eec0 | ||
![]() |
b71f452795 | ||
![]() |
7ea1ece169 | ||
![]() |
aece3a37c0 | ||
![]() |
705871f8dc | ||
![]() |
4a11975349 | ||
![]() |
4d3d27f2c4 | ||
![]() |
d784a30d42 | ||
![]() |
35f776284b | ||
![]() |
f659a6fe37 | ||
![]() |
ad53c99fc4 | ||
![]() |
fa0172d00c | ||
![]() |
ba77a88714 | ||
![]() |
9b39087102 | ||
![]() |
845411b48c | ||
![]() |
d715867b09 | ||
![]() |
0ca2cdfbed | ||
![]() |
a00961b9ef | ||
![]() |
701c188bab | ||
![]() |
e81002807f | ||
![]() |
0d1c72386e | ||
![]() |
c91779dffe | ||
![]() |
3853cc9214 | ||
![]() |
a66b3f6b80 | ||
![]() |
c97ec32343 | ||
![]() |
2abba7e445 | ||
![]() |
f887c27ad1 | ||
![]() |
6ee8d74899 | ||
![]() |
f196c72563 | ||
![]() |
419e564441 | ||
![]() |
de97b54c95 | ||
![]() |
07001f7b5c | ||
![]() |
bee17fce64 | ||
![]() |
718904a853 | ||
![]() |
e14d652651 | ||
![]() |
98ae5270ef | ||
![]() |
19ccf0ab40 | ||
![]() |
72af4a69d6 | ||
![]() |
fe50f4229c | ||
![]() |
6021bec5ee | ||
![]() |
7fcadc85fa | ||
![]() |
ca4de877c1 | ||
![]() |
1dfecf9618 | ||
![]() |
0a3505ed89 | ||
![]() |
33cbf7eabe | ||
![]() |
935d97ce1a | ||
![]() |
9f73f0ca8d | ||
![]() |
5d7f971a82 | ||
![]() |
d8cdbac15e | ||
![]() |
03b8c1348c | ||
![]() |
25a0be7672 | ||
![]() |
08f1ce2d54 | ||
![]() |
bea20d0495 | ||
![]() |
c42430ccf9 | ||
![]() |
5ae10e8516 | ||
![]() |
e3f4a9ce5b | ||
![]() |
cf1fb606fb | ||
![]() |
54ec81b67d | ||
![]() |
f2a9725572 | ||
![]() |
4765114e80 | ||
![]() |
5ff757ad65 | ||
![]() |
1642c68493 | ||
![]() |
f31f10cea9 | ||
![]() |
76e0bbb55d | ||
![]() |
f43af9c0a5 | ||
![]() |
f7a3d2705c | ||
![]() |
22c8af0cc5 | ||
![]() |
f263a5221d | ||
![]() |
3834ab8ede | ||
![]() |
e2e167630d | ||
![]() |
01dd44300b | ||
![]() |
b30160d671 | ||
![]() |
f44d505b41 | ||
![]() |
16fa6904d9 | ||
![]() |
b58c17e75e | ||
![]() |
ae590d42dc | ||
![]() |
d7917160c0 | ||
![]() |
01e4414d17 | ||
![]() |
0bc2eb530d | ||
![]() |
12b124e5a3 | ||
![]() |
478a4b2593 | ||
![]() |
9752e30eb4 | ||
![]() |
af6e87ba31 | ||
![]() |
64d390ad0f | ||
![]() |
c94bcb6896 | ||
![]() |
97f9df2f2d | ||
![]() |
4e7f68a86c | ||
![]() |
2f7f677549 | ||
![]() |
12a8a1531d | ||
![]() |
f44d867d3a | ||
![]() |
6f636187f7 | ||
![]() |
9414f89e50 | ||
![]() |
60bf1a5451 | ||
![]() |
32ba8f4731 | ||
![]() |
81f96de2bd | ||
![]() |
0c417755ed | ||
![]() |
93e5bde797 | ||
![]() |
c85f69c9ee | ||
![]() |
b6eaf0a7c5 | ||
![]() |
5f1851bade | ||
![]() |
5c66a02711 | ||
![]() |
bde925a0e3 | ||
![]() |
0f574a765b | ||
![]() |
782b941531 | ||
![]() |
f42c0a0717 | ||
![]() |
13ac14d449 | ||
![]() |
db9cea81db | ||
![]() |
7c1fd542da | ||
![]() |
54a2b2534a | ||
![]() |
f5fb6c1e03 | ||
![]() |
781c0701fc | ||
![]() |
742f1f85dc | ||
![]() |
a648e9be49 | ||
![]() |
fd9441dde2 | ||
![]() |
b5ec59c396 | ||
![]() |
60e4594abd | ||
![]() |
79692ef58a | ||
![]() |
ace7ee5622 | ||
![]() |
741ac679a0 | ||
![]() |
216526e391 | ||
![]() |
d76af2cb61 | ||
![]() |
b7d4c40736 | ||
![]() |
6092af8de6 | ||
![]() |
627424b8b9 | ||
![]() |
e33aff7cf3 | ||
![]() |
ef0bfb237a | ||
![]() |
c042c5568b | ||
![]() |
d84a7ee358 | ||
![]() |
8bfc8ece9d | ||
![]() |
2d3cf7d84d | ||
![]() |
520ef8f1df | ||
![]() |
f251d4267f | ||
![]() |
2052a5351c | ||
![]() |
9807d0aede | ||
![]() |
a41afcd714 | ||
![]() |
d93d2b5945 | ||
![]() |
d54a129605 | ||
![]() |
77911980cb | ||
![]() |
d51fd1e2f9 | ||
![]() |
fe54f8eb16 | ||
![]() |
fc7c4af27a | ||
![]() |
09e7600d86 | ||
![]() |
17410874e3 | ||
![]() |
03d4174163 | ||
![]() |
99eff73b0d | ||
![]() |
acefa39796 | ||
![]() |
c01c0528a6 | ||
![]() |
0ec58007c9 | ||
![]() |
e8daf88729 | ||
![]() |
ab74c7f7eb | ||
![]() |
6b673c7f44 | ||
![]() |
53510a3cb9 | ||
![]() |
d4d38a880d | ||
![]() |
18783d5e3b | ||
![]() |
eb235cb552 | ||
![]() |
435a6b6d53 | ||
![]() |
8d13745c6b | ||
![]() |
14c7cfc64c | ||
![]() |
c7821b9cee | ||
![]() |
a1d66aef0c | ||
![]() |
e275f1f4b9 | ||
![]() |
48de8b0739 | ||
![]() |
b75dc0efe0 | ||
![]() |
1d498349c5 | ||
![]() |
311e1cfb00 | ||
![]() |
5cdcec699b | ||
![]() |
cd72287d99 | ||
![]() |
c8717bfa32 | ||
![]() |
83de75b689 | ||
![]() |
e5ea762cbc | ||
![]() |
01df01cd66 | ||
![]() |
2c07a2c825 | ||
![]() |
c3f50ba0fb | ||
![]() |
c04419fd09 | ||
![]() |
9c7af0dfce | ||
![]() |
b66d14e980 | ||
![]() |
6a553e9554 | ||
![]() |
4273b72d71 | ||
![]() |
9ccfa79199 | ||
![]() |
fe3d22d4f8 | ||
![]() |
e06642e892 | ||
![]() |
5199e946a1 | ||
![]() |
17aff2f9b8 | ||
![]() |
f7c7ac44f7 | ||
![]() |
62dd0a561e | ||
![]() |
858eacddea | ||
![]() |
471bb5169c | ||
![]() |
9d89aa329c | ||
![]() |
4e4d8bdc5e | ||
![]() |
a30ec32ac1 | ||
![]() |
a9192ae2e1 | ||
![]() |
3d4a0b02e5 | ||
![]() |
3659cf7c87 | ||
![]() |
fbcf35414c | ||
![]() |
d79e5dd8fb | ||
![]() |
92b116c0da | ||
![]() |
da3f911deb | ||
![]() |
9d82ce8ab4 | ||
![]() |
db9597d2e7 | ||
![]() |
1523558f4c | ||
![]() |
bd9f4fe41c | ||
![]() |
6b938b2597 | ||
![]() |
5a8009e46e | ||
![]() |
c92eeb6bb7 | ||
![]() |
8ea6baaf5d | ||
![]() |
1ed03842c0 | ||
![]() |
0e9984413c | ||
![]() |
362b419814 | ||
![]() |
bffcccc1fe | ||
![]() |
b8e9a4ce9f | ||
![]() |
bdff3fd452 | ||
![]() |
1fc51f0087 | ||
![]() |
226013d999 | ||
![]() |
86847263b8 | ||
![]() |
b798523d53 | ||
![]() |
bd59c4fccf | ||
![]() |
566ffe24a4 | ||
![]() |
0e5c1b2041 | ||
![]() |
9a088a21da | ||
![]() |
1160d27004 | ||
![]() |
b4e5740050 | ||
![]() |
12bb3f5796 | ||
![]() |
ff62fdb69d | ||
![]() |
4ebf32cb1f | ||
![]() |
5afb8a77a9 | ||
![]() |
48ed33af95 | ||
![]() |
4a64cd4464 | ||
![]() |
8ae1a1b558 | ||
![]() |
ef1dd8b761 | ||
![]() |
3766f44787 | ||
![]() |
101067d018 | ||
![]() |
448d19bfbb | ||
![]() |
c1caad6d43 | ||
![]() |
a653bf5b0d | ||
![]() |
afdb369e04 | ||
![]() |
f02841409c | ||
![]() |
d4000cf662 | ||
![]() |
e1cf5919fa | ||
![]() |
d33e8d77c2 | ||
![]() |
3a522215a9 | ||
![]() |
7de6ea0879 | ||
![]() |
5ee0250ba5 | ||
![]() |
69d0a22091 | ||
![]() |
4d6c11ce31 | ||
![]() |
178605664e | ||
![]() |
12acb5473b | ||
![]() |
0cf8004b8d | ||
![]() |
6b0a8eae74 | ||
![]() |
00412c7216 | ||
![]() |
6483f23558 | ||
![]() |
4234d51a29 | ||
![]() |
9243d300cc | ||
![]() |
2ce70206c6 | ||
![]() |
b22455d2a5 | ||
![]() |
4f0bb9f6c3 | ||
![]() |
7dfa1b0942 | ||
![]() |
093e23c006 | ||
![]() |
5f003ccbe2 | ||
![]() |
8d0608610f | ||
![]() |
8bfe583a20 | ||
![]() |
0a3172dfdb | ||
![]() |
5c0e151bc2 | ||
![]() |
e69f36047d | ||
![]() |
ed368ddd9d | ||
![]() |
8400e90e34 | ||
![]() |
4cd95b724b | ||
![]() |
46b3836fbd | ||
![]() |
9988227d93 | ||
![]() |
9d289bfa34 | ||
![]() |
048de6b388 | ||
![]() |
9b7d8934da | ||
![]() |
0dd9b21c2d | ||
![]() |
417184525f | ||
![]() |
0a09ec706f | ||
![]() |
cf43b26e14 | ||
![]() |
a8b27e224f | ||
![]() |
dc5d14834d | ||
![]() |
12c935f647 | ||
![]() |
7710cb245c | ||
![]() |
a6b77c0457 | ||
![]() |
748a05f355 | ||
![]() |
831b9da0cf | ||
![]() |
a3339c9d5f | ||
![]() |
d228f38471 | ||
![]() |
fe13853b8b | ||
![]() |
6f4dbdc959 | ||
![]() |
870f0bcbb1 | ||
![]() |
599dd81e3c | ||
![]() |
9e99d158fd | ||
![]() |
136ebb5a07 | ||
![]() |
707338b1aa | ||
![]() |
7e06bd53b6 | ||
![]() |
08c1b864fc | ||
![]() |
16e7a16d12 | ||
![]() |
45200da32f | ||
![]() |
84a9ca59ef | ||
![]() |
40f4c35b42 | ||
![]() |
bb77d34017 | ||
![]() |
9659ebe59b | ||
![]() |
16c914b139 | ||
![]() |
142f26add1 | ||
![]() |
ef7d2aea8d | ||
![]() |
1aa40cb6df | ||
![]() |
cd06b931a9 | ||
![]() |
fd2df92000 | ||
![]() |
b565a8b8f7 | ||
![]() |
1aab656705 | ||
![]() |
6919d0cde6 | ||
![]() |
95fd8de1bc | ||
![]() |
28ca1a5193 | ||
![]() |
a1d07e5a00 | ||
![]() |
131a7f3782 | ||
![]() |
c28a7d6c10 | ||
![]() |
6b20bb967b | ||
![]() |
75f228418d | ||
![]() |
41f8b0d19b | ||
![]() |
cea3b8b010 | ||
![]() |
aba0e1f026 | ||
![]() |
f42587af22 | ||
![]() |
edcb7e87bb | ||
![]() |
96f0ceeb8c | ||
![]() |
a9baa7f1c1 | ||
![]() |
b1483287dc | ||
![]() |
a4657541fc | ||
![]() |
56d88b4c56 | ||
![]() |
02313e4be8 | ||
![]() |
2a14a3a4dc | ||
![]() |
d02a2e8c2e | ||
![]() |
0d281f8437 | ||
![]() |
2b0f43f334 | ||
![]() |
f9d28fc124 | ||
![]() |
da07173471 | ||
![]() |
4deeff7029 | ||
![]() |
1538fbb102 | ||
![]() |
b9259b87eb | ||
![]() |
30997dbc88 | ||
![]() |
a9d926e80a | ||
![]() |
c41369c89c | ||
![]() |
656bef3da9 | ||
![]() |
607eb6d130 | ||
![]() |
f2e9b3577d | ||
![]() |
cb2c6d8560 | ||
![]() |
bfe8346ced | ||
![]() |
88da9bb91b | ||
![]() |
5e2ee1a16c | ||
![]() |
2fdc746392 | ||
![]() |
1667973a66 | ||
![]() |
42f0101440 | ||
![]() |
13b69bff1b | ||
![]() |
2c2226dfd6 | ||
![]() |
a3fdfe0e15 | ||
![]() |
a0de209a55 | ||
![]() |
0208b50ac7 | ||
![]() |
4a61779aba | ||
![]() |
05057ade05 | ||
![]() |
6fb206853c | ||
![]() |
fab68055bf | ||
![]() |
d5a77ef3cd | ||
![]() |
dcb2605de4 | ||
![]() |
e6d38f4539 | ||
![]() |
293b56cfa6 | ||
![]() |
775e93d54b | ||
![]() |
7f840e75df | ||
![]() |
2113ea675e | ||
![]() |
916a5c1a6b | ||
![]() |
f684531315 | ||
![]() |
fe8dda8996 | ||
![]() |
4cd4b328c8 | ||
![]() |
3d7ee6a4df | ||
![]() |
d844c89b94 | ||
![]() |
177ea2b85a | ||
![]() |
50c5c15f49 | ||
![]() |
1810760dc7 | ||
![]() |
4635b92e3f | ||
![]() |
1c652626eb | ||
![]() |
2000cfb1db | ||
![]() |
f4d07828e7 | ||
![]() |
95b552671c | ||
![]() |
ef3bc3efe1 | ||
![]() |
371ad899f5 | ||
![]() |
2c54158d84 | ||
![]() |
5d9e30bbdc | ||
![]() |
e477fd567d | ||
![]() |
6a6c2937fe | ||
![]() |
09e17c4da8 | ||
![]() |
fd00469d11 | ||
![]() |
cbbeb795f3 | ||
![]() |
bba40e0da8 | ||
![]() |
d23165d06a | ||
![]() |
405fef6f03 | ||
![]() |
588f217826 | ||
![]() |
3d8b7cf80e | ||
![]() |
c0ef923ad3 | ||
![]() |
3df44fc71e | ||
![]() |
c1965492d9 | ||
![]() |
1f56ffde80 | ||
![]() |
f335fdc002 | ||
![]() |
0c914b5ec8 | ||
![]() |
d767b06858 | ||
![]() |
d4e49f3944 | ||
![]() |
7dfc5b3faf | ||
![]() |
8a88033ab9 | ||
![]() |
7b06b38c94 | ||
![]() |
5409752817 | ||
![]() |
a70e6c49a1 | ||
![]() |
c10dca9c7b | ||
![]() |
2682c6e150 | ||
![]() |
b7ccf3e0e5 | ||
![]() |
50e7410002 |
@@ -4,7 +4,7 @@
|
|||||||
"dockerfile": "Dockerfile",
|
"dockerfile": "Dockerfile",
|
||||||
"context": ".."
|
"context": ".."
|
||||||
},
|
},
|
||||||
"appPort": 8123,
|
"appPort": "8124:8123",
|
||||||
"context": "..",
|
"context": "..",
|
||||||
"postCreateCommand": "script/bootstrap",
|
"postCreateCommand": "script/bootstrap",
|
||||||
"extensions": [
|
"extensions": [
|
||||||
@@ -26,6 +26,9 @@
|
|||||||
"[typescript]": {
|
"[typescript]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
},
|
},
|
||||||
|
"[javascript]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
"files.trimTrailingWhitespace": true
|
"files.trimTrailingWhitespace": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,8 +4,7 @@
|
|||||||
"plugin:@typescript-eslint/recommended",
|
"plugin:@typescript-eslint/recommended",
|
||||||
"plugin:wc/recommended",
|
"plugin:wc/recommended",
|
||||||
"plugin:lit/recommended",
|
"plugin:lit/recommended",
|
||||||
"prettier",
|
"prettier"
|
||||||
"prettier/@typescript-eslint"
|
|
||||||
],
|
],
|
||||||
"parser": "@typescript-eslint/parser",
|
"parser": "@typescript-eslint/parser",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
@@ -84,7 +83,27 @@
|
|||||||
"@typescript-eslint/no-unused-vars": 0,
|
"@typescript-eslint/no-unused-vars": 0,
|
||||||
"@typescript-eslint/explicit-function-return-type": 0,
|
"@typescript-eslint/explicit-function-return-type": 0,
|
||||||
"@typescript-eslint/explicit-module-boundary-types": 0,
|
"@typescript-eslint/explicit-module-boundary-types": 0,
|
||||||
"@typescript-eslint/no-shadow": ["error"]
|
"@typescript-eslint/no-shadow": ["error"],
|
||||||
|
"@typescript-eslint/naming-convention": [
|
||||||
|
0,
|
||||||
|
{
|
||||||
|
"selector": "default",
|
||||||
|
"format": ["camelCase", "snake_case"],
|
||||||
|
"leadingUnderscore": "allow",
|
||||||
|
"trailingUnderscore": "allow"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"selector": ["variable"],
|
||||||
|
"format": ["camelCase", "snake_case", "UPPER_CASE"],
|
||||||
|
"leadingUnderscore": "allow",
|
||||||
|
"trailingUnderscore": "allow"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"selector": "typeLike",
|
||||||
|
"format": ["PascalCase"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lit/attribute-value-entities": 0
|
||||||
},
|
},
|
||||||
"plugins": ["disable", "import", "lit", "prettier", "@typescript-eslint"],
|
"plugins": ["disable", "import", "lit", "prettier", "@typescript-eslint"],
|
||||||
"processor": "disable/disable"
|
"processor": "disable/disable"
|
||||||
|
@@ -74,12 +74,12 @@ DO NOT DELETE ANY TEXT from this template! Otherwise, your issue may be closed w
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Problem-relevant configuration
|
## Problem-relevant frontend configuration
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
An example configuration that caused the problem for you. Fill this out even
|
An example configuration that caused the problem for you, e.g. the YAML configuration
|
||||||
if it seems unimportant to you. Please be sure to remove personal information
|
of the used cards. Fill this out even if it seems unimportant to you. Please be sure
|
||||||
like passwords, private URLs and other credentials.
|
to remove personal information 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.
|
||||||
-->
|
-->
|
||||||
|
|
121
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
121
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
name: Report a bug with the UI, Frontend or Lovelace
|
||||||
|
description: Report an issue related to the Home Assistant frontend.
|
||||||
|
labels: bug
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Make sure you are running the [latest version of Home Assistant][releases] before reporting an issue.
|
||||||
|
|
||||||
|
If you have a feature or enhancement request for the frontend, please [start an discussion][fr] instead of creating an issue.
|
||||||
|
|
||||||
|
**Please not not report issues for custom Lovelace cards.**
|
||||||
|
|
||||||
|
[fr]: https://github.com/home-assistant/frontend/discussions
|
||||||
|
[releases]: https://github.com/home-assistant/home-assistant/releases
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Checklist
|
||||||
|
description: Please verify that you've followed these steps
|
||||||
|
options:
|
||||||
|
- label: I have updated to the latest available Home Assistant version.
|
||||||
|
required: true
|
||||||
|
- label: I have cleared the cache of my browser.
|
||||||
|
required: true
|
||||||
|
- label: I have tried a different browser to see if it is related to my browser.
|
||||||
|
required: true
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
## The problem
|
||||||
|
- type: textarea
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
attributes:
|
||||||
|
label: Describe the issue you are experiencing
|
||||||
|
description: Provide a clear and concise description of what the bug is.
|
||||||
|
- type: textarea
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
attributes:
|
||||||
|
label: Describe the behavior you expected
|
||||||
|
description: Describe what you expected to happen or it should look/behave.
|
||||||
|
- type: textarea
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
attributes:
|
||||||
|
label: Steps to reproduce the issue
|
||||||
|
description: |
|
||||||
|
Please tell us exactly how to reproduce your issue.
|
||||||
|
Provide clear and concise step by step instructions and add code snippets if needed.
|
||||||
|
value: |
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
...
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
## Environment
|
||||||
|
- type: input
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
attributes:
|
||||||
|
label: What version of Home Assistant Core has the issue?
|
||||||
|
placeholder: core-
|
||||||
|
description: >
|
||||||
|
Can be found in the Configuration panel -> Info.
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: What was the last working version of Home Assistant Core?
|
||||||
|
placeholder: core-
|
||||||
|
description: >
|
||||||
|
If known, otherwise leave blank.
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: In which browser are you experiencing the issue with?
|
||||||
|
placeholder: Google Chrome 88.0.4324.150
|
||||||
|
description: >
|
||||||
|
Provide the full name and don't forget to add the version!
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: Which operating system are you using to run this browser?
|
||||||
|
placeholder: macOS Big Sur (1.11)
|
||||||
|
description: >
|
||||||
|
Don't forget to add the version!
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
# Details
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: State of relevant entities
|
||||||
|
description: >
|
||||||
|
If your issue is about how an entity is shown in the UI, please add the
|
||||||
|
state and attributes for all situations. You can find this information
|
||||||
|
at Developer Tools -> States.
|
||||||
|
render: txt
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Problem-relevant frontend configuration
|
||||||
|
description: >
|
||||||
|
An example configuration that caused the problem for you, e.g., the YAML
|
||||||
|
configuration of the used cards. Fill this out even if it seems
|
||||||
|
unimportant to you. Please be sure to remove personal information like
|
||||||
|
passwords, private URLs and other credentials.
|
||||||
|
render: yaml
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Javascript errors shown in your browser console/inspector
|
||||||
|
description: >
|
||||||
|
If you come across any Javascript or other error logs, e.g., in your
|
||||||
|
browser console/inspector please provide them.
|
||||||
|
render: txt
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Additional information
|
||||||
|
description: >
|
||||||
|
If you have any additional information for us, use the field below.
|
||||||
|
Please note, you can attach screenshots or screen recordings here, by
|
||||||
|
dragging and dropping files in the field below.
|
6
.github/workflows/ci.yaml
vendored
6
.github/workflows/ci.yaml
vendored
@@ -37,9 +37,11 @@ jobs:
|
|||||||
- name: Build resources
|
- name: Build resources
|
||||||
run: ./node_modules/.bin/gulp gen-icons-json build-translations gather-gallery-demos
|
run: ./node_modules/.bin/gulp gen-icons-json build-translations gather-gallery-demos
|
||||||
- name: Run eslint
|
- name: Run eslint
|
||||||
run: ./node_modules/.bin/eslint '{**/src,src}/**/*.{js,ts,html}' --ignore-path .gitignore
|
run: yarn run lint:eslint
|
||||||
- name: Run tsc
|
- name: Run tsc
|
||||||
run: ./node_modules/.bin/tsc
|
run: yarn run lint:types
|
||||||
|
- name: Run prettier
|
||||||
|
run: yarn run lint:prettier
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
19
.github/workflows/netflify.yml
vendored
Normal file
19
.github/workflows/netflify.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
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
Normal file
81
.github/workflows/release.yaml
vendored
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types:
|
||||||
|
- published
|
||||||
|
|
||||||
|
env:
|
||||||
|
WHEELS_TAG: 3.8-alpine3.12
|
||||||
|
PYTHON_VERSION: 3.8
|
||||||
|
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
Normal file
65
.github/workflows/translations.yaml
vendored
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
name: Translations
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "30 0 * * *"
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- dev
|
||||||
|
paths:
|
||||||
|
- src/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`
|
||||||
- Hass.io: [Instructions](https://developers.home-assistant.io/docs/en/hassio_hass.html)
|
- Supervisor: [Instructions](https://developers.home-assistant.io/docs/supervisor/developing)
|
||||||
|
|
||||||
## Frontend development
|
## Frontend development
|
||||||
|
|
||||||
|
@@ -1,30 +0,0 @@
|
|||||||
# 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'
|
|
@@ -1,59 +0,0 @@
|
|||||||
# 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
|
|
@@ -1,70 +0,0 @@
|
|||||||
# 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'
|
|
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const env = require("./env.js");
|
const env = require("./env.js");
|
||||||
const paths = require("./paths.js");
|
const paths = require("./paths.js");
|
||||||
@@ -53,13 +54,13 @@ module.exports.babelOptions = ({ latestBuild }) => ({
|
|||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: [
|
||||||
!latestBuild && [
|
!latestBuild && [
|
||||||
require("@babel/preset-env").default,
|
"@babel/preset-env",
|
||||||
{
|
{
|
||||||
useBuiltIns: "entry",
|
useBuiltIns: "entry",
|
||||||
corejs: "3.6",
|
corejs: "3.6",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
require("@babel/preset-typescript").default,
|
"@babel/preset-typescript",
|
||||||
].filter(Boolean),
|
].filter(Boolean),
|
||||||
plugins: [
|
plugins: [
|
||||||
// Part of ES2018. Converts {...a, b: 2} to Object.assign({}, a, {b: 2})
|
// Part of ES2018. Converts {...a, b: 2} to Object.assign({}, a, {b: 2})
|
||||||
@@ -72,14 +73,9 @@ module.exports.babelOptions = ({ latestBuild }) => ({
|
|||||||
"@babel/plugin-syntax-dynamic-import",
|
"@babel/plugin-syntax-dynamic-import",
|
||||||
"@babel/plugin-proposal-optional-chaining",
|
"@babel/plugin-proposal-optional-chaining",
|
||||||
"@babel/plugin-proposal-nullish-coalescing-operator",
|
"@babel/plugin-proposal-nullish-coalescing-operator",
|
||||||
[
|
["@babel/plugin-proposal-decorators", { decoratorsBeforeExport: true }],
|
||||||
require("@babel/plugin-proposal-decorators").default,
|
["@babel/plugin-proposal-private-methods", { loose: true }],
|
||||||
{ decoratorsBeforeExport: true },
|
["@babel/plugin-proposal-class-properties", { loose: true }],
|
||||||
],
|
|
||||||
[
|
|
||||||
require("@babel/plugin-proposal-class-properties").default,
|
|
||||||
{ loose: true },
|
|
||||||
],
|
|
||||||
].filter(Boolean),
|
].filter(Boolean),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const paths = require("./paths.js");
|
const paths = require("./paths.js");
|
||||||
|
@@ -85,6 +85,11 @@ gulp.task("copy-translations-app", async () => {
|
|||||||
copyTranslations(staticDir);
|
copyTranslations(staticDir);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
gulp.task("copy-translations-supervisor", async () => {
|
||||||
|
const staticDir = paths.hassio_output_static;
|
||||||
|
copyTranslations(staticDir);
|
||||||
|
});
|
||||||
|
|
||||||
gulp.task("copy-static-app", async () => {
|
gulp.task("copy-static-app", async () => {
|
||||||
const staticDir = paths.app_output_static;
|
const staticDir = paths.app_output_static;
|
||||||
// Basic static files
|
// Basic static files
|
||||||
|
@@ -10,6 +10,8 @@ require("./gen-icons-json.js");
|
|||||||
require("./webpack.js");
|
require("./webpack.js");
|
||||||
require("./compress.js");
|
require("./compress.js");
|
||||||
require("./rollup.js");
|
require("./rollup.js");
|
||||||
|
require("./gather-static.js");
|
||||||
|
require("./translations.js");
|
||||||
|
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"develop-hassio",
|
"develop-hassio",
|
||||||
@@ -20,6 +22,8 @@ gulp.task(
|
|||||||
"clean-hassio",
|
"clean-hassio",
|
||||||
"gen-icons-json",
|
"gen-icons-json",
|
||||||
"gen-index-hassio-dev",
|
"gen-index-hassio-dev",
|
||||||
|
"build-supervisor-translations",
|
||||||
|
"copy-translations-supervisor",
|
||||||
env.useRollup() ? "rollup-watch-hassio" : "webpack-watch-hassio"
|
env.useRollup() ? "rollup-watch-hassio" : "webpack-watch-hassio"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -32,6 +36,8 @@ gulp.task(
|
|||||||
},
|
},
|
||||||
"clean-hassio",
|
"clean-hassio",
|
||||||
"gen-icons-json",
|
"gen-icons-json",
|
||||||
|
"build-supervisor-translations",
|
||||||
|
"copy-translations-supervisor",
|
||||||
env.useRollup() ? "rollup-prod-hassio" : "webpack-prod-hassio",
|
env.useRollup() ? "rollup-prod-hassio" : "webpack-prod-hassio",
|
||||||
"gen-index-hassio-prod",
|
"gen-index-hassio-prod",
|
||||||
...// Don't compress running tests
|
...// Don't compress running tests
|
||||||
|
@@ -266,6 +266,7 @@ gulp.task(taskName, function () {
|
|||||||
TRANSLATION_FRAGMENTS.forEach((fragment) => {
|
TRANSLATION_FRAGMENTS.forEach((fragment) => {
|
||||||
delete data.ui.panel[fragment];
|
delete data.ui.panel[fragment];
|
||||||
});
|
});
|
||||||
|
delete data.supervisor;
|
||||||
return data;
|
return data;
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@@ -342,6 +343,62 @@ gulp.task(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
gulp.task("build-translation-fragment-supervisor", function () {
|
||||||
|
return gulp
|
||||||
|
.src(fullDir + "/*.json")
|
||||||
|
.pipe(transform((data) => data.supervisor))
|
||||||
|
.pipe(gulp.dest(workDir + "/supervisor"));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("build-translation-flatten-supervisor", function () {
|
||||||
|
return gulp
|
||||||
|
.src(workDir + "/supervisor/*.json")
|
||||||
|
.pipe(
|
||||||
|
transform(function (data) {
|
||||||
|
// Polymer.AppLocalizeBehavior requires flattened json
|
||||||
|
return flatten(data);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.pipe(gulp.dest(outDir));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("build-translation-write-metadata", function writeMetadata() {
|
||||||
|
return gulp
|
||||||
|
.src(
|
||||||
|
[
|
||||||
|
path.join(paths.translations_src, "translationMetadata.json"),
|
||||||
|
workDir + "/testMetadata.json",
|
||||||
|
workDir + "/translationFingerprints.json",
|
||||||
|
],
|
||||||
|
{ allowEmpty: true }
|
||||||
|
)
|
||||||
|
.pipe(merge({}))
|
||||||
|
.pipe(
|
||||||
|
transform(function (data) {
|
||||||
|
const newData = {};
|
||||||
|
Object.entries(data).forEach(([key, value]) => {
|
||||||
|
// Filter out translations without native name.
|
||||||
|
if (value.nativeName) {
|
||||||
|
newData[key] = value;
|
||||||
|
} else {
|
||||||
|
console.warn(
|
||||||
|
`Skipping language ${key}. Native name was not translated.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return newData;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.pipe(
|
||||||
|
transform((data) => ({
|
||||||
|
fragments: TRANSLATION_FRAGMENTS,
|
||||||
|
translations: data,
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
.pipe(rename("translationMetadata.json"))
|
||||||
|
.pipe(gulp.dest(workDir));
|
||||||
|
});
|
||||||
|
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"build-translations",
|
"build-translations",
|
||||||
gulp.series(
|
gulp.series(
|
||||||
@@ -353,42 +410,20 @@ gulp.task(
|
|||||||
gulp.parallel(...splitTasks),
|
gulp.parallel(...splitTasks),
|
||||||
"build-flattened-translations",
|
"build-flattened-translations",
|
||||||
"build-translation-fingerprints",
|
"build-translation-fingerprints",
|
||||||
function writeMetadata() {
|
"build-translation-write-metadata"
|
||||||
return gulp
|
)
|
||||||
.src(
|
);
|
||||||
[
|
|
||||||
path.join(paths.translations_src, "translationMetadata.json"),
|
gulp.task(
|
||||||
workDir + "/testMetadata.json",
|
"build-supervisor-translations",
|
||||||
workDir + "/translationFingerprints.json",
|
gulp.series(
|
||||||
],
|
"clean-translations",
|
||||||
{ allowEmpty: true }
|
"ensure-translations-build-dir",
|
||||||
)
|
"build-master-translation",
|
||||||
.pipe(merge({}))
|
"build-merged-translations",
|
||||||
.pipe(
|
"build-translation-fragment-supervisor",
|
||||||
transform(function (data) {
|
"build-translation-flatten-supervisor",
|
||||||
const newData = {};
|
"build-translation-fingerprints",
|
||||||
Object.entries(data).forEach(([key, value]) => {
|
"build-translation-write-metadata"
|
||||||
// Filter out translations without native name.
|
|
||||||
if (data[key].nativeName) {
|
|
||||||
newData[key] = data[key];
|
|
||||||
} else {
|
|
||||||
console.warn(
|
|
||||||
`Skipping language ${key}. Native name was not translated.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (data[key]) newData[key] = value;
|
|
||||||
});
|
|
||||||
return newData;
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.pipe(
|
|
||||||
transform((data) => ({
|
|
||||||
fragments: TRANSLATION_FRAGMENTS,
|
|
||||||
translations: data,
|
|
||||||
}))
|
|
||||||
)
|
|
||||||
.pipe(rename("translationMetadata.json"))
|
|
||||||
.pipe(gulp.dest(workDir));
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@@ -137,7 +137,12 @@ gulp.task("webpack-watch-hassio", () => {
|
|||||||
isProdBuild: false,
|
isProdBuild: false,
|
||||||
latestBuild: true,
|
latestBuild: true,
|
||||||
})
|
})
|
||||||
).watch({}, doneHandler());
|
).watch({ ignored: /build-translations/ }, doneHandler());
|
||||||
|
|
||||||
|
gulp.watch(
|
||||||
|
path.join(paths.translations_src, "en.json"),
|
||||||
|
gulp.series("build-supervisor-translations", "copy-translations-supervisor")
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("webpack-prod-hassio", () =>
|
gulp.task("webpack-prod-hassio", () =>
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@@ -34,6 +35,7 @@ module.exports = {
|
|||||||
|
|
||||||
hassio_dir: path.resolve(__dirname, "../hassio"),
|
hassio_dir: path.resolve(__dirname, "../hassio"),
|
||||||
hassio_output_root: path.resolve(__dirname, "../hassio/build"),
|
hassio_output_root: path.resolve(__dirname, "../hassio/build"),
|
||||||
|
hassio_output_static: path.resolve(__dirname, "../hassio/build/static"),
|
||||||
hassio_output_latest: path.resolve(
|
hassio_output_latest: path.resolve(
|
||||||
__dirname,
|
__dirname,
|
||||||
"../hassio/build/frontend_latest"
|
"../hassio/build/frontend_latest"
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
const commonjs = require("@rollup/plugin-commonjs");
|
const commonjs = require("@rollup/plugin-commonjs");
|
||||||
@@ -32,88 +33,82 @@ const createRollupConfig = ({
|
|||||||
publicPath,
|
publicPath,
|
||||||
dontHash,
|
dontHash,
|
||||||
isWDS,
|
isWDS,
|
||||||
}) => {
|
}) => ({
|
||||||
return {
|
/**
|
||||||
/**
|
* @type { import("rollup").InputOptions }
|
||||||
* @type { import("rollup").InputOptions }
|
*/
|
||||||
*/
|
inputOptions: {
|
||||||
inputOptions: {
|
input: entry,
|
||||||
input: entry,
|
// Some entry points contain no JavaScript. This setting silences a warning about that.
|
||||||
// Some entry points contain no JavaScript. This setting silences a warning about that.
|
// https://rollupjs.org/guide/en/#preserveentrysignatures
|
||||||
// https://rollupjs.org/guide/en/#preserveentrysignatures
|
preserveEntrySignatures: false,
|
||||||
preserveEntrySignatures: false,
|
plugins: [
|
||||||
plugins: [
|
ignore({
|
||||||
ignore({
|
files: bundle.emptyPackages({ latestBuild }),
|
||||||
files: bundle.emptyPackages({ latestBuild }),
|
}),
|
||||||
|
resolve({
|
||||||
|
extensions,
|
||||||
|
preferBuiltins: false,
|
||||||
|
browser: true,
|
||||||
|
rootDir: paths.polymer_dir,
|
||||||
|
}),
|
||||||
|
commonjs({
|
||||||
|
namedExports: {
|
||||||
|
"js-yaml": ["safeDump", "safeLoad"],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
json(),
|
||||||
|
babel({
|
||||||
|
...bundle.babelOptions({ latestBuild }),
|
||||||
|
extensions,
|
||||||
|
exclude: bundle.babelExclude(),
|
||||||
|
babelHelpers: isWDS ? "inline" : "bundled",
|
||||||
|
}),
|
||||||
|
string({
|
||||||
|
// Import certain extensions as strings
|
||||||
|
include: [path.join(paths.polymer_dir, "node_modules/**/*.css")],
|
||||||
|
}),
|
||||||
|
replace(bundle.definedVars({ isProdBuild, latestBuild, defineOverlay })),
|
||||||
|
!isWDS &&
|
||||||
|
manifest({
|
||||||
|
publicPath,
|
||||||
}),
|
}),
|
||||||
resolve({
|
!isWDS && worker(),
|
||||||
extensions,
|
!isWDS && dontHashPlugin({ dontHash }),
|
||||||
preferBuiltins: false,
|
!isWDS && isProdBuild && terser(bundle.terserOptions(latestBuild)),
|
||||||
browser: true,
|
!isWDS &&
|
||||||
rootDir: paths.polymer_dir,
|
isStatsBuild &&
|
||||||
|
visualizer({
|
||||||
|
// https://github.com/btd/rollup-plugin-visualizer#options
|
||||||
|
open: true,
|
||||||
|
sourcemap: true,
|
||||||
}),
|
}),
|
||||||
commonjs({
|
].filter(Boolean),
|
||||||
namedExports: {
|
},
|
||||||
"js-yaml": ["safeDump", "safeLoad"],
|
/**
|
||||||
},
|
* @type { import("rollup").OutputOptions }
|
||||||
}),
|
*/
|
||||||
json(),
|
outputOptions: {
|
||||||
babel({
|
// https://rollupjs.org/guide/en/#outputdir
|
||||||
...bundle.babelOptions({ latestBuild }),
|
dir: outputPath,
|
||||||
extensions,
|
// https://rollupjs.org/guide/en/#outputformat
|
||||||
exclude: bundle.babelExclude(),
|
format: latestBuild ? "es" : "systemjs",
|
||||||
babelHelpers: isWDS ? "inline" : "bundled",
|
// https://rollupjs.org/guide/en/#outputexternallivebindings
|
||||||
}),
|
externalLiveBindings: false,
|
||||||
string({
|
// https://rollupjs.org/guide/en/#outputentryfilenames
|
||||||
// Import certain extensions as strings
|
// https://rollupjs.org/guide/en/#outputchunkfilenames
|
||||||
include: [path.join(paths.polymer_dir, "node_modules/**/*.css")],
|
// https://rollupjs.org/guide/en/#outputassetfilenames
|
||||||
}),
|
entryFileNames:
|
||||||
replace(
|
isProdBuild && !isStatsBuild ? "[name]-[hash].js" : "[name].js",
|
||||||
bundle.definedVars({ isProdBuild, latestBuild, defineOverlay })
|
chunkFileNames: isProdBuild && !isStatsBuild ? "c.[hash].js" : "[name].js",
|
||||||
),
|
assetFileNames: isProdBuild && !isStatsBuild ? "a.[hash].js" : "[name].js",
|
||||||
!isWDS &&
|
// https://rollupjs.org/guide/en/#outputsourcemap
|
||||||
manifest({
|
sourcemap: isProdBuild ? true : "inline",
|
||||||
publicPath,
|
},
|
||||||
}),
|
});
|
||||||
!isWDS && worker(),
|
|
||||||
!isWDS && dontHashPlugin({ dontHash }),
|
|
||||||
!isWDS && isProdBuild && terser(bundle.terserOptions(latestBuild)),
|
|
||||||
!isWDS &&
|
|
||||||
isStatsBuild &&
|
|
||||||
visualizer({
|
|
||||||
// https://github.com/btd/rollup-plugin-visualizer#options
|
|
||||||
open: true,
|
|
||||||
sourcemap: true,
|
|
||||||
}),
|
|
||||||
].filter(Boolean),
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @type { import("rollup").OutputOptions }
|
|
||||||
*/
|
|
||||||
outputOptions: {
|
|
||||||
// https://rollupjs.org/guide/en/#outputdir
|
|
||||||
dir: outputPath,
|
|
||||||
// https://rollupjs.org/guide/en/#outputformat
|
|
||||||
format: latestBuild ? "es" : "systemjs",
|
|
||||||
// https://rollupjs.org/guide/en/#outputexternallivebindings
|
|
||||||
externalLiveBindings: false,
|
|
||||||
// https://rollupjs.org/guide/en/#outputentryfilenames
|
|
||||||
// https://rollupjs.org/guide/en/#outputchunkfilenames
|
|
||||||
// https://rollupjs.org/guide/en/#outputassetfilenames
|
|
||||||
entryFileNames:
|
|
||||||
isProdBuild && !isStatsBuild ? "[name]-[hash].js" : "[name].js",
|
|
||||||
chunkFileNames:
|
|
||||||
isProdBuild && !isStatsBuild ? "c.[hash].js" : "[name].js",
|
|
||||||
assetFileNames:
|
|
||||||
isProdBuild && !isStatsBuild ? "a.[hash].js" : "[name].js",
|
|
||||||
// https://rollupjs.org/guide/en/#outputsourcemap
|
|
||||||
sourcemap: isProdBuild ? true : "inline",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild, isWDS }) => {
|
const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild, isWDS }) =>
|
||||||
return createRollupConfig(
|
createRollupConfig(
|
||||||
bundle.config.app({
|
bundle.config.app({
|
||||||
isProdBuild,
|
isProdBuild,
|
||||||
latestBuild,
|
latestBuild,
|
||||||
@@ -121,31 +116,24 @@ const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild, isWDS }) => {
|
|||||||
isWDS,
|
isWDS,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
const createDemoConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => {
|
const createDemoConfig = ({ isProdBuild, latestBuild, isStatsBuild }) =>
|
||||||
return createRollupConfig(
|
createRollupConfig(
|
||||||
bundle.config.demo({
|
bundle.config.demo({
|
||||||
isProdBuild,
|
isProdBuild,
|
||||||
latestBuild,
|
latestBuild,
|
||||||
isStatsBuild,
|
isStatsBuild,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
const createCastConfig = ({ isProdBuild, latestBuild }) => {
|
const createCastConfig = ({ isProdBuild, latestBuild }) =>
|
||||||
return createRollupConfig(bundle.config.cast({ isProdBuild, latestBuild }));
|
createRollupConfig(bundle.config.cast({ isProdBuild, latestBuild }));
|
||||||
};
|
|
||||||
|
|
||||||
const createHassioConfig = ({ isProdBuild, latestBuild }) => {
|
const createHassioConfig = ({ isProdBuild, latestBuild }) =>
|
||||||
return createRollupConfig(bundle.config.hassio({ isProdBuild, latestBuild }));
|
createRollupConfig(bundle.config.hassio({ isProdBuild, latestBuild }));
|
||||||
};
|
|
||||||
|
|
||||||
const createGalleryConfig = ({ isProdBuild, latestBuild }) => {
|
const createGalleryConfig = ({ isProdBuild, latestBuild }) =>
|
||||||
return createRollupConfig(
|
createRollupConfig(bundle.config.gallery({ isProdBuild, latestBuild }));
|
||||||
bundle.config.gallery({ isProdBuild, latestBuild })
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createAppConfig,
|
createAppConfig,
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
|
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||||
const webpack = require("webpack");
|
const webpack = require("webpack");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const TerserPlugin = require("terser-webpack-plugin");
|
const TerserPlugin = require("terser-webpack-plugin");
|
||||||
const ManifestPlugin = require("webpack-manifest-plugin");
|
const { WebpackManifestPlugin } = require("webpack-manifest-plugin");
|
||||||
const paths = require("./paths.js");
|
const paths = require("./paths.js");
|
||||||
const bundle = require("./bundle");
|
const bundle = require("./bundle.js");
|
||||||
const log = require("fancy-log");
|
const log = require("fancy-log");
|
||||||
|
|
||||||
class LogStartCompilePlugin {
|
class LogStartCompilePlugin {
|
||||||
@@ -36,6 +37,7 @@ 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",
|
||||||
@@ -67,7 +69,7 @@ const createWebpackConfig = ({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new ManifestPlugin({
|
new WebpackManifestPlugin({
|
||||||
// Only include the JS of entrypoints
|
// Only include the JS of entrypoints
|
||||||
filter: (file) => file.isInitial && !file.name.endsWith(".map"),
|
filter: (file) => file.isInitial && !file.name.endsWith(".map"),
|
||||||
}),
|
}),
|
||||||
@@ -93,6 +95,7 @@ const createWebpackConfig = ({
|
|||||||
? path.resolve(context, resource)
|
? path.resolve(context, resource)
|
||||||
: require.resolve(resource);
|
: require.resolve(resource);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
console.error(
|
console.error(
|
||||||
"Error in Home Assistant ignore plugin",
|
"Error in Home Assistant ignore plugin",
|
||||||
resource,
|
resource,
|
||||||
@@ -114,7 +117,7 @@ const createWebpackConfig = ({
|
|||||||
new webpack.NormalModuleReplacementPlugin(
|
new webpack.NormalModuleReplacementPlugin(
|
||||||
new RegExp(
|
new RegExp(
|
||||||
require.resolve(
|
require.resolve(
|
||||||
"lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.js"
|
"@lit-labs/virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.js"
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
path.resolve(paths.polymer_dir, "src/resources/EventTarget-ponyfill.js")
|
path.resolve(paths.polymer_dir, "src/resources/EventTarget-ponyfill.js")
|
||||||
@@ -123,6 +126,11 @@ const createWebpackConfig = ({
|
|||||||
].filter(Boolean),
|
].filter(Boolean),
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: [".ts", ".js", ".json"],
|
extensions: [".ts", ".js", ".json"],
|
||||||
|
alias: {
|
||||||
|
"lit/decorators$": "lit/decorators.js",
|
||||||
|
"lit/directive$": "lit/directive.js",
|
||||||
|
"lit/polyfill-support$": "lit/polyfill-support.js",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: ({ chunk }) => {
|
filename: ({ chunk }) => {
|
||||||
@@ -131,22 +139,6 @@ 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"
|
||||||
@@ -159,33 +151,24 @@ const createWebpackConfig = ({
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => {
|
const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild }) =>
|
||||||
return createWebpackConfig(
|
createWebpackConfig(
|
||||||
bundle.config.app({ isProdBuild, latestBuild, isStatsBuild })
|
bundle.config.app({ isProdBuild, latestBuild, isStatsBuild })
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
const createDemoConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => {
|
const createDemoConfig = ({ isProdBuild, latestBuild, isStatsBuild }) =>
|
||||||
return createWebpackConfig(
|
createWebpackConfig(
|
||||||
bundle.config.demo({ isProdBuild, latestBuild, isStatsBuild })
|
bundle.config.demo({ isProdBuild, latestBuild, isStatsBuild })
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
const createCastConfig = ({ isProdBuild, latestBuild }) => {
|
const createCastConfig = ({ isProdBuild, latestBuild }) =>
|
||||||
return createWebpackConfig(bundle.config.cast({ isProdBuild, latestBuild }));
|
createWebpackConfig(bundle.config.cast({ isProdBuild, latestBuild }));
|
||||||
};
|
|
||||||
|
|
||||||
const createHassioConfig = ({ isProdBuild, latestBuild }) => {
|
const createHassioConfig = ({ isProdBuild, latestBuild }) =>
|
||||||
return createWebpackConfig(
|
createWebpackConfig(bundle.config.hassio({ isProdBuild, latestBuild }));
|
||||||
bundle.config.hassio({ isProdBuild, latestBuild })
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const createGalleryConfig = ({ isProdBuild, latestBuild }) => {
|
const createGalleryConfig = ({ isProdBuild, latestBuild }) =>
|
||||||
return createWebpackConfig(
|
createWebpackConfig(bundle.config.gallery({ isProdBuild, latestBuild }));
|
||||||
bundle.config.gallery({ isProdBuild, latestBuild })
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createAppConfig,
|
createAppConfig,
|
||||||
|
@@ -1,16 +1,9 @@
|
|||||||
|
import "@material/mwc-button/mwc-button";
|
||||||
import "@polymer/paper-item/paper-icon-item";
|
import "@polymer/paper-item/paper-icon-item";
|
||||||
import "@polymer/paper-listbox/paper-listbox";
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
import { Auth, Connection } from "home-assistant-js-websocket";
|
import { Auth, Connection } from "home-assistant-js-websocket";
|
||||||
import {
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
css,
|
import { customElement, property, state } from "lit/decorators";
|
||||||
CSSResult,
|
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
property,
|
|
||||||
internalProperty,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { CastManager } from "../../../../src/cast/cast_manager";
|
import { CastManager } from "../../../../src/cast/cast_manager";
|
||||||
import {
|
import {
|
||||||
castSendShowLovelaceView,
|
castSendShowLovelaceView,
|
||||||
@@ -32,7 +25,6 @@ import {
|
|||||||
import "../../../../src/layouts/hass-loading-screen";
|
import "../../../../src/layouts/hass-loading-screen";
|
||||||
import { generateDefaultViewConfig } from "../../../../src/panels/lovelace/common/generate-lovelace-config";
|
import { generateDefaultViewConfig } from "../../../../src/panels/lovelace/common/generate-lovelace-config";
|
||||||
import "./hc-layout";
|
import "./hc-layout";
|
||||||
import "@material/mwc-button/mwc-button";
|
|
||||||
|
|
||||||
@customElement("hc-cast")
|
@customElement("hc-cast")
|
||||||
class HcCast extends LitElement {
|
class HcCast extends LitElement {
|
||||||
@@ -42,21 +34,19 @@ class HcCast extends LitElement {
|
|||||||
|
|
||||||
@property() public castManager!: CastManager;
|
@property() public castManager!: CastManager;
|
||||||
|
|
||||||
@internalProperty() private askWrite = false;
|
@state() private askWrite = false;
|
||||||
|
|
||||||
@internalProperty() private lovelaceConfig?: LovelaceConfig | null;
|
@state() private lovelaceConfig?: LovelaceConfig | null;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (this.lovelaceConfig === undefined) {
|
if (this.lovelaceConfig === undefined) {
|
||||||
return html` <hass-loading-screen no-toolbar></hass-loading-screen>> `;
|
return html`<hass-loading-screen no-toolbar></hass-loading-screen>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const error =
|
const error =
|
||||||
this.castManager.castState === "NO_DEVICES_AVAILABLE"
|
this.castManager.castState === "NO_DEVICES_AVAILABLE"
|
||||||
? html`
|
? html`
|
||||||
<p>
|
<p>There were no suitable Chromecast devices to cast to found.</p>
|
||||||
There were no suitable Chromecast devices to cast to found.
|
|
||||||
</p>
|
|
||||||
`
|
`
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
@@ -206,7 +196,7 @@ class HcCast extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResultGroup {
|
||||||
return css`
|
return css`
|
||||||
.center-item {
|
.center-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@@ -11,15 +11,8 @@ import {
|
|||||||
getAuth,
|
getAuth,
|
||||||
getAuthOptions,
|
getAuthOptions,
|
||||||
} from "home-assistant-js-websocket";
|
} from "home-assistant-js-websocket";
|
||||||
import {
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
css,
|
import { customElement, state } from "lit/decorators";
|
||||||
CSSResult,
|
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
TemplateResult,
|
|
||||||
internalProperty,
|
|
||||||
} from "lit-element";
|
|
||||||
import { CastManager, getCastManager } from "../../../../src/cast/cast_manager";
|
import { CastManager, getCastManager } from "../../../../src/cast/cast_manager";
|
||||||
import { castSendShowDemo } from "../../../../src/cast/receiver_messages";
|
import { castSendShowDemo } from "../../../../src/cast/receiver_messages";
|
||||||
import {
|
import {
|
||||||
@@ -60,19 +53,19 @@ const INTRO = html`
|
|||||||
|
|
||||||
@customElement("hc-connect")
|
@customElement("hc-connect")
|
||||||
export class HcConnect extends LitElement {
|
export class HcConnect extends LitElement {
|
||||||
@internalProperty() private loading = false;
|
@state() private loading = false;
|
||||||
|
|
||||||
// If we had stored credentials but we cannot connect,
|
// If we had stored credentials but we cannot connect,
|
||||||
// show a screen asking retry or logout.
|
// show a screen asking retry or logout.
|
||||||
@internalProperty() private cannotConnect = false;
|
@state() private cannotConnect = false;
|
||||||
|
|
||||||
@internalProperty() private error?: string | TemplateResult;
|
@state() private error?: string | TemplateResult;
|
||||||
|
|
||||||
@internalProperty() private auth?: Auth;
|
@state() private auth?: Auth;
|
||||||
|
|
||||||
@internalProperty() private connection?: Connection;
|
@state() private connection?: Connection;
|
||||||
|
|
||||||
@internalProperty() private castManager?: CastManager | null;
|
@state() private castManager?: CastManager | null;
|
||||||
|
|
||||||
private openDemo = false;
|
private openDemo = false;
|
||||||
|
|
||||||
@@ -86,9 +79,7 @@ export class HcConnect extends LitElement {
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<mwc-button>
|
<mwc-button> Retry </mwc-button>
|
||||||
Retry
|
|
||||||
</mwc-button>
|
|
||||||
</a>
|
</a>
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<mwc-button @click=${this._handleLogout}>Log out</mwc-button>
|
<mwc-button @click=${this._handleLogout}>Log out</mwc-button>
|
||||||
@@ -299,7 +290,7 @@ export class HcConnect extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResultGroup {
|
||||||
return css`
|
return css`
|
||||||
.card-content a {
|
.card-content a {
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
|
@@ -4,15 +4,8 @@ import {
|
|||||||
getUser,
|
getUser,
|
||||||
HassUser,
|
HassUser,
|
||||||
} from "home-assistant-js-websocket";
|
} from "home-assistant-js-websocket";
|
||||||
import {
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
css,
|
import { customElement, property } from "lit/decorators";
|
||||||
CSSResult,
|
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
property,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import "../../../../src/components/ha-card";
|
import "../../../../src/components/ha-card";
|
||||||
|
|
||||||
@customElement("hc-layout")
|
@customElement("hc-layout")
|
||||||
@@ -69,7 +62,7 @@ class HcLayout extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResultGroup {
|
||||||
return css`
|
return css`
|
||||||
:host {
|
:host {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -98,8 +91,12 @@ class HcLayout extends LitElement {
|
|||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
padding: 24px 16px 16px;
|
padding: 24px 16px 16px;
|
||||||
display: block;
|
display: block;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hero {
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
}
|
||||||
.subtitle {
|
.subtitle {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
|
@@ -1,10 +1,5 @@
|
|||||||
import {
|
import { html, TemplateResult } from "lit";
|
||||||
customElement,
|
import { customElement, property, state } from "lit/decorators";
|
||||||
html,
|
|
||||||
property,
|
|
||||||
internalProperty,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { mockHistory } from "../../../../demo/src/stubs/history";
|
import { mockHistory } from "../../../../demo/src/stubs/history";
|
||||||
import { LovelaceConfig } from "../../../../src/data/lovelace";
|
import { LovelaceConfig } from "../../../../src/data/lovelace";
|
||||||
import {
|
import {
|
||||||
@@ -21,7 +16,7 @@ import "./hc-lovelace";
|
|||||||
class HcDemo extends HassElement {
|
class HcDemo extends HassElement {
|
||||||
@property({ attribute: false }) public lovelacePath!: string;
|
@property({ attribute: false }) public lovelacePath!: string;
|
||||||
|
|
||||||
@internalProperty() private _lovelaceConfig?: LovelaceConfig;
|
@state() private _lovelaceConfig?: LovelaceConfig;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (!this._lovelaceConfig) {
|
if (!this._lovelaceConfig) {
|
||||||
@@ -38,10 +33,10 @@ class HcDemo extends HassElement {
|
|||||||
|
|
||||||
protected firstUpdated(changedProps) {
|
protected firstUpdated(changedProps) {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
this._initialize();
|
this._initializeHass();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _initialize() {
|
private async _initializeHass() {
|
||||||
const initial: Partial<MockHomeAssistant> = {
|
const initial: Partial<MockHomeAssistant> = {
|
||||||
// Override updateHass so that the correct hass lifecycle methods are called
|
// Override updateHass so that the correct hass lifecycle methods are called
|
||||||
updateHass: (hassUpdate: Partial<HomeAssistant>) =>
|
updateHass: (hassUpdate: Partial<HomeAssistant>) =>
|
||||||
|
@@ -1,12 +1,5 @@
|
|||||||
import {
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
css,
|
import { customElement, property } from "lit/decorators";
|
||||||
CSSResult,
|
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
property,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { HomeAssistant } from "../../../../src/types";
|
import { HomeAssistant } from "../../../../src/types";
|
||||||
|
|
||||||
@customElement("hc-launch-screen")
|
@customElement("hc-launch-screen")
|
||||||
@@ -29,7 +22,7 @@ class HcLaunchScreen extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResultGroup {
|
||||||
return css`
|
return css`
|
||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
|
@@ -1,12 +1,5 @@
|
|||||||
import {
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
css,
|
import { customElement, property } from "lit/decorators";
|
||||||
CSSResult,
|
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
property,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { LovelaceConfig } from "../../../../src/data/lovelace";
|
import { LovelaceConfig } from "../../../../src/data/lovelace";
|
||||||
import { Lovelace } from "../../../../src/panels/lovelace/types";
|
import { Lovelace } from "../../../../src/panels/lovelace/types";
|
||||||
import "../../../../src/panels/lovelace/views/hui-view";
|
import "../../../../src/panels/lovelace/views/hui-view";
|
||||||
@@ -35,11 +28,12 @@ class HcLovelace extends LitElement {
|
|||||||
}
|
}
|
||||||
const lovelace: Lovelace = {
|
const lovelace: Lovelace = {
|
||||||
config: this.lovelaceConfig,
|
config: this.lovelaceConfig,
|
||||||
|
rawConfig: this.lovelaceConfig,
|
||||||
editMode: false,
|
editMode: false,
|
||||||
urlPath: this.urlPath!,
|
urlPath: this.urlPath!,
|
||||||
enableFullEditMode: () => undefined,
|
enableFullEditMode: () => undefined,
|
||||||
mode: "storage",
|
mode: "storage",
|
||||||
language: "en",
|
locale: this.hass.locale,
|
||||||
saveConfig: async () => undefined,
|
saveConfig: async () => undefined,
|
||||||
deleteConfig: async () => undefined,
|
deleteConfig: async () => undefined,
|
||||||
setEditMode: () => undefined,
|
setEditMode: () => undefined,
|
||||||
@@ -90,10 +84,11 @@ class HcLovelace extends LitElement {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResultGroup {
|
||||||
return css`
|
return css`
|
||||||
:host {
|
:host {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
|
height: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
@@ -3,12 +3,8 @@ import {
|
|||||||
getAuth,
|
getAuth,
|
||||||
UnsubscribeFunc,
|
UnsubscribeFunc,
|
||||||
} from "home-assistant-js-websocket";
|
} from "home-assistant-js-websocket";
|
||||||
import {
|
import { html, TemplateResult } from "lit";
|
||||||
customElement,
|
import { customElement, state } from "lit/decorators";
|
||||||
html,
|
|
||||||
internalProperty,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { CAST_NS } from "../../../../src/cast/const";
|
import { CAST_NS } from "../../../../src/cast/const";
|
||||||
import {
|
import {
|
||||||
ConnectMessage,
|
ConnectMessage,
|
||||||
@@ -36,13 +32,13 @@ let resourcesLoaded = false;
|
|||||||
|
|
||||||
@customElement("hc-main")
|
@customElement("hc-main")
|
||||||
export class HcMain extends HassElement {
|
export class HcMain extends HassElement {
|
||||||
@internalProperty() private _showDemo = false;
|
@state() private _showDemo = false;
|
||||||
|
|
||||||
@internalProperty() private _lovelaceConfig?: LovelaceConfig;
|
@state() private _lovelaceConfig?: LovelaceConfig;
|
||||||
|
|
||||||
@internalProperty() private _lovelacePath: string | number | null = null;
|
@state() private _lovelacePath: string | number | null = null;
|
||||||
|
|
||||||
@internalProperty() private _error?: string;
|
@state() private _error?: string;
|
||||||
|
|
||||||
private _unsubLovelace?: UnsubscribeFunc;
|
private _unsubLovelace?: UnsubscribeFunc;
|
||||||
|
|
||||||
@@ -221,11 +217,17 @@ export class HcMain extends HassElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _generateLovelaceConfig() {
|
private async _generateLovelaceConfig() {
|
||||||
const { generateLovelaceConfigFromHass } = await import(
|
const { generateLovelaceDashboardStrategy } = await import(
|
||||||
"../../../../src/panels/lovelace/common/generate-lovelace-config"
|
"../../../../src/panels/lovelace/strategies/get-strategy"
|
||||||
);
|
);
|
||||||
this._handleNewLovelaceConfig(
|
this._handleNewLovelaceConfig(
|
||||||
await generateLovelaceConfigFromHass(this.hass!)
|
await generateLovelaceDashboardStrategy(
|
||||||
|
{
|
||||||
|
hass: this.hass!,
|
||||||
|
narrow: false,
|
||||||
|
},
|
||||||
|
"original-states"
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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/roboto";
|
|
||||||
import "../../../src/resources/ha-style";
|
import "../../../src/resources/ha-style";
|
||||||
|
import "../../../src/resources/roboto";
|
||||||
import "./layout/hc-lovelace";
|
import "./layout/hc-lovelace";
|
||||||
|
@@ -54,6 +54,8 @@ 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": {
|
||||||
@@ -61,6 +63,8 @@ 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": {
|
||||||
@@ -242,11 +246,15 @@ export const demoEntitiesArsaboo: DemoConfig["entities"] = (localize) =>
|
|||||||
|
|
||||||
"light.living_room_lights": {
|
"light.living_room_lights": {
|
||||||
entity_id: "light.living_room_lights",
|
entity_id: "light.living_room_lights",
|
||||||
state: "off",
|
state: "on",
|
||||||
attributes: {
|
attributes: {
|
||||||
min_mireds: 111,
|
min_mireds: 111,
|
||||||
max_mireds: 400,
|
max_mireds: 400,
|
||||||
|
brightness: 175,
|
||||||
|
color_temp: 300,
|
||||||
|
supported_color_modes: ["brightness", "color_temp"],
|
||||||
friendly_name: "Living Room Lights",
|
friendly_name: "Living Room Lights",
|
||||||
|
color_mode: "color_temp",
|
||||||
supported_features: 55,
|
supported_features: 55,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -259,13 +267,27 @@ export const demoEntitiesArsaboo: DemoConfig["entities"] = (localize) =>
|
|||||||
},
|
},
|
||||||
"light.kitchen_lights": {
|
"light.kitchen_lights": {
|
||||||
entity_id: "light.kitchen_lights",
|
entity_id: "light.kitchen_lights",
|
||||||
|
state: "on",
|
||||||
|
attributes: {
|
||||||
|
min_mireds: 111,
|
||||||
|
max_mireds: 400,
|
||||||
|
brightness: 200,
|
||||||
|
rgb_color: [255, 175, 96],
|
||||||
|
supported_color_modes: ["brightness", "color_temp", "rgb"],
|
||||||
|
color_mode: "rgb",
|
||||||
|
friendly_name: "Kitchen Lights",
|
||||||
|
supported_features: 55,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"light.lifx5": {
|
||||||
|
entity_id: "light.lifx5",
|
||||||
state: "off",
|
state: "off",
|
||||||
attributes: {
|
attributes: {
|
||||||
friendly_name: "Kitchen lights",
|
supported_color_modes: ["brightness"],
|
||||||
|
friendly_name: "Garage Lights",
|
||||||
supported_features: 1,
|
supported_features: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
"sensor.plexspy": {
|
"sensor.plexspy": {
|
||||||
entity_id: "sensor.plexspy",
|
entity_id: "sensor.plexspy",
|
||||||
state: "0",
|
state: "0",
|
||||||
@@ -478,16 +500,6 @@ export const demoEntitiesArsaboo: DemoConfig["entities"] = (localize) =>
|
|||||||
icon: "hademo:history",
|
icon: "hademo:history",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"light.lifx5": {
|
|
||||||
entity_id: "light.lifx5",
|
|
||||||
state: "on",
|
|
||||||
attributes: {
|
|
||||||
min_mireds: 111,
|
|
||||||
max_mireds: 400,
|
|
||||||
friendly_name: "Garage lights",
|
|
||||||
supported_features: 55,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"sensor.alok_to_home": {
|
"sensor.alok_to_home": {
|
||||||
entity_id: "sensor.alok_to_home",
|
entity_id: "sensor.alok_to_home",
|
||||||
state: "41",
|
state: "41",
|
||||||
|
@@ -12,6 +12,7 @@ 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,49 +3,7 @@ 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: [
|
||||||
@@ -603,89 +561,6 @@ 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",
|
||||||
@@ -722,46 +597,8 @@ 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:
|
||||||
@@ -881,26 +718,13 @@ 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": "20px",
|
"font-size": "50px",
|
||||||
left: "44%",
|
left: "30%",
|
||||||
},
|
},
|
||||||
type: "state-label",
|
type: "state-label",
|
||||||
entity: "sensor.us_air_pollution_level_2",
|
entity: "sensor.us_air_pollution_level_2",
|
||||||
@@ -920,7 +744,7 @@ export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
|
|||||||
style: {
|
style: {
|
||||||
color: "white",
|
color: "white",
|
||||||
top: "80%",
|
top: "80%",
|
||||||
left: "52%",
|
left: "48%",
|
||||||
},
|
},
|
||||||
type: "state-icon",
|
type: "state-icon",
|
||||||
entity: "sensor.us_main_pollutant_2",
|
entity: "sensor.us_main_pollutant_2",
|
||||||
@@ -1411,6 +1235,7 @@ 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,7 +101,12 @@ 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: { friendly_name: "Battery", icon: "mdi:battery-60" },
|
attributes: {
|
||||||
|
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",
|
||||||
@@ -164,7 +169,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: "None",
|
state: "Rainbow",
|
||||||
attributes: {
|
attributes: {
|
||||||
options: [
|
options: [
|
||||||
"None",
|
"None",
|
||||||
@@ -186,7 +191,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: "None",
|
state: "Party",
|
||||||
attributes: {
|
attributes: {
|
||||||
options: [
|
options: [
|
||||||
"None",
|
"None",
|
||||||
@@ -457,7 +462,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: "Nedladdning",
|
friendly_name: "Downloading",
|
||||||
icon: "mdi:file-download",
|
icon: "mdi:file-download",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -471,7 +476,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: "Uppladdning",
|
friendly_name: "Uploading",
|
||||||
icon: "mdi:file-upload",
|
icon: "mdi:file-upload",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@@ -2,44 +2,7 @@ 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: [
|
||||||
@@ -64,7 +27,7 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
|
|||||||
style: {
|
style: {
|
||||||
color: "white",
|
color: "white",
|
||||||
top: "93%",
|
top: "93%",
|
||||||
left: "90%",
|
left: "85%",
|
||||||
},
|
},
|
||||||
type: "state-label",
|
type: "state-label",
|
||||||
entity: "sensor.battery_oskar",
|
entity: "sensor.battery_oskar",
|
||||||
@@ -87,7 +50,7 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
|
|||||||
{
|
{
|
||||||
style: {
|
style: {
|
||||||
color: "white",
|
color: "white",
|
||||||
top: "92%",
|
top: "93%",
|
||||||
left: "20%",
|
left: "20%",
|
||||||
},
|
},
|
||||||
type: "state-label",
|
type: "state-label",
|
||||||
@@ -96,8 +59,8 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
|
|||||||
{
|
{
|
||||||
style: {
|
style: {
|
||||||
color: "white",
|
color: "white",
|
||||||
top: "92%",
|
top: "93%",
|
||||||
left: "90%",
|
left: "85%",
|
||||||
},
|
},
|
||||||
type: "state-label",
|
type: "state-label",
|
||||||
entity: "sensor.battery_bella",
|
entity: "sensor.battery_bella",
|
||||||
@@ -105,7 +68,7 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
|
|||||||
{
|
{
|
||||||
style: {
|
style: {
|
||||||
color: "white",
|
color: "white",
|
||||||
top: "92%",
|
top: "93%",
|
||||||
left: "55%",
|
left: "55%",
|
||||||
},
|
},
|
||||||
type: "state-label",
|
type: "state-label",
|
||||||
@@ -131,78 +94,6 @@ 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: [
|
||||||
{
|
{
|
||||||
@@ -226,10 +117,6 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
|
|||||||
],
|
],
|
||||||
type: "vertical-stack",
|
type: "vertical-stack",
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// url: "https://embed.windy.com/embed2.html",
|
|
||||||
// type: "iframe",
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
entities: [
|
entities: [
|
||||||
{
|
{
|
||||||
@@ -263,6 +150,7 @@ 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"],
|
||||||
@@ -270,32 +158,6 @@ 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",
|
||||||
@@ -378,41 +240,9 @@ 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",
|
||||||
},
|
},
|
||||||
@@ -422,29 +252,10 @@ 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",
|
||||||
},
|
},
|
||||||
|
@@ -1114,6 +1114,9 @@ export const demoEntitiesTeachingbirds: DemoConfig["entities"] = () =>
|
|||||||
min_mireds: 153,
|
min_mireds: 153,
|
||||||
max_mireds: 500,
|
max_mireds: 500,
|
||||||
brightness: 63,
|
brightness: 63,
|
||||||
|
color_temp: 200,
|
||||||
|
supported_color_modes: ["brightness", "color_temp", "rgb"],
|
||||||
|
color_mode: "color_temp",
|
||||||
friendly_name: "Upstairs lights",
|
friendly_name: "Upstairs lights",
|
||||||
supported_features: 63,
|
supported_features: 63,
|
||||||
custom_ui_state_card: "state-card-custom-ui",
|
custom_ui_state_card: "state-card-custom-ui",
|
||||||
@@ -1125,6 +1128,7 @@ export const demoEntitiesTeachingbirds: DemoConfig["entities"] = () =>
|
|||||||
attributes: {
|
attributes: {
|
||||||
friendly_name: "Walk in closet lights",
|
friendly_name: "Walk in closet lights",
|
||||||
supported_features: 41,
|
supported_features: 41,
|
||||||
|
supported_color_modes: ["brightness", "color_temp"],
|
||||||
custom_ui_state_card: "state-card-custom-ui",
|
custom_ui_state_card: "state-card-custom-ui",
|
||||||
icon: "mdi:wall-sconce",
|
icon: "mdi:wall-sconce",
|
||||||
},
|
},
|
||||||
@@ -1136,6 +1140,8 @@ export const demoEntitiesTeachingbirds: DemoConfig["entities"] = () =>
|
|||||||
brightness: 254,
|
brightness: 254,
|
||||||
friendly_name: "Outdoor lights",
|
friendly_name: "Outdoor lights",
|
||||||
supported_features: 41,
|
supported_features: 41,
|
||||||
|
supported_color_modes: ["brightness"],
|
||||||
|
color_mode: "brightness",
|
||||||
custom_ui_state_card: "state-card-custom-ui",
|
custom_ui_state_card: "state-card-custom-ui",
|
||||||
icon: "mdi:wall-sconce",
|
icon: "mdi:wall-sconce",
|
||||||
},
|
},
|
||||||
@@ -1148,6 +1154,8 @@ export const demoEntitiesTeachingbirds: DemoConfig["entities"] = () =>
|
|||||||
max_mireds: 500,
|
max_mireds: 500,
|
||||||
brightness: 128,
|
brightness: 128,
|
||||||
color_temp: 366,
|
color_temp: 366,
|
||||||
|
supported_color_modes: ["brightness", "color_temp", "rgb"],
|
||||||
|
color_mode: "color_temp",
|
||||||
effect_list: ["colorloop"],
|
effect_list: ["colorloop"],
|
||||||
friendly_name: "Downstairs lights",
|
friendly_name: "Downstairs lights",
|
||||||
supported_features: 63,
|
supported_features: 63,
|
||||||
@@ -1307,6 +1315,7 @@ export const demoEntitiesTeachingbirds: DemoConfig["entities"] = () =>
|
|||||||
attributes: {
|
attributes: {
|
||||||
min_mireds: 153,
|
min_mireds: 153,
|
||||||
max_mireds: 500,
|
max_mireds: 500,
|
||||||
|
supported_color_modes: ["brightness", "color_temp"],
|
||||||
is_deconz_group: false,
|
is_deconz_group: false,
|
||||||
friendly_name: "Bedside Lamp",
|
friendly_name: "Bedside Lamp",
|
||||||
supported_features: 63,
|
supported_features: 63,
|
||||||
@@ -1320,6 +1329,7 @@ export const demoEntitiesTeachingbirds: DemoConfig["entities"] = () =>
|
|||||||
attributes: {
|
attributes: {
|
||||||
min_mireds: 153,
|
min_mireds: 153,
|
||||||
max_mireds: 500,
|
max_mireds: 500,
|
||||||
|
supported_color_modes: ["brightness", "color_temp"],
|
||||||
is_deconz_group: false,
|
is_deconz_group: false,
|
||||||
friendly_name: "Floorlamp Reading Light",
|
friendly_name: "Floorlamp Reading Light",
|
||||||
supported_features: 43,
|
supported_features: 43,
|
||||||
@@ -1335,6 +1345,8 @@ export const demoEntitiesTeachingbirds: DemoConfig["entities"] = () =>
|
|||||||
max_mireds: 500,
|
max_mireds: 500,
|
||||||
brightness: 128,
|
brightness: 128,
|
||||||
color_temp: 366,
|
color_temp: 366,
|
||||||
|
supported_color_modes: ["brightness", "color_temp", "rgb"],
|
||||||
|
color_mode: "color_temp",
|
||||||
effect_list: ["colorloop"],
|
effect_list: ["colorloop"],
|
||||||
is_deconz_group: false,
|
is_deconz_group: false,
|
||||||
friendly_name: "Hallway window light",
|
friendly_name: "Hallway window light",
|
||||||
@@ -1349,6 +1361,7 @@ export const demoEntitiesTeachingbirds: DemoConfig["entities"] = () =>
|
|||||||
attributes: {
|
attributes: {
|
||||||
brightness: 77,
|
brightness: 77,
|
||||||
is_deconz_group: false,
|
is_deconz_group: false,
|
||||||
|
supported_color_modes: ["brightness"],
|
||||||
friendly_name: "Isa Ceiling Light",
|
friendly_name: "Isa Ceiling Light",
|
||||||
supported_features: 41,
|
supported_features: 41,
|
||||||
custom_ui_state_card: "state-card-custom-ui",
|
custom_ui_state_card: "state-card-custom-ui",
|
||||||
@@ -1363,6 +1376,8 @@ export const demoEntitiesTeachingbirds: DemoConfig["entities"] = () =>
|
|||||||
max_mireds: 500,
|
max_mireds: 500,
|
||||||
brightness: 150,
|
brightness: 150,
|
||||||
color_temp: 366,
|
color_temp: 366,
|
||||||
|
supported_color_modes: ["brightness", "color_temp"],
|
||||||
|
color_mode: "color_temp",
|
||||||
effect_list: ["colorloop"],
|
effect_list: ["colorloop"],
|
||||||
is_deconz_group: false,
|
is_deconz_group: false,
|
||||||
friendly_name: "Floorlamp",
|
friendly_name: "Floorlamp",
|
||||||
@@ -1377,6 +1392,7 @@ export const demoEntitiesTeachingbirds: DemoConfig["entities"] = () =>
|
|||||||
attributes: {
|
attributes: {
|
||||||
friendly_name: "Bedroom Ceiling Light",
|
friendly_name: "Bedroom Ceiling Light",
|
||||||
supported_features: 41,
|
supported_features: 41,
|
||||||
|
supported_color_modes: ["brightness"],
|
||||||
custom_ui_state_card: "state-card-custom-ui",
|
custom_ui_state_card: "state-card-custom-ui",
|
||||||
icon: "mdi:ceiling-light",
|
icon: "mdi:ceiling-light",
|
||||||
},
|
},
|
||||||
@@ -1387,6 +1403,7 @@ export const demoEntitiesTeachingbirds: DemoConfig["entities"] = () =>
|
|||||||
attributes: {
|
attributes: {
|
||||||
friendly_name: "Nightlight",
|
friendly_name: "Nightlight",
|
||||||
supported_features: 17,
|
supported_features: 17,
|
||||||
|
supported_color_modes: ["brightness"],
|
||||||
custom_ui_state_card: "state-card-custom-ui",
|
custom_ui_state_card: "state-card-custom-ui",
|
||||||
icon: "mdi:lamp",
|
icon: "mdi:lamp",
|
||||||
},
|
},
|
||||||
@@ -1753,6 +1770,7 @@ export const demoEntitiesTeachingbirds: DemoConfig["entities"] = () =>
|
|||||||
power_consumption: 2.2,
|
power_consumption: 2.2,
|
||||||
friendly_name: "Upstairs Hallway Light",
|
friendly_name: "Upstairs Hallway Light",
|
||||||
supported_features: 33,
|
supported_features: 33,
|
||||||
|
supported_color_modes: ["brightness"],
|
||||||
custom_ui_state_card: "state-card-custom-ui",
|
custom_ui_state_card: "state-card-custom-ui",
|
||||||
icon: "mdi:ceiling-light",
|
icon: "mdi:ceiling-light",
|
||||||
},
|
},
|
||||||
@@ -1768,6 +1786,7 @@ export const demoEntitiesTeachingbirds: DemoConfig["entities"] = () =>
|
|||||||
power_consumption: 0,
|
power_consumption: 0,
|
||||||
friendly_name: "Dining Room Light",
|
friendly_name: "Dining Room Light",
|
||||||
supported_features: 33,
|
supported_features: 33,
|
||||||
|
supported_color_modes: ["brightness"],
|
||||||
custom_ui_state_card: "state-card-custom-ui",
|
custom_ui_state_card: "state-card-custom-ui",
|
||||||
icon: "mdi:ceiling-light",
|
icon: "mdi:ceiling-light",
|
||||||
},
|
},
|
||||||
@@ -1783,6 +1802,7 @@ export const demoEntitiesTeachingbirds: DemoConfig["entities"] = () =>
|
|||||||
power_consumption: 0,
|
power_consumption: 0,
|
||||||
friendly_name: "Living room Spotlights",
|
friendly_name: "Living room Spotlights",
|
||||||
supported_features: 33,
|
supported_features: 33,
|
||||||
|
supported_color_modes: ["brightness"],
|
||||||
custom_ui_state_card: "state-card-custom-ui",
|
custom_ui_state_card: "state-card-custom-ui",
|
||||||
icon: "mdi:track-light",
|
icon: "mdi:track-light",
|
||||||
},
|
},
|
||||||
@@ -1799,6 +1819,7 @@ export const demoEntitiesTeachingbirds: DemoConfig["entities"] = () =>
|
|||||||
power_consumption: 2.5,
|
power_consumption: 2.5,
|
||||||
friendly_name: "Passage Lights",
|
friendly_name: "Passage Lights",
|
||||||
supported_features: 33,
|
supported_features: 33,
|
||||||
|
supported_color_modes: ["brightness"],
|
||||||
custom_ui_state_card: "state-card-custom-ui",
|
custom_ui_state_card: "state-card-custom-ui",
|
||||||
icon: "mdi:track-light",
|
icon: "mdi:track-light",
|
||||||
},
|
},
|
||||||
@@ -1843,6 +1864,7 @@ export const demoEntitiesTeachingbirds: DemoConfig["entities"] = () =>
|
|||||||
power_consumption: 37.4,
|
power_consumption: 37.4,
|
||||||
friendly_name: "Kitchen Lights",
|
friendly_name: "Kitchen Lights",
|
||||||
supported_features: 33,
|
supported_features: 33,
|
||||||
|
supported_color_modes: ["brightness"],
|
||||||
custom_ui_state_card: "state-card-custom-ui",
|
custom_ui_state_card: "state-card-custom-ui",
|
||||||
icon: "mdi:track-light",
|
icon: "mdi:track-light",
|
||||||
},
|
},
|
||||||
|
@@ -215,6 +215,7 @@ 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"],
|
||||||
},
|
},
|
||||||
@@ -439,57 +440,43 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
type: "horizontal-stack",
|
type: "horizontal-stack",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
type: "grid",
|
||||||
|
columns: 2,
|
||||||
cards: [
|
cards: [
|
||||||
{
|
{
|
||||||
cards: [
|
graph: "line",
|
||||||
{
|
type: "sensor",
|
||||||
graph: "line",
|
entity: "sensor.temperature_bedroom",
|
||||||
type: "sensor",
|
|
||||||
entity: "sensor.temperature_bedroom",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
graph: "line",
|
|
||||||
type: "sensor",
|
|
||||||
name: "S's room",
|
|
||||||
entity: "sensor.temperature_stefan",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
type: "horizontal-stack",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cards: [
|
graph: "line",
|
||||||
{
|
type: "sensor",
|
||||||
graph: "line",
|
name: "S's room",
|
||||||
type: "sensor",
|
entity: "sensor.temperature_stefan",
|
||||||
entity: "sensor.temperature_passage",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
graph: "line",
|
|
||||||
type: "sensor",
|
|
||||||
name: "Bathroom",
|
|
||||||
entity: "sensor.temperature_downstairs_bathroom",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
type: "horizontal-stack",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cards: [
|
graph: "line",
|
||||||
{
|
type: "sensor",
|
||||||
graph: "line",
|
entity: "sensor.temperature_passage",
|
||||||
type: "sensor",
|
},
|
||||||
entity: "sensor.temperature_storage",
|
{
|
||||||
},
|
graph: "line",
|
||||||
{
|
type: "sensor",
|
||||||
graph: "line",
|
name: "Bathroom",
|
||||||
type: "sensor",
|
entity: "sensor.temperature_downstairs_bathroom",
|
||||||
name: "Refrigerator",
|
},
|
||||||
entity: "sensor.refrigerator",
|
{
|
||||||
},
|
graph: "line",
|
||||||
],
|
type: "sensor",
|
||||||
type: "horizontal-stack",
|
entity: "sensor.temperature_storage",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
graph: "line",
|
||||||
|
type: "sensor",
|
||||||
|
name: "Refrigerator",
|
||||||
|
entity: "sensor.refrigerator",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
type: "vertical-stack",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
entities: [
|
entities: [
|
||||||
@@ -808,67 +795,6 @@ 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",
|
||||||
@@ -918,10 +844,6 @@ 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",
|
||||||
@@ -940,7 +862,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
"sensor.system_ring_chime",
|
"sensor.system_ring_chime",
|
||||||
],
|
],
|
||||||
type: "glance",
|
type: "glance",
|
||||||
columns: 5,
|
columns: 4,
|
||||||
show_state: false,
|
show_state: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { LitElement } from "lit-element";
|
import { LitElement } from "lit";
|
||||||
import "./card-tools";
|
import "./card-tools";
|
||||||
|
|
||||||
class CardModder extends LitElement {
|
class CardModder extends LitElement {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { html, LitElement } from "lit-element";
|
import { html, LitElement } from "lit";
|
||||||
|
|
||||||
if (!window.cardTools) {
|
if (!window.cardTools) {
|
||||||
const version = 0.2;
|
const version = 0.2;
|
||||||
|
@@ -1,12 +1,5 @@
|
|||||||
import {
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
css,
|
import { customElement, state } from "lit/decorators";
|
||||||
CSSResult,
|
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
internalProperty,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { CastManager } from "../../../src/cast/cast_manager";
|
import { CastManager } from "../../../src/cast/cast_manager";
|
||||||
import { castSendShowDemo } from "../../../src/cast/receiver_messages";
|
import { castSendShowDemo } from "../../../src/cast/receiver_messages";
|
||||||
import "../../../src/components/ha-icon";
|
import "../../../src/components/ha-icon";
|
||||||
@@ -20,7 +13,7 @@ import { HomeAssistant } from "../../../src/types";
|
|||||||
class CastDemoRow extends LitElement implements LovelaceRow {
|
class CastDemoRow extends LitElement implements LovelaceRow {
|
||||||
public hass!: HomeAssistant;
|
public hass!: HomeAssistant;
|
||||||
|
|
||||||
@internalProperty() private _castManager?: CastManager | null;
|
@state() private _castManager?: CastManager | null;
|
||||||
|
|
||||||
public setConfig(_config: CastConfig): void {
|
public setConfig(_config: CastConfig): void {
|
||||||
// No config possible.
|
// No config possible.
|
||||||
@@ -73,7 +66,7 @@ class CastDemoRow extends LitElement implements LovelaceRow {
|
|||||||
this.style.display = this._castManager ? "" : "none";
|
this.style.display = this._castManager ? "" : "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResultGroup {
|
||||||
return css`
|
return css`
|
||||||
:host {
|
:host {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@@ -1,14 +1,7 @@
|
|||||||
import "@material/mwc-button";
|
import "@material/mwc-button";
|
||||||
import {
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
css,
|
import { property, state } from "lit/decorators";
|
||||||
CSSResult,
|
import { until } from "lit/directives/until";
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
property,
|
|
||||||
internalProperty,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { until } from "lit-html/directives/until";
|
|
||||||
import "../../../src/components/ha-card";
|
import "../../../src/components/ha-card";
|
||||||
import "../../../src/components/ha-circular-progress";
|
import "../../../src/components/ha-circular-progress";
|
||||||
import { LovelaceCardConfig } from "../../../src/data/lovelace";
|
import { LovelaceCardConfig } from "../../../src/data/lovelace";
|
||||||
@@ -26,7 +19,7 @@ export class HADemoCard extends LitElement implements LovelaceCard {
|
|||||||
|
|
||||||
@property({ attribute: false }) public hass!: MockHomeAssistant;
|
@property({ attribute: false }) public hass!: MockHomeAssistant;
|
||||||
|
|
||||||
@internalProperty() private _switching?: boolean;
|
@state() private _switching?: boolean;
|
||||||
|
|
||||||
private _hidden = localStorage.hide_demo_card;
|
private _hidden = localStorage.hide_demo_card;
|
||||||
|
|
||||||
@@ -113,7 +106,7 @@ export class HADemoCard extends LitElement implements LovelaceCard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
css`
|
css`
|
||||||
a {
|
a {
|
||||||
|
@@ -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,3 +1,4 @@
|
|||||||
|
// 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";
|
||||||
@@ -21,9 +22,9 @@ import { mockTemplate } from "./stubs/template";
|
|||||||
import { mockTranslations } from "./stubs/translations";
|
import { mockTranslations } from "./stubs/translations";
|
||||||
|
|
||||||
class HaDemo extends HomeAssistantAppEl {
|
class HaDemo extends HomeAssistantAppEl {
|
||||||
protected async _initialize() {
|
protected async _initializeHass() {
|
||||||
const initial: Partial<MockHomeAssistant> = {
|
const initial: Partial<MockHomeAssistant> = {
|
||||||
panelUrl: (this as any).panelUrl,
|
panelUrl: (this as any)._panelUrl,
|
||||||
// Override updateHass so that the correct hass lifecycle methods are called
|
// Override updateHass so that the correct hass lifecycle methods are called
|
||||||
updateHass: (hassUpdate: Partial<HomeAssistant>) =>
|
updateHass: (hassUpdate: Partial<HomeAssistant>) =>
|
||||||
this._updateHass(hassUpdate),
|
this._updateHass(hassUpdate),
|
||||||
|
@@ -3,8 +3,6 @@ import { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
|
|||||||
export const mockTranslations = (hass: MockHomeAssistant) => {
|
export const mockTranslations = (hass: MockHomeAssistant) => {
|
||||||
hass.mockWS(
|
hass.mockWS(
|
||||||
"frontend/get_translations",
|
"frontend/get_translations",
|
||||||
(/* msg: {language: string, category: string} */) => {
|
(/* msg: {language: string, category: string} */) => ({ resources: {} })
|
||||||
return { resources: {} };
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -15,6 +15,10 @@ class DemoCard extends PolymerElement {
|
|||||||
margin: 0 0 20px;
|
margin: 0 0 20px;
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
h2 small {
|
||||||
|
font-size: 0.5em;
|
||||||
|
color: var(--primary-text-color);
|
||||||
|
}
|
||||||
#card {
|
#card {
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
@@ -34,7 +38,12 @@ class DemoCard extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h2>[[config.heading]]</h2>
|
<h2>
|
||||||
|
[[config.heading]]
|
||||||
|
<template is="dom-if" if="[[_size]]">
|
||||||
|
<small>(size [[_size]])</small>
|
||||||
|
</template>
|
||||||
|
</h2>
|
||||||
<div class="root">
|
<div class="root">
|
||||||
<div id="card"></div>
|
<div id="card"></div>
|
||||||
<template is="dom-if" if="[[showConfig]]">
|
<template is="dom-if" if="[[showConfig]]">
|
||||||
@@ -55,6 +64,9 @@ class DemoCard extends PolymerElement {
|
|||||||
observer: "_configChanged",
|
observer: "_configChanged",
|
||||||
},
|
},
|
||||||
showConfig: Boolean,
|
showConfig: Boolean,
|
||||||
|
_size: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,6 +82,17 @@ class DemoCard extends PolymerElement {
|
|||||||
|
|
||||||
const el = this._createCardElement(safeLoad(config.config)[0]);
|
const el = this._createCardElement(safeLoad(config.config)[0]);
|
||||||
card.appendChild(el);
|
card.appendChild(el);
|
||||||
|
this._getSize(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
async _getSize(el) {
|
||||||
|
await customElements.whenDefined(el.localName);
|
||||||
|
|
||||||
|
if (!("getCardSize" in el)) {
|
||||||
|
this._size = undefined;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._size = await el.getCardSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
_createCardElement(cardConfig) {
|
_createCardElement(cardConfig) {
|
||||||
|
@@ -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 "../../../src/components/ha-switch";
|
|
||||||
import "../../../src/components/ha-formfield";
|
|
||||||
import "./demo-card";
|
|
||||||
import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element";
|
import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element";
|
||||||
|
import "../../../src/components/ha-formfield";
|
||||||
|
import "../../../src/components/ha-switch";
|
||||||
|
import "./demo-card";
|
||||||
|
|
||||||
class DemoCards extends PolymerElement {
|
class DemoCards extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
|
@@ -2,37 +2,36 @@ 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/state-summary/state-card-content";
|
|
||||||
import "../../../src/dialogs/more-info/more-info-content";
|
import "../../../src/dialogs/more-info/more-info-content";
|
||||||
|
import "../../../src/state-summary/state-card-content";
|
||||||
|
|
||||||
class DemoMoreInfo extends PolymerElement {
|
class DemoMoreInfo extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
return html`
|
return html`
|
||||||
<style>
|
<style>
|
||||||
:host {
|
.root {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: start;
|
|
||||||
}
|
}
|
||||||
|
#card {
|
||||||
|
max-width: 400px;
|
||||||
|
width: 100vw;
|
||||||
|
}
|
||||||
ha-card {
|
ha-card {
|
||||||
width: 333px;
|
width: 352px;
|
||||||
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) {
|
||||||
:host {
|
.root {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
pre {
|
pre {
|
||||||
@@ -40,21 +39,25 @@ class DemoMoreInfo extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<ha-card>
|
<div class="root">
|
||||||
<state-card-content
|
<div id="card">
|
||||||
state-obj="[[_stateObj]]"
|
<ha-card>
|
||||||
hass="[[hass]]"
|
<state-card-content
|
||||||
in-dialog
|
state-obj="[[_stateObj]]"
|
||||||
></state-card-content>
|
hass="[[hass]]"
|
||||||
|
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>
|
||||||
<template is="dom-if" if="[[showConfig]]">
|
</div>
|
||||||
<pre>[[_jsonEntity(_stateObj)]]</pre>
|
<template is="dom-if" if="[[showConfig]]">
|
||||||
</template>
|
<pre>[[_jsonEntity(_stateObj)]]</pre>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,6 +2,8 @@ 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";
|
||||||
|
|
||||||
@@ -9,6 +11,10 @@ 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;
|
||||||
@@ -23,20 +29,31 @@ 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-switch checked="{{_showConfig}}">Show entity</ha-switch>
|
<ha-formfield label="Show entities">
|
||||||
|
<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 class="cards">
|
<div id="container">
|
||||||
<template is="dom-repeat" items="[[entities]]">
|
<div class="cards">
|
||||||
<demo-more-info
|
<template is="dom-repeat" items="[[entities]]">
|
||||||
entity-id="[[item]]"
|
<demo-more-info
|
||||||
show-config="[[_showConfig]]"
|
entity-id="[[item]]"
|
||||||
hass="[[hass]]"
|
show-config="[[_showConfig]]"
|
||||||
></demo-more-info>
|
hass="[[hass]]"
|
||||||
</template>
|
></demo-more-info>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@@ -51,6 +68,16 @@ 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);
|
||||||
|
72
gallery/src/data/plants.ts
Normal file
72
gallery/src/data/plants.ts
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
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",
|
||||||
|
}),
|
||||||
|
];
|
349
gallery/src/data/traces/basic_trace.ts
Normal file
349
gallery/src/data/traces/basic_trace.ts
Normal file
@@ -0,0 +1,349 @@
|
|||||||
|
import { DemoTrace } from "./types";
|
||||||
|
|
||||||
|
export const basicTrace: DemoTrace = {
|
||||||
|
trace: {
|
||||||
|
last_step: "action/2",
|
||||||
|
run_id: "0",
|
||||||
|
state: "stopped",
|
||||||
|
timestamp: {
|
||||||
|
start: "2021-03-25T04:36:51.223693+00:00",
|
||||||
|
finish: "2021-03-25T04:36:51.266132+00:00",
|
||||||
|
},
|
||||||
|
trigger: "state of input_boolean.toggle_1",
|
||||||
|
domain: "automation",
|
||||||
|
item_id: "1615419646544",
|
||||||
|
trace: {
|
||||||
|
"trigger/0": [
|
||||||
|
{
|
||||||
|
path: "trigger/0",
|
||||||
|
timestamp: "2021-03-25T04:36:51.223693+00:00",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"condition/0": [
|
||||||
|
{
|
||||||
|
path: "condition/0",
|
||||||
|
timestamp: "2021-03-25T04:36:51.228243+00:00",
|
||||||
|
changed_variables: {
|
||||||
|
trigger: {
|
||||||
|
platform: "state",
|
||||||
|
entity_id: "input_boolean.toggle_1",
|
||||||
|
from_state: {
|
||||||
|
entity_id: "input_boolean.toggle_1",
|
||||||
|
state: "on",
|
||||||
|
attributes: {
|
||||||
|
editable: true,
|
||||||
|
friendly_name: "Toggle 1",
|
||||||
|
},
|
||||||
|
last_changed: "2021-03-24T19:03:59.141440+00:00",
|
||||||
|
last_updated: "2021-03-24T19:03:59.141440+00:00",
|
||||||
|
context: {
|
||||||
|
id: "5d0918eb379214d07554bdab6a08bcff",
|
||||||
|
parent_id: null,
|
||||||
|
user_id: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
to_state: {
|
||||||
|
entity_id: "input_boolean.toggle_1",
|
||||||
|
state: "off",
|
||||||
|
attributes: {
|
||||||
|
editable: true,
|
||||||
|
friendly_name: "Toggle 1",
|
||||||
|
},
|
||||||
|
last_changed: "2021-03-25T04:36:51.220696+00:00",
|
||||||
|
last_updated: "2021-03-25T04:36:51.220696+00:00",
|
||||||
|
context: {
|
||||||
|
id: "664d6d261450a9ecea6738e97269a149",
|
||||||
|
parent_id: null,
|
||||||
|
user_id: "d1b4e89da01445fa8bc98e39fac477ca",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
for: null,
|
||||||
|
attribute: null,
|
||||||
|
description: "state of input_boolean.toggle_1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: {
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"action/0": [
|
||||||
|
{
|
||||||
|
path: "action/0",
|
||||||
|
timestamp: "2021-03-25T04:36:51.243018+00:00",
|
||||||
|
changed_variables: {
|
||||||
|
trigger: {
|
||||||
|
platform: "state",
|
||||||
|
entity_id: "input_boolean.toggle_1",
|
||||||
|
from_state: {
|
||||||
|
entity_id: "input_boolean.toggle_1",
|
||||||
|
state: "on",
|
||||||
|
attributes: {
|
||||||
|
editable: true,
|
||||||
|
friendly_name: "Toggle 1",
|
||||||
|
},
|
||||||
|
last_changed: "2021-03-24T19:03:59.141440+00:00",
|
||||||
|
last_updated: "2021-03-24T19:03:59.141440+00:00",
|
||||||
|
context: {
|
||||||
|
id: "5d0918eb379214d07554bdab6a08bcff",
|
||||||
|
parent_id: null,
|
||||||
|
user_id: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
to_state: {
|
||||||
|
entity_id: "input_boolean.toggle_1",
|
||||||
|
state: "off",
|
||||||
|
attributes: {
|
||||||
|
editable: true,
|
||||||
|
friendly_name: "Toggle 1",
|
||||||
|
},
|
||||||
|
last_changed: "2021-03-25T04:36:51.220696+00:00",
|
||||||
|
last_updated: "2021-03-25T04:36:51.220696+00:00",
|
||||||
|
context: {
|
||||||
|
id: "664d6d261450a9ecea6738e97269a149",
|
||||||
|
parent_id: null,
|
||||||
|
user_id: "d1b4e89da01445fa8bc98e39fac477ca",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
for: null,
|
||||||
|
attribute: null,
|
||||||
|
description: "state of input_boolean.toggle_1",
|
||||||
|
},
|
||||||
|
context: {
|
||||||
|
id: "6cfcae368e7b3686fad6c59e83ae76c9",
|
||||||
|
parent_id: "664d6d261450a9ecea6738e97269a149",
|
||||||
|
user_id: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: {
|
||||||
|
params: {
|
||||||
|
domain: "input_boolean",
|
||||||
|
service: "toggle",
|
||||||
|
service_data: {},
|
||||||
|
target: {
|
||||||
|
entity_id: ["input_boolean.toggle_4"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
running_script: false,
|
||||||
|
limit: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"action/1": [
|
||||||
|
{
|
||||||
|
path: "action/1",
|
||||||
|
timestamp: "2021-03-25T04:36:51.252406+00:00",
|
||||||
|
result: {
|
||||||
|
choice: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"action/1/choose/0": [
|
||||||
|
{
|
||||||
|
path: "action/1/choose/0",
|
||||||
|
timestamp: "2021-03-25T04:36:51.254569+00:00",
|
||||||
|
result: {
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"action/1/choose/0/conditions/0": [
|
||||||
|
{
|
||||||
|
path: "action/1/choose/0/conditions/0",
|
||||||
|
timestamp: "2021-03-25T04:36:51.254697+00:00",
|
||||||
|
result: {
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"action/1/choose/0/sequence/0": [
|
||||||
|
{
|
||||||
|
path: "action/1/choose/0/sequence/0",
|
||||||
|
timestamp: "2021-03-25T04:36:51.257360+00:00",
|
||||||
|
result: {
|
||||||
|
params: {
|
||||||
|
domain: "input_boolean",
|
||||||
|
service: "toggle",
|
||||||
|
service_data: {},
|
||||||
|
target: {
|
||||||
|
entity_id: ["input_boolean.toggle_2"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
running_script: false,
|
||||||
|
limit: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"action/1/choose/0/sequence/1": [
|
||||||
|
{
|
||||||
|
path: "action/1/choose/0/sequence/1",
|
||||||
|
timestamp: "2021-03-25T04:36:51.260658+00:00",
|
||||||
|
result: {
|
||||||
|
params: {
|
||||||
|
domain: "input_boolean",
|
||||||
|
service: "toggle",
|
||||||
|
service_data: {},
|
||||||
|
target: {
|
||||||
|
entity_id: ["input_boolean.toggle_3"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
running_script: false,
|
||||||
|
limit: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"action/2": [
|
||||||
|
{
|
||||||
|
path: "action/2",
|
||||||
|
timestamp: "2021-03-25T04:36:51.264159+00:00",
|
||||||
|
result: {
|
||||||
|
params: {
|
||||||
|
domain: "input_boolean",
|
||||||
|
service: "toggle",
|
||||||
|
service_data: {},
|
||||||
|
target: {
|
||||||
|
entity_id: ["input_boolean.toggle_4"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
running_script: false,
|
||||||
|
limit: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
config: {
|
||||||
|
id: "1615419646544",
|
||||||
|
alias: "Ensure Party mode",
|
||||||
|
description: "",
|
||||||
|
trigger: [
|
||||||
|
{
|
||||||
|
platform: "state",
|
||||||
|
entity_id: "input_boolean.toggle_1",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
condition: [
|
||||||
|
{
|
||||||
|
condition: "template",
|
||||||
|
alias: "Test if Paulus is home",
|
||||||
|
value_template: "{{ true }}",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
action: [
|
||||||
|
{
|
||||||
|
service: "input_boolean.toggle",
|
||||||
|
target: {
|
||||||
|
entity_id: "input_boolean.toggle_4",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
choose: [
|
||||||
|
{
|
||||||
|
alias: "If toggle 3 is on",
|
||||||
|
conditions: [
|
||||||
|
{
|
||||||
|
condition: "template",
|
||||||
|
value_template:
|
||||||
|
"{{ is_state('input_boolean.toggle_3', 'on') }}",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
sequence: [
|
||||||
|
{
|
||||||
|
service: "input_boolean.toggle",
|
||||||
|
alias: "Toggle 2 while 3 is on",
|
||||||
|
target: {
|
||||||
|
entity_id: "input_boolean.toggle_2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
service: "input_boolean.toggle",
|
||||||
|
alias: "Toggle 3",
|
||||||
|
target: {
|
||||||
|
entity_id: "input_boolean.toggle_3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: [
|
||||||
|
{
|
||||||
|
service: "input_boolean.toggle",
|
||||||
|
alias: "Toggle 2",
|
||||||
|
target: {
|
||||||
|
entity_id: "input_boolean.toggle_2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
service: "input_boolean.toggle",
|
||||||
|
target: {
|
||||||
|
entity_id: "input_boolean.toggle_4",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
mode: "single",
|
||||||
|
},
|
||||||
|
context: {
|
||||||
|
id: "6cfcae368e7b3686fad6c59e83ae76c9",
|
||||||
|
parent_id: "664d6d261450a9ecea6738e97269a149",
|
||||||
|
user_id: null,
|
||||||
|
},
|
||||||
|
script_execution: "finished",
|
||||||
|
},
|
||||||
|
logbookEntries: [
|
||||||
|
{
|
||||||
|
name: "Ensure Party mode",
|
||||||
|
message: "has been triggered by state of input_boolean.toggle_1",
|
||||||
|
source: "state of input_boolean.toggle_1",
|
||||||
|
entity_id: "automation.toggle_toggles",
|
||||||
|
context_id: "6cfcae368e7b3686fad6c59e83ae76c9",
|
||||||
|
when: "2021-03-25T04:36:51.240832+00:00",
|
||||||
|
domain: "automation",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
when: "2021-03-25T04:36:51.249828+00:00",
|
||||||
|
name: "Toggle 4",
|
||||||
|
state: "on",
|
||||||
|
entity_id: "input_boolean.toggle_4",
|
||||||
|
context_entity_id: "automation.toggle_toggles",
|
||||||
|
context_entity_id_name: "Ensure Party mode",
|
||||||
|
context_event_type: "automation_triggered",
|
||||||
|
context_domain: "automation",
|
||||||
|
context_name: "Ensure Party mode",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
when: "2021-03-25T04:36:51.258947+00:00",
|
||||||
|
name: "Toggle 2",
|
||||||
|
state: "on",
|
||||||
|
entity_id: "input_boolean.toggle_2",
|
||||||
|
context_entity_id: "automation.toggle_toggles",
|
||||||
|
context_entity_id_name: "Ensure Party mode",
|
||||||
|
context_event_type: "automation_triggered",
|
||||||
|
context_domain: "automation",
|
||||||
|
context_name: "Ensure Party mode",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
when: "2021-03-25T04:36:51.261806+00:00",
|
||||||
|
name: "Toggle 3",
|
||||||
|
state: "off",
|
||||||
|
entity_id: "input_boolean.toggle_3",
|
||||||
|
context_entity_id: "automation.toggle_toggles",
|
||||||
|
context_entity_id_name: "Ensure Party mode",
|
||||||
|
context_event_type: "automation_triggered",
|
||||||
|
context_domain: "automation",
|
||||||
|
context_name: "Ensure Party mode",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
when: "2021-03-25T04:36:51.265246+00:00",
|
||||||
|
name: "Toggle 4",
|
||||||
|
state: "off",
|
||||||
|
entity_id: "input_boolean.toggle_4",
|
||||||
|
context_entity_id: "automation.toggle_toggles",
|
||||||
|
context_entity_id_name: "Ensure Party mode",
|
||||||
|
context_event_type: "automation_triggered",
|
||||||
|
context_domain: "automation",
|
||||||
|
context_name: "Ensure Party mode",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
44
gallery/src/data/traces/mock-demo-trace.ts
Normal file
44
gallery/src/data/traces/mock-demo-trace.ts
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import { LogbookEntry } from "../../../../src/data/logbook";
|
||||||
|
import { AutomationTraceExtended } from "../../../../src/data/trace";
|
||||||
|
import { DemoTrace } from "./types";
|
||||||
|
|
||||||
|
export const mockDemoTrace = (
|
||||||
|
tracePartial: Partial<AutomationTraceExtended>,
|
||||||
|
logbookEntries?: LogbookEntry[]
|
||||||
|
): DemoTrace => ({
|
||||||
|
trace: {
|
||||||
|
last_step: "",
|
||||||
|
run_id: "0",
|
||||||
|
state: "stopped",
|
||||||
|
timestamp: {
|
||||||
|
start: "2021-03-25T04:36:51.223693+00:00",
|
||||||
|
finish: "2021-03-25T04:36:51.266132+00:00",
|
||||||
|
},
|
||||||
|
trigger: "mocked trigger",
|
||||||
|
domain: "automation",
|
||||||
|
item_id: "1615419646544",
|
||||||
|
trace: {
|
||||||
|
"trigger/0": [
|
||||||
|
{
|
||||||
|
path: "trigger/0",
|
||||||
|
changed_variables: {
|
||||||
|
trigger: {
|
||||||
|
description: "mocked trigger",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
timestamp: "2021-03-25T04:36:51.223693+00:00",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
config: {
|
||||||
|
trigger: [],
|
||||||
|
action: [],
|
||||||
|
},
|
||||||
|
context: {
|
||||||
|
id: "abcd",
|
||||||
|
},
|
||||||
|
script_execution: "finished",
|
||||||
|
...tracePartial,
|
||||||
|
},
|
||||||
|
logbookEntries: logbookEntries || [],
|
||||||
|
});
|
214
gallery/src/data/traces/motion-light-trace.ts
Normal file
214
gallery/src/data/traces/motion-light-trace.ts
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
import { DemoTrace } from "./types";
|
||||||
|
|
||||||
|
export const motionLightTrace: DemoTrace = {
|
||||||
|
trace: {
|
||||||
|
last_step: "action/3",
|
||||||
|
run_id: "1",
|
||||||
|
state: "stopped",
|
||||||
|
timestamp: {
|
||||||
|
start: "2021-03-14T06:07:01.768006+00:00",
|
||||||
|
finish: "2021-03-14T06:07:53.287525+00:00",
|
||||||
|
},
|
||||||
|
trigger: "state of binary_sensor.pauluss_macbook_pro_camera_in_use",
|
||||||
|
domain: "automation",
|
||||||
|
item_id: "1614732497392",
|
||||||
|
trace: {
|
||||||
|
"trigger/0": [
|
||||||
|
{
|
||||||
|
path: "trigger/0",
|
||||||
|
timestamp: "2021-03-25T04:36:51.223693+00:00",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"action/0": [
|
||||||
|
{
|
||||||
|
path: "action/0",
|
||||||
|
timestamp: "2021-03-14T06:07:01.771038+00:00",
|
||||||
|
changed_variables: {
|
||||||
|
trigger: {
|
||||||
|
platform: "state",
|
||||||
|
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
|
||||||
|
from_state: {
|
||||||
|
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
|
||||||
|
state: "off",
|
||||||
|
attributes: {
|
||||||
|
friendly_name: "Paulus’s MacBook Pro Camera In Use",
|
||||||
|
icon: "mdi:camera-off",
|
||||||
|
},
|
||||||
|
last_changed: "2021-03-14T06:06:29.235325+00:00",
|
||||||
|
last_updated: "2021-03-14T06:06:29.235325+00:00",
|
||||||
|
context: {
|
||||||
|
id: "ad4864c5ce957c38a07b50378eeb245d",
|
||||||
|
parent_id: null,
|
||||||
|
user_id: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
to_state: {
|
||||||
|
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
|
||||||
|
state: "on",
|
||||||
|
attributes: {
|
||||||
|
friendly_name: "Paulus’s MacBook Pro Camera In Use",
|
||||||
|
icon: "mdi:camera",
|
||||||
|
},
|
||||||
|
last_changed: "2021-03-14T06:07:01.762009+00:00",
|
||||||
|
last_updated: "2021-03-14T06:07:01.762009+00:00",
|
||||||
|
context: {
|
||||||
|
id: "e22ddfd5f11dc4aad9a52fc10dab613b",
|
||||||
|
parent_id: null,
|
||||||
|
user_id: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
for: null,
|
||||||
|
attribute: null,
|
||||||
|
description:
|
||||||
|
"state of binary_sensor.pauluss_macbook_pro_camera_in_use",
|
||||||
|
},
|
||||||
|
context: {
|
||||||
|
id: "43b6ee9293a551c5cc14e8eb60af54ba",
|
||||||
|
parent_id: "e22ddfd5f11dc4aad9a52fc10dab613b",
|
||||||
|
user_id: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"action/1": [
|
||||||
|
{ path: "action/1", timestamp: "2021-03-14T06:07:01.875316+00:00" },
|
||||||
|
],
|
||||||
|
"action/2": [
|
||||||
|
{
|
||||||
|
path: "action/2",
|
||||||
|
timestamp: "2021-03-14T06:07:53.195013+00:00",
|
||||||
|
changed_variables: {
|
||||||
|
wait: {
|
||||||
|
remaining: null,
|
||||||
|
trigger: {
|
||||||
|
platform: "state",
|
||||||
|
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
|
||||||
|
from_state: {
|
||||||
|
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
|
||||||
|
state: "on",
|
||||||
|
attributes: {
|
||||||
|
friendly_name: "Paulus’s MacBook Pro Camera In Use",
|
||||||
|
icon: "mdi:camera",
|
||||||
|
},
|
||||||
|
last_changed: "2021-03-14T06:07:01.762009+00:00",
|
||||||
|
last_updated: "2021-03-14T06:07:01.762009+00:00",
|
||||||
|
context: {
|
||||||
|
id: "e22ddfd5f11dc4aad9a52fc10dab613b",
|
||||||
|
parent_id: null,
|
||||||
|
user_id: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
to_state: {
|
||||||
|
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
|
||||||
|
state: "off",
|
||||||
|
attributes: {
|
||||||
|
friendly_name: "Paulus’s MacBook Pro Camera In Use",
|
||||||
|
icon: "mdi:camera-off",
|
||||||
|
},
|
||||||
|
last_changed: "2021-03-14T06:07:53.186755+00:00",
|
||||||
|
last_updated: "2021-03-14T06:07:53.186755+00:00",
|
||||||
|
context: {
|
||||||
|
id: "b2308cc91d509ea8e0c623331ab178d6",
|
||||||
|
parent_id: null,
|
||||||
|
user_id: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
for: null,
|
||||||
|
attribute: null,
|
||||||
|
description:
|
||||||
|
"state of binary_sensor.pauluss_macbook_pro_camera_in_use",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"action/3": [
|
||||||
|
{
|
||||||
|
path: "action/3",
|
||||||
|
timestamp: "2021-03-14T06:07:53.196014+00:00",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
config: {
|
||||||
|
mode: "restart",
|
||||||
|
max_exceeded: "silent",
|
||||||
|
trigger: [
|
||||||
|
{
|
||||||
|
platform: "state",
|
||||||
|
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
|
||||||
|
from: "off",
|
||||||
|
to: "on",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
action: [
|
||||||
|
{
|
||||||
|
service: "light.turn_on",
|
||||||
|
target: {
|
||||||
|
entity_id: "light.elgato_key_light_air",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
wait_for_trigger: [
|
||||||
|
{
|
||||||
|
platform: "state",
|
||||||
|
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
|
||||||
|
from: "on",
|
||||||
|
to: "off",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
delay: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
service: "light.turn_off",
|
||||||
|
target: {
|
||||||
|
entity_id: "light.elgato_key_light_air",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
id: "1614732497392",
|
||||||
|
alias: "Auto Elgato",
|
||||||
|
description: "",
|
||||||
|
},
|
||||||
|
context: {
|
||||||
|
id: "43b6ee9293a551c5cc14e8eb60af54ba",
|
||||||
|
parent_id: "e22ddfd5f11dc4aad9a52fc10dab613b",
|
||||||
|
user_id: null,
|
||||||
|
},
|
||||||
|
script_execution: "finished",
|
||||||
|
},
|
||||||
|
logbookEntries: [
|
||||||
|
{
|
||||||
|
name: "Auto Elgato",
|
||||||
|
message:
|
||||||
|
"has been triggered by state of binary_sensor.pauluss_macbook_pro_camera_in_use",
|
||||||
|
source: "state of binary_sensor.pauluss_macbook_pro_camera_in_use",
|
||||||
|
entity_id: "automation.auto_elgato",
|
||||||
|
when: "2021-03-14T06:07:01.768492+00:00",
|
||||||
|
domain: "automation",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
when: "2021-03-14T06:07:01.872187+00:00",
|
||||||
|
name: "Elgato Key Light Air",
|
||||||
|
state: "on",
|
||||||
|
entity_id: "light.elgato_key_light_air",
|
||||||
|
context_entity_id: "automation.auto_elgato",
|
||||||
|
context_entity_id_name: "Auto Elgato",
|
||||||
|
context_event_type: "automation_triggered",
|
||||||
|
context_domain: "automation",
|
||||||
|
context_name: "Auto Elgato",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
when: "2021-03-14T06:07:53.284505+00:00",
|
||||||
|
name: "Elgato Key Light Air",
|
||||||
|
state: "off",
|
||||||
|
entity_id: "light.elgato_key_light_air",
|
||||||
|
context_entity_id: "automation.auto_elgato",
|
||||||
|
context_entity_id_name: "Auto Elgato",
|
||||||
|
context_event_type: "automation_triggered",
|
||||||
|
context_domain: "automation",
|
||||||
|
context_name: "Auto Elgato",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
7
gallery/src/data/traces/types.ts
Normal file
7
gallery/src/data/traces/types.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { AutomationTraceExtended } from "../../../../src/data/trace";
|
||||||
|
import { LogbookEntry } from "../../../../src/data/logbook";
|
||||||
|
|
||||||
|
export interface DemoTrace {
|
||||||
|
trace: AutomationTraceExtended;
|
||||||
|
logbookEntries: LogbookEntry[];
|
||||||
|
}
|
96
gallery/src/demos/demo-automation-describe-action.ts
Normal file
96
gallery/src/demos/demo-automation-describe-action.ts
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
import { safeDump } from "js-yaml";
|
||||||
|
import { html, css, LitElement, TemplateResult } from "lit";
|
||||||
|
import { customElement, property } from "lit/decorators";
|
||||||
|
import "../../../src/components/ha-card";
|
||||||
|
import { describeAction } from "../../../src/data/script_i18n";
|
||||||
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
|
import { HomeAssistant } from "../../../src/types";
|
||||||
|
|
||||||
|
const actions = [
|
||||||
|
{ wait_template: "{{ true }}", alias: "Something with an alias" },
|
||||||
|
{ delay: "0:05" },
|
||||||
|
{ wait_template: "{{ true }}" },
|
||||||
|
{
|
||||||
|
condition: "template",
|
||||||
|
value_template: "{{ true }}",
|
||||||
|
},
|
||||||
|
{ event: "happy_event" },
|
||||||
|
{
|
||||||
|
device_id: "abcdefgh",
|
||||||
|
domain: "plex",
|
||||||
|
entity_id: "media_player.kitchen",
|
||||||
|
},
|
||||||
|
{ scene: "scene.kitchen_morning" },
|
||||||
|
{
|
||||||
|
wait_for_trigger: [
|
||||||
|
{
|
||||||
|
platform: "state",
|
||||||
|
entity_id: "input_boolean.toggle_1",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
variables: {
|
||||||
|
hello: "world",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
service: "input_boolean.toggle",
|
||||||
|
target: {
|
||||||
|
entity_id: "input_boolean.toggle_4",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
@customElement("demo-automation-describe-action")
|
||||||
|
export class DemoAutomationDescribeAction extends LitElement {
|
||||||
|
@property({ attribute: false }) hass!: HomeAssistant;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
if (!this.hass) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
return html`
|
||||||
|
<ha-card header="Actions">
|
||||||
|
${actions.map(
|
||||||
|
(conf) => html`
|
||||||
|
<div class="action">
|
||||||
|
<span>${describeAction(this.hass, conf as any)}</span>
|
||||||
|
<pre>${safeDump(conf)}</pre>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
</ha-card>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected firstUpdated(changedProps) {
|
||||||
|
super.firstUpdated(changedProps);
|
||||||
|
const hass = provideHass(this);
|
||||||
|
hass.updateTranslations(null, "en");
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return css`
|
||||||
|
ha-card {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 24px auto;
|
||||||
|
}
|
||||||
|
.action {
|
||||||
|
padding: 16px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-automation-describe-action": DemoAutomationDescribeAction;
|
||||||
|
}
|
||||||
|
}
|
60
gallery/src/demos/demo-automation-describe-condition.ts
Normal file
60
gallery/src/demos/demo-automation-describe-condition.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { safeDump } from "js-yaml";
|
||||||
|
import { html, css, LitElement, TemplateResult } from "lit";
|
||||||
|
import { customElement } from "lit/decorators";
|
||||||
|
import "../../../src/components/ha-card";
|
||||||
|
import { describeCondition } from "../../../src/data/automation_i18n";
|
||||||
|
|
||||||
|
const conditions = [
|
||||||
|
{ condition: "and" },
|
||||||
|
{ condition: "not" },
|
||||||
|
{ condition: "or" },
|
||||||
|
{ condition: "state" },
|
||||||
|
{ condition: "numeric_state" },
|
||||||
|
{ condition: "sun", after: "sunset" },
|
||||||
|
{ condition: "sun", after: "sunrise" },
|
||||||
|
{ condition: "zone" },
|
||||||
|
{ condition: "time" },
|
||||||
|
{ condition: "template" },
|
||||||
|
];
|
||||||
|
|
||||||
|
@customElement("demo-automation-describe-condition")
|
||||||
|
export class DemoAutomationDescribeCondition extends LitElement {
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
<ha-card header="Conditions">
|
||||||
|
${conditions.map(
|
||||||
|
(conf) => html`
|
||||||
|
<div class="condition">
|
||||||
|
<span>${describeCondition(conf as any)}</span>
|
||||||
|
<pre>${safeDump(conf)}</pre>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
</ha-card>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return css`
|
||||||
|
ha-card {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 24px auto;
|
||||||
|
}
|
||||||
|
.condition {
|
||||||
|
padding: 16px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-automation-describe-condition": DemoAutomationDescribeCondition;
|
||||||
|
}
|
||||||
|
}
|
63
gallery/src/demos/demo-automation-describe-trigger.ts
Normal file
63
gallery/src/demos/demo-automation-describe-trigger.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import { safeDump } from "js-yaml";
|
||||||
|
import { html, css, LitElement, TemplateResult } from "lit";
|
||||||
|
import { customElement } from "lit/decorators";
|
||||||
|
import "../../../src/components/ha-card";
|
||||||
|
import { describeTrigger } from "../../../src/data/automation_i18n";
|
||||||
|
|
||||||
|
const triggers = [
|
||||||
|
{ platform: "state" },
|
||||||
|
{ platform: "mqtt" },
|
||||||
|
{ platform: "geo_location" },
|
||||||
|
{ platform: "homeassistant" },
|
||||||
|
{ platform: "numeric_state" },
|
||||||
|
{ platform: "sun" },
|
||||||
|
{ platform: "time_pattern" },
|
||||||
|
{ platform: "webhook" },
|
||||||
|
{ platform: "zone" },
|
||||||
|
{ platform: "tag" },
|
||||||
|
{ platform: "time" },
|
||||||
|
{ platform: "template" },
|
||||||
|
{ platform: "event" },
|
||||||
|
];
|
||||||
|
|
||||||
|
@customElement("demo-automation-describe-trigger")
|
||||||
|
export class DemoAutomationDescribeTrigger extends LitElement {
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
<ha-card header="Triggers">
|
||||||
|
${triggers.map(
|
||||||
|
(conf) => html`
|
||||||
|
<div class="trigger">
|
||||||
|
<span>${describeTrigger(conf as any)}</span>
|
||||||
|
<pre>${safeDump(conf)}</pre>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
</ha-card>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return css`
|
||||||
|
ha-card {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 24px auto;
|
||||||
|
}
|
||||||
|
.trigger {
|
||||||
|
padding: 16px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-automation-describe-trigger": DemoAutomationDescribeTrigger;
|
||||||
|
}
|
||||||
|
}
|
81
gallery/src/demos/demo-automation-trace-timeline.ts
Normal file
81
gallery/src/demos/demo-automation-trace-timeline.ts
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import { html, css, LitElement, TemplateResult } from "lit";
|
||||||
|
import { customElement, property } from "lit/decorators";
|
||||||
|
import "../../../src/components/ha-card";
|
||||||
|
import "../../../src/components/trace/hat-script-graph";
|
||||||
|
import "../../../src/components/trace/hat-trace-timeline";
|
||||||
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
|
import { HomeAssistant } from "../../../src/types";
|
||||||
|
import { mockDemoTrace } from "../data/traces/mock-demo-trace";
|
||||||
|
import { DemoTrace } from "../data/traces/types";
|
||||||
|
|
||||||
|
const traces: DemoTrace[] = [
|
||||||
|
mockDemoTrace({ state: "running" }),
|
||||||
|
mockDemoTrace({ state: "debugged" }),
|
||||||
|
mockDemoTrace({ state: "stopped", script_execution: "failed_conditions" }),
|
||||||
|
mockDemoTrace({ state: "stopped", script_execution: "failed_single" }),
|
||||||
|
mockDemoTrace({ state: "stopped", script_execution: "failed_max_runs" }),
|
||||||
|
mockDemoTrace({ state: "stopped", script_execution: "finished" }),
|
||||||
|
mockDemoTrace({ state: "stopped", script_execution: "aborted" }),
|
||||||
|
mockDemoTrace({
|
||||||
|
state: "stopped",
|
||||||
|
script_execution: "error",
|
||||||
|
error: 'Variable "beer" cannot be None',
|
||||||
|
}),
|
||||||
|
mockDemoTrace({ state: "stopped", script_execution: "cancelled" }),
|
||||||
|
];
|
||||||
|
|
||||||
|
@customElement("demo-automation-trace-timeline")
|
||||||
|
export class DemoAutomationTraceTimeline extends LitElement {
|
||||||
|
@property({ attribute: false }) hass?: HomeAssistant;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
if (!this.hass) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
return html`
|
||||||
|
${traces.map(
|
||||||
|
(trace) => html`
|
||||||
|
<ha-card .header=${trace.trace.config.alias}>
|
||||||
|
<div class="card-content">
|
||||||
|
<hat-trace-timeline
|
||||||
|
.hass=${this.hass}
|
||||||
|
.trace=${trace.trace}
|
||||||
|
.logbookEntries=${trace.logbookEntries}
|
||||||
|
></hat-trace-timeline>
|
||||||
|
<button @click=${() => console.log(trace)}>Log trace</button>
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected firstUpdated(changedProps) {
|
||||||
|
super.firstUpdated(changedProps);
|
||||||
|
const hass = provideHass(this);
|
||||||
|
hass.updateTranslations(null, "en");
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return css`
|
||||||
|
ha-card {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 24px;
|
||||||
|
}
|
||||||
|
.card-content {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-automation-trace-timeline": DemoAutomationTraceTimeline;
|
||||||
|
}
|
||||||
|
}
|
91
gallery/src/demos/demo-automation-trace.ts
Normal file
91
gallery/src/demos/demo-automation-trace.ts
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
import { html, css, LitElement, TemplateResult } from "lit";
|
||||||
|
import "../../../src/components/ha-card";
|
||||||
|
import "../../../src/components/trace/hat-script-graph";
|
||||||
|
import "../../../src/components/trace/hat-trace-timeline";
|
||||||
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
|
import { HomeAssistant } from "../../../src/types";
|
||||||
|
import { DemoTrace } from "../data/traces/types";
|
||||||
|
import { basicTrace } from "../data/traces/basic_trace";
|
||||||
|
import { motionLightTrace } from "../data/traces/motion-light-trace";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
|
||||||
|
const traces: DemoTrace[] = [basicTrace, motionLightTrace];
|
||||||
|
|
||||||
|
@customElement("demo-automation-trace")
|
||||||
|
export class DemoAutomationTrace extends LitElement {
|
||||||
|
@property({ attribute: false }) hass?: HomeAssistant;
|
||||||
|
|
||||||
|
@state() private _selected = {};
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
if (!this.hass) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
return html`
|
||||||
|
${traces.map(
|
||||||
|
(trace, idx) => html`
|
||||||
|
<ha-card .header=${trace.trace.config.alias}>
|
||||||
|
<div class="card-content">
|
||||||
|
<hat-script-graph
|
||||||
|
.trace=${trace.trace}
|
||||||
|
.selected=${this._selected[idx]}
|
||||||
|
@graph-node-selected=${(ev) => {
|
||||||
|
this._selected = { ...this._selected, [idx]: ev.detail.path };
|
||||||
|
}}
|
||||||
|
></hat-script-graph>
|
||||||
|
<hat-trace-timeline
|
||||||
|
allowPick
|
||||||
|
.hass=${this.hass}
|
||||||
|
.trace=${trace.trace}
|
||||||
|
.logbookEntries=${trace.logbookEntries}
|
||||||
|
.selectedPath=${this._selected[idx]}
|
||||||
|
@value-changed=${(ev) => {
|
||||||
|
this._selected = {
|
||||||
|
...this._selected,
|
||||||
|
[idx]: ev.detail.value,
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
></hat-trace-timeline>
|
||||||
|
<button @click=${() => console.log(trace)}>Log trace</button>
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected firstUpdated(changedProps) {
|
||||||
|
super.firstUpdated(changedProps);
|
||||||
|
const hass = provideHass(this);
|
||||||
|
hass.updateTranslations(null, "en");
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return css`
|
||||||
|
ha-card {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 24px;
|
||||||
|
}
|
||||||
|
.card-content {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.card-content > * {
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
.card-content > *:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-automation-trace": DemoAutomationTrace;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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";
|
||||||
@@ -71,30 +70,25 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoAlarmPanelEntity extends PolymerElement {
|
@customElement("demo-hui-alarm-panel-card")
|
||||||
static get template() {
|
class DemoAlarmPanelEntity extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
type: Object,
|
hass.updateTranslations(null, "en");
|
||||||
value: CONFIGS,
|
hass.updateTranslations("lovelace", "en");
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-hui-alarm-panel-card", DemoAlarmPanelEntity);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-alarm-panel-card": DemoAlarmPanelEntity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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,26 +52,25 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoConditional extends PolymerElement {
|
@customElement("demo-hui-conditional-card")
|
||||||
static get template() {
|
class DemoConditional extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
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-conditional-card", DemoConditional);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-conditional-card": DemoConditional;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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";
|
||||||
@@ -217,26 +216,25 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoEntities extends PolymerElement {
|
@customElement("demo-hui-entities-card")
|
||||||
static get template() {
|
class DemoEntities extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
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-entities-card", DemoEntities);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-entities-card": DemoEntities;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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 +47,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
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
@@ -69,26 +68,25 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoButtonEntity extends PolymerElement {
|
@customElement("demo-hui-entity-button-card")
|
||||||
static get template() {
|
class DemoButtonEntity extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
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-button-card", DemoButtonEntity);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-entity-button-card": DemoButtonEntity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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";
|
||||||
@@ -43,7 +42,7 @@ const ENTITIES = [
|
|||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
{
|
{
|
||||||
heading: "Controller",
|
heading: "Unfiltered controller",
|
||||||
config: `
|
config: `
|
||||||
- type: entities
|
- type: entities
|
||||||
entities:
|
entities:
|
||||||
@@ -53,7 +52,7 @@ const CONFIGS = [
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "Basic",
|
heading: "Filtered entities card",
|
||||||
config: `
|
config: `
|
||||||
- type: entity-filter
|
- type: entity-filter
|
||||||
entities:
|
entities:
|
||||||
@@ -69,7 +68,27 @@ const CONFIGS = [
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "With card config",
|
heading: 'With "entities" 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:
|
||||||
@@ -84,31 +103,31 @@ const CONFIGS = [
|
|||||||
- not_home
|
- not_home
|
||||||
card:
|
card:
|
||||||
type: glance
|
type: glance
|
||||||
show_state: false
|
show_state: true
|
||||||
|
title: Custom Title
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoFilter extends PolymerElement {
|
@customElement("demo-hui-entity-filter-card")
|
||||||
static get template() {
|
class DemoEntityFilter extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
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", DemoFilter);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-entity-filter-card": DemoEntityFilter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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";
|
||||||
@@ -107,26 +106,25 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoGaugeEntity extends PolymerElement {
|
@customElement("demo-hui-gauge-card")
|
||||||
static get template() {
|
class DemoGaugeEntity extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
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-gauge-card", DemoGaugeEntity);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-gauge-card": DemoGaugeEntity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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";
|
||||||
@@ -77,7 +76,8 @@ const CONFIGS = [
|
|||||||
heading: "With title",
|
heading: "With title",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
title: This is glance
|
title: Custom title
|
||||||
|
columns: 4
|
||||||
entities:
|
entities:
|
||||||
- device_tracker.demo_paulus
|
- device_tracker.demo_paulus
|
||||||
- media_player.living_room
|
- media_player.living_room
|
||||||
@@ -104,9 +104,10 @@ const CONFIGS = [
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "No name",
|
heading: "No entity names",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
|
columns: 4
|
||||||
show_name: false
|
show_name: false
|
||||||
entities:
|
entities:
|
||||||
- device_tracker.demo_paulus
|
- device_tracker.demo_paulus
|
||||||
@@ -119,9 +120,10 @@ const CONFIGS = [
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "No state",
|
heading: "No state labels",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
|
columns: 4
|
||||||
show_state: false
|
show_state: false
|
||||||
entities:
|
entities:
|
||||||
- device_tracker.demo_paulus
|
- device_tracker.demo_paulus
|
||||||
@@ -134,9 +136,10 @@ const CONFIGS = [
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "No name and no state",
|
heading: "No names and no state labels",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
|
columns: 4
|
||||||
show_name: false
|
show_name: false
|
||||||
show_state: false
|
show_state: false
|
||||||
entities:
|
entities:
|
||||||
@@ -150,47 +153,24 @@ 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
|
||||||
- media_player.living_room
|
- entity: media_player.living_room
|
||||||
- sun.sun
|
name: ¯\\_(ツ)_/¯
|
||||||
- cover.kitchen_window
|
icon: mdi:home-assistant
|
||||||
- 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
|
||||||
@@ -199,45 +179,55 @@ 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: "Primary theme",
|
heading: "Custom tap action",
|
||||||
config: `
|
config: `
|
||||||
- type: glance
|
- type: glance
|
||||||
theming: primary
|
columns: 4
|
||||||
entities:
|
entities:
|
||||||
- device_tracker.demo_paulus
|
- entity: lock.kitchen_door
|
||||||
- media_player.living_room
|
name: Custom
|
||||||
- sun.sun
|
tap_action:
|
||||||
- cover.kitchen_window
|
type: toggle
|
||||||
- light.kitchen_lights
|
- entity: light.ceiling_lights
|
||||||
- lock.kitchen_door
|
name: Custom
|
||||||
- light.ceiling_lights
|
tap_action:
|
||||||
|
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
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoPicEntity extends PolymerElement {
|
@customElement("demo-hui-glance-card")
|
||||||
static get template() {
|
class DemoGlanceEntity extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
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", DemoPicEntity);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-glance-card": DemoGlanceEntity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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";
|
||||||
@@ -44,6 +43,110 @@ const ENTITIES = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
|
{
|
||||||
|
heading: "Default Grid",
|
||||||
|
config: `
|
||||||
|
- type: grid
|
||||||
|
cards:
|
||||||
|
- type: entity
|
||||||
|
entity: light.kitchen_lights
|
||||||
|
- type: entity
|
||||||
|
entity: light.bed_light
|
||||||
|
- type: entity
|
||||||
|
entity: device_tracker.demo_paulus
|
||||||
|
- type: sensor
|
||||||
|
entity: sensor.illumination
|
||||||
|
graph: line
|
||||||
|
- type: entity
|
||||||
|
entity: device_tracker.demo_anne_therese
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Non-square Grid with 2 columns",
|
||||||
|
config: `
|
||||||
|
- type: grid
|
||||||
|
columns: 2
|
||||||
|
square: false
|
||||||
|
cards:
|
||||||
|
- type: entity
|
||||||
|
entity: light.kitchen_lights
|
||||||
|
- type: entity
|
||||||
|
entity: light.bed_light
|
||||||
|
- type: entity
|
||||||
|
entity: device_tracker.demo_paulus
|
||||||
|
- type: sensor
|
||||||
|
entity: sensor.illumination
|
||||||
|
graph: line
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Default Grid with title",
|
||||||
|
config: `
|
||||||
|
- type: grid
|
||||||
|
title: Kitchen
|
||||||
|
cards:
|
||||||
|
- type: entity
|
||||||
|
entity: light.kitchen_lights
|
||||||
|
- type: entity
|
||||||
|
entity: light.bed_light
|
||||||
|
- type: entity
|
||||||
|
entity: device_tracker.demo_paulus
|
||||||
|
- type: sensor
|
||||||
|
entity: sensor.illumination
|
||||||
|
graph: line
|
||||||
|
- type: entity
|
||||||
|
entity: device_tracker.demo_anne_therese
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Columns 4",
|
||||||
|
config: `
|
||||||
|
- type: grid
|
||||||
|
columns: 4
|
||||||
|
cards:
|
||||||
|
- type: entity
|
||||||
|
entity: light.kitchen_lights
|
||||||
|
- type: entity
|
||||||
|
entity: light.bed_light
|
||||||
|
- type: entity
|
||||||
|
entity: device_tracker.demo_paulus
|
||||||
|
- type: sensor
|
||||||
|
entity: sensor.illumination
|
||||||
|
graph: line
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Columns 2",
|
||||||
|
config: `
|
||||||
|
- type: grid
|
||||||
|
columns: 2
|
||||||
|
cards:
|
||||||
|
- type: entity
|
||||||
|
entity: light.kitchen_lights
|
||||||
|
- type: entity
|
||||||
|
entity: light.bed_light
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Columns 1",
|
||||||
|
config: `
|
||||||
|
- type: grid
|
||||||
|
columns: 1
|
||||||
|
cards:
|
||||||
|
- type: entity
|
||||||
|
entity: light.kitchen_lights
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Size for single card",
|
||||||
|
config: `
|
||||||
|
- type: grid
|
||||||
|
cards:
|
||||||
|
- type: entity
|
||||||
|
entity: light.kitchen_lights
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
heading: "Vertical Stack",
|
heading: "Vertical Stack",
|
||||||
config: `
|
config: `
|
||||||
@@ -94,65 +197,28 @@ const CONFIGS = [
|
|||||||
entity: light.bed_light
|
entity: light.bed_light
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
heading: "Default Grid",
|
|
||||||
config: `
|
|
||||||
- type: grid
|
|
||||||
cards:
|
|
||||||
- type: entity
|
|
||||||
entity: light.kitchen_lights
|
|
||||||
- type: entity
|
|
||||||
entity: light.bed_light
|
|
||||||
- type: entity
|
|
||||||
entity: device_tracker.demo_paulus
|
|
||||||
- type: sensor
|
|
||||||
entity: sensor.illumination
|
|
||||||
graph: line
|
|
||||||
- type: entity
|
|
||||||
entity: device_tracker.demo_anne_therese
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
heading: "Non-square Grid with 2 columns",
|
|
||||||
config: `
|
|
||||||
- type: grid
|
|
||||||
columns: 2
|
|
||||||
square: false
|
|
||||||
cards:
|
|
||||||
- type: entity
|
|
||||||
entity: light.kitchen_lights
|
|
||||||
- type: entity
|
|
||||||
entity: light.bed_light
|
|
||||||
- type: entity
|
|
||||||
entity: device_tracker.demo_paulus
|
|
||||||
- type: sensor
|
|
||||||
entity: sensor.illumination
|
|
||||||
graph: line
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoStack extends PolymerElement {
|
@customElement("demo-hui-grid-and-stack-card")
|
||||||
static get template() {
|
class DemoStack extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-hui-stack-card", DemoStack);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-grid-and-stack-card": DemoStack;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
@@ -37,19 +36,15 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoIframe extends PolymerElement {
|
@customElement("demo-hui-iframe-card")
|
||||||
static get template() {
|
class DemoIframe extends LitElement {
|
||||||
return html` <demo-cards configs="[[_configs]]"></demo-cards> `;
|
protected render(): TemplateResult {
|
||||||
}
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
|
|
||||||
static get properties() {
|
|
||||||
return {
|
|
||||||
_configs: {
|
|
||||||
type: Object,
|
|
||||||
value: CONFIGS,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-hui-iframe-card", DemoIframe);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-iframe-card": DemoIframe;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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";
|
||||||
@@ -63,26 +62,25 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoLightEntity extends PolymerElement {
|
@customElement("demo-hui-light-card")
|
||||||
static get template() {
|
class DemoLightEntity extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
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-light-card", DemoLightEntity);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-light-card": DemoLightEntity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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";
|
||||||
@@ -161,26 +160,25 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoMap extends PolymerElement {
|
@customElement("demo-hui-map-card")
|
||||||
static get template() {
|
class DemoMap extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
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-map-card", DemoMap);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-map-card": DemoMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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";
|
||||||
@@ -254,25 +253,25 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoMarkdown extends PolymerElement {
|
@customElement("demo-hui-markdown-card")
|
||||||
static get template() {
|
class DemoMarkdown extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
type: Object,
|
hass.updateTranslations(null, "en");
|
||||||
value: CONFIGS,
|
hass.updateTranslations("lovelace", "en");
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public ready() {
|
|
||||||
super.ready();
|
|
||||||
const hass = provideHass(this.$.demos);
|
|
||||||
mockTemplate(hass);
|
mockTemplate(hass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-hui-markdown-card", DemoMarkdown);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-markdown-card": DemoMarkdown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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";
|
||||||
@@ -158,26 +157,25 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoHuiMediControlCard extends PolymerElement {
|
@customElement("demo-hui-media-control-card")
|
||||||
static get template() {
|
class DemoHuiMediaControlCard extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
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", DemoHuiMediControlCard);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-media-control-card": DemoHuiMediaControlCard;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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";
|
||||||
@@ -26,9 +25,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
|
||||||
@@ -38,7 +37,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
|
||||||
@@ -55,26 +54,25 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoHuiMediaPlayerRows extends PolymerElement {
|
@customElement("demo-hui-media-player-row")
|
||||||
static get template() {
|
class DemoHuiMediaPlayerRow extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
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-rows", DemoHuiMediaPlayerRows);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-media-player-row": DemoHuiMediaPlayerRow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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";
|
||||||
@@ -125,26 +124,25 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoPicElements extends PolymerElement {
|
@customElement("demo-hui-picture-elements-card")
|
||||||
static get template() {
|
class DemoPictureElements extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
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", DemoPicElements);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-picture-elements-card": DemoPictureElements;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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";
|
||||||
@@ -80,26 +79,25 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoPicEntity extends PolymerElement {
|
@customElement("demo-hui-picture-entity-card")
|
||||||
static get template() {
|
class DemoPictureEntity extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
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", DemoPicEntity);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-picture-entity-card": DemoPictureEntity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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";
|
||||||
@@ -121,26 +120,25 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoPicGlance extends PolymerElement {
|
@customElement("demo-hui-picture-glance-card")
|
||||||
static get template() {
|
class DemoPictureGlance extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
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", DemoPicGlance);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-picture-glance-card": DemoPictureGlance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
53
gallery/src/demos/demo-hui-plant-card.ts
Normal file
53
gallery/src/demos/demo-hui-plant-card.ts
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
|
import { customElement, query } from "lit/decorators";
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-plant-card": DemoPlantEntity;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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";
|
||||||
|
|
||||||
@@ -20,24 +19,19 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoShoppingListEntity extends PolymerElement {
|
@customElement("demo-hui-shopping-list-card")
|
||||||
static get template() {
|
class DemoShoppingListEntity extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
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 },
|
||||||
@@ -48,4 +42,8 @@ class DemoShoppingListEntity extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-hui-shopping-list-card", DemoShoppingListEntity);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-shopping-list-card": DemoShoppingListEntity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-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";
|
||||||
@@ -74,26 +73,25 @@ const CONFIGS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoThermostatEntity extends PolymerElement {
|
@customElement("demo-hui-thermostat-card")
|
||||||
static get template() {
|
class DemoThermostatEntity extends LitElement {
|
||||||
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
@query("#demos") private _demoRoot!: HTMLElement;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_configs: {
|
const hass = provideHass(this._demoRoot);
|
||||||
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-thermostat-card", DemoThermostatEntity);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-hui-thermostat-card": DemoThermostatEntity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
349
gallery/src/demos/demo-integration-card.ts
Normal file
349
gallery/src/demos/demo-integration-card.ts
Normal file
@@ -0,0 +1,349 @@
|
|||||||
|
import { html, css, LitElement, TemplateResult } from "lit";
|
||||||
|
import "../../../src/components/ha-formfield";
|
||||||
|
import "../../../src/components/ha-switch";
|
||||||
|
|
||||||
|
import { IntegrationManifest } from "../../../src/data/integration";
|
||||||
|
|
||||||
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
|
import { HomeAssistant } from "../../../src/types";
|
||||||
|
import "../../../src/panels/config/integrations/ha-integration-card";
|
||||||
|
import "../../../src/panels/config/integrations/ha-ignored-config-entry-card";
|
||||||
|
import "../../../src/panels/config/integrations/ha-config-flow-card";
|
||||||
|
import type {
|
||||||
|
ConfigEntryExtended,
|
||||||
|
DataEntryFlowProgressExtended,
|
||||||
|
} from "../../../src/panels/config/integrations/ha-config-integrations";
|
||||||
|
import { DeviceRegistryEntry } from "../../../src/data/device_registry";
|
||||||
|
import { EntityRegistryEntry } from "../../../src/data/entity_registry";
|
||||||
|
import { classMap } from "lit/directives/class-map";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
|
||||||
|
const createConfigEntry = (
|
||||||
|
title: string,
|
||||||
|
override: Partial<ConfigEntryExtended> = {}
|
||||||
|
): ConfigEntryExtended => ({
|
||||||
|
entry_id: title,
|
||||||
|
domain: "esphome",
|
||||||
|
localized_domain_name: "ESPHome",
|
||||||
|
title,
|
||||||
|
source: "zeroconf",
|
||||||
|
state: "loaded",
|
||||||
|
connection_class: "local_push",
|
||||||
|
supports_options: false,
|
||||||
|
supports_unload: true,
|
||||||
|
disabled_by: null,
|
||||||
|
reason: null,
|
||||||
|
...override,
|
||||||
|
});
|
||||||
|
|
||||||
|
const createManifest = (
|
||||||
|
isCustom: boolean,
|
||||||
|
isCloud: boolean,
|
||||||
|
name = "ESPHome"
|
||||||
|
): IntegrationManifest => ({
|
||||||
|
name,
|
||||||
|
domain: "esphome",
|
||||||
|
is_built_in: !isCustom,
|
||||||
|
config_flow: false,
|
||||||
|
documentation: "https://www.home-assistant.io/integrations/esphome/",
|
||||||
|
iot_class: isCloud ? "cloud_polling" : "local_polling",
|
||||||
|
});
|
||||||
|
|
||||||
|
const loadedEntry = createConfigEntry("Loaded");
|
||||||
|
const nameAsDomainEntry = createConfigEntry("ESPHome");
|
||||||
|
const longNameEntry = createConfigEntry(
|
||||||
|
"Entry with a super long name that is going to the next line"
|
||||||
|
);
|
||||||
|
const longNonBreakingNameEntry = createConfigEntry(
|
||||||
|
"EntryWithASuperLongNameThatDoesNotBreak"
|
||||||
|
);
|
||||||
|
const configPanelEntry = createConfigEntry("Config Panel", {
|
||||||
|
domain: "mqtt",
|
||||||
|
localized_domain_name: "MQTT",
|
||||||
|
});
|
||||||
|
const optionsFlowEntry = createConfigEntry("Options Flow", {
|
||||||
|
supports_options: true,
|
||||||
|
});
|
||||||
|
const setupErrorEntry = createConfigEntry("Setup Error", {
|
||||||
|
state: "setup_error",
|
||||||
|
});
|
||||||
|
const migrationErrorEntry = createConfigEntry("Migration Error", {
|
||||||
|
state: "migration_error",
|
||||||
|
});
|
||||||
|
const setupRetryEntry = createConfigEntry("Setup Retry", {
|
||||||
|
state: "setup_retry",
|
||||||
|
});
|
||||||
|
const setupRetryReasonEntry = createConfigEntry("Setup Retry", {
|
||||||
|
state: "setup_retry",
|
||||||
|
reason: "connection_error",
|
||||||
|
});
|
||||||
|
const setupRetryReasonMissingKeyEntry = createConfigEntry("Setup Retry", {
|
||||||
|
state: "setup_retry",
|
||||||
|
reason:
|
||||||
|
"HTTPSConnectionpool: Max retries exceeded with NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x9eedfc10>: Failed to establish a new connection: [Errno 113] Host is unreachable')",
|
||||||
|
});
|
||||||
|
const failedUnloadEntry = createConfigEntry("Failed Unload", {
|
||||||
|
state: "failed_unload",
|
||||||
|
});
|
||||||
|
const notLoadedEntry = createConfigEntry("Not Loaded", { state: "not_loaded" });
|
||||||
|
const disabledEntry = createConfigEntry("Disabled", {
|
||||||
|
state: "not_loaded",
|
||||||
|
disabled_by: "user",
|
||||||
|
});
|
||||||
|
const disabledFailedUnloadEntry = createConfigEntry(
|
||||||
|
"Disabled - Failed Unload",
|
||||||
|
{
|
||||||
|
state: "failed_unload",
|
||||||
|
disabled_by: "user",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const configFlows: DataEntryFlowProgressExtended[] = [
|
||||||
|
{
|
||||||
|
flow_id: "adbb401329d8439ebb78ef29837826a8",
|
||||||
|
handler: "roku",
|
||||||
|
context: {
|
||||||
|
source: "ssdp",
|
||||||
|
unique_id: "YF008D862864",
|
||||||
|
title_placeholders: {
|
||||||
|
name: "Living room Roku",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
step_id: "discovery_confirm",
|
||||||
|
localized_title: "Living room Roku",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
flow_id: "adbb401329d8439ebb78ef29837826a8",
|
||||||
|
handler: "hue",
|
||||||
|
context: {
|
||||||
|
source: "reauth",
|
||||||
|
unique_id: "YF008D862864",
|
||||||
|
title_placeholders: {
|
||||||
|
name: "Living room Roku",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
step_id: "discovery_confirm",
|
||||||
|
localized_title: "Philips Hue",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const configEntries: Array<{
|
||||||
|
items: ConfigEntryExtended[];
|
||||||
|
is_custom?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
highlight?: string;
|
||||||
|
}> = [
|
||||||
|
{ items: [loadedEntry] },
|
||||||
|
{ items: [configPanelEntry] },
|
||||||
|
{ items: [optionsFlowEntry] },
|
||||||
|
{ items: [nameAsDomainEntry] },
|
||||||
|
{ items: [longNameEntry] },
|
||||||
|
{ items: [longNonBreakingNameEntry] },
|
||||||
|
{ items: [setupErrorEntry] },
|
||||||
|
{ items: [migrationErrorEntry] },
|
||||||
|
{ items: [setupRetryEntry] },
|
||||||
|
{ items: [setupRetryReasonEntry] },
|
||||||
|
{ items: [setupRetryReasonMissingKeyEntry] },
|
||||||
|
{ items: [failedUnloadEntry] },
|
||||||
|
{ items: [notLoadedEntry] },
|
||||||
|
{
|
||||||
|
items: [
|
||||||
|
loadedEntry,
|
||||||
|
setupErrorEntry,
|
||||||
|
migrationErrorEntry,
|
||||||
|
longNameEntry,
|
||||||
|
longNonBreakingNameEntry,
|
||||||
|
setupRetryEntry,
|
||||||
|
failedUnloadEntry,
|
||||||
|
notLoadedEntry,
|
||||||
|
disabledEntry,
|
||||||
|
nameAsDomainEntry,
|
||||||
|
configPanelEntry,
|
||||||
|
optionsFlowEntry,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ disabled: true, items: [disabledEntry] },
|
||||||
|
{ disabled: true, items: [disabledFailedUnloadEntry] },
|
||||||
|
{
|
||||||
|
disabled: true,
|
||||||
|
items: [disabledEntry, disabledFailedUnloadEntry],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
items: [loadedEntry, configPanelEntry],
|
||||||
|
highlight: "Loaded",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const createEntityRegistryEntries = (
|
||||||
|
item: ConfigEntryExtended
|
||||||
|
): EntityRegistryEntry[] => [
|
||||||
|
{
|
||||||
|
config_entry_id: item.entry_id,
|
||||||
|
device_id: "mock-device-id",
|
||||||
|
area_id: null,
|
||||||
|
disabled_by: null,
|
||||||
|
entity_id: "binary_sensor.updater",
|
||||||
|
name: null,
|
||||||
|
icon: null,
|
||||||
|
platform: "updater",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const createDeviceRegistryEntries = (
|
||||||
|
item: ConfigEntryExtended
|
||||||
|
): DeviceRegistryEntry[] => [
|
||||||
|
{
|
||||||
|
entry_type: null,
|
||||||
|
config_entries: [item.entry_id],
|
||||||
|
connections: [],
|
||||||
|
manufacturer: "ESPHome",
|
||||||
|
model: "Mock Device",
|
||||||
|
name: "Tag Reader",
|
||||||
|
sw_version: null,
|
||||||
|
id: "mock-device-id",
|
||||||
|
identifiers: [],
|
||||||
|
via_device_id: null,
|
||||||
|
area_id: null,
|
||||||
|
name_by_user: null,
|
||||||
|
disabled_by: null,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
@customElement("demo-integration-card")
|
||||||
|
export class DemoIntegrationCard extends LitElement {
|
||||||
|
@property({ attribute: false }) hass?: HomeAssistant;
|
||||||
|
|
||||||
|
@state() isCustomIntegration = false;
|
||||||
|
|
||||||
|
@state() isCloud = false;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
if (!this.hass) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
return html`
|
||||||
|
<div class="container">
|
||||||
|
<div class="filters">
|
||||||
|
<ha-formfield label="Custom Integration">
|
||||||
|
<ha-switch @change=${this._toggleCustomIntegration}></ha-switch>
|
||||||
|
</ha-formfield>
|
||||||
|
<ha-formfield label="Relies on cloud">
|
||||||
|
<ha-switch @change=${this._toggleCloud}></ha-switch>
|
||||||
|
</ha-formfield>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ha-ignored-config-entry-card
|
||||||
|
.hass=${this.hass}
|
||||||
|
.entry=${createConfigEntry("Ignored Entry")}
|
||||||
|
.manifest=${createManifest(this.isCustomIntegration, this.isCloud)}
|
||||||
|
></ha-ignored-config-entry-card>
|
||||||
|
|
||||||
|
${configFlows.map(
|
||||||
|
(flow) => html`
|
||||||
|
<ha-config-flow-card
|
||||||
|
.hass=${this.hass}
|
||||||
|
.flow=${flow}
|
||||||
|
.manifest=${createManifest(
|
||||||
|
this.isCustomIntegration,
|
||||||
|
this.isCloud,
|
||||||
|
flow.handler === "roku" ? "Roku" : "Philips Hue"
|
||||||
|
)}
|
||||||
|
></ha-config-flow-card>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
${configEntries.map(
|
||||||
|
(info) => html`
|
||||||
|
<ha-integration-card
|
||||||
|
class=${classMap({
|
||||||
|
highlight: info.highlight !== undefined,
|
||||||
|
})}
|
||||||
|
.hass=${this.hass}
|
||||||
|
domain="esphome"
|
||||||
|
.items=${info.items}
|
||||||
|
.manifest=${createManifest(
|
||||||
|
this.isCustomIntegration,
|
||||||
|
this.isCloud
|
||||||
|
)}
|
||||||
|
.entityRegistryEntries=${createEntityRegistryEntries(
|
||||||
|
info.items[0]
|
||||||
|
)}
|
||||||
|
.deviceRegistryEntries=${createDeviceRegistryEntries(
|
||||||
|
info.items[0]
|
||||||
|
)}
|
||||||
|
?disabled=${info.disabled}
|
||||||
|
.selectedConfigEntryId=${info.highlight}
|
||||||
|
></ha-integration-card>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<!-- One that is standalone to see how it increases height if height
|
||||||
|
not defined by other cards. -->
|
||||||
|
<ha-integration-card
|
||||||
|
.hass=${this.hass}
|
||||||
|
domain="esphome"
|
||||||
|
.items=${[
|
||||||
|
loadedEntry,
|
||||||
|
setupErrorEntry,
|
||||||
|
migrationErrorEntry,
|
||||||
|
setupRetryEntry,
|
||||||
|
failedUnloadEntry,
|
||||||
|
]}
|
||||||
|
.manifest=${createManifest(this.isCustomIntegration, this.isCloud)}
|
||||||
|
.entityRegistryEntries=${createEntityRegistryEntries(loadedEntry)}
|
||||||
|
.deviceRegistryEntries=${createDeviceRegistryEntries(loadedEntry)}
|
||||||
|
></ha-integration-card>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected firstUpdated(changedProps) {
|
||||||
|
super.firstUpdated(changedProps);
|
||||||
|
const hass = provideHass(this);
|
||||||
|
hass.updateTranslations(null, "en");
|
||||||
|
hass.updateTranslations("config", "en");
|
||||||
|
// Normally this string is loaded from backend
|
||||||
|
hass.addTranslations(
|
||||||
|
{
|
||||||
|
"component.esphome.config.error.connection_error":
|
||||||
|
"Can't connect to ESP. Please make sure your YAML file contains an 'api:' line.",
|
||||||
|
},
|
||||||
|
"en"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _toggleCustomIntegration() {
|
||||||
|
this.isCustomIntegration = !this.isCustomIntegration;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _toggleCloud() {
|
||||||
|
this.isCloud = !this.isCloud;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return css`
|
||||||
|
.container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
|
grid-gap: 16px 16px;
|
||||||
|
padding: 8px 16px 16px;
|
||||||
|
margin-bottom: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container > * {
|
||||||
|
max-width: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ha-formfield {
|
||||||
|
margin: 8px 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-integration-card": DemoIntegrationCard;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,12 +1,19 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
/* eslint-plugin-disable lit */
|
import { customElement, property, query } from "lit/decorators";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
|
||||||
import "../../../src/components/ha-card";
|
import "../../../src/components/ha-card";
|
||||||
import { SUPPORT_BRIGHTNESS } from "../../../src/data/light";
|
import {
|
||||||
import { getEntity } from "../../../src/fake_data/entity";
|
LightColorModes,
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
SUPPORT_EFFECT,
|
||||||
import "../components/demo-more-infos";
|
SUPPORT_FLASH,
|
||||||
|
SUPPORT_TRANSITION,
|
||||||
|
} from "../../../src/data/light";
|
||||||
import "../../../src/dialogs/more-info/more-info-content";
|
import "../../../src/dialogs/more-info/more-info-content";
|
||||||
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
|
import {
|
||||||
|
MockHomeAssistant,
|
||||||
|
provideHass,
|
||||||
|
} from "../../../src/fake_data/provide_hass";
|
||||||
|
import "../components/demo-more-infos";
|
||||||
|
|
||||||
const ENTITIES = [
|
const ENTITIES = [
|
||||||
getEntity("light", "bed_light", "on", {
|
getEntity("light", "bed_light", "on", {
|
||||||
@@ -14,40 +21,135 @@ const ENTITIES = [
|
|||||||
}),
|
}),
|
||||||
getEntity("light", "kitchen_light", "on", {
|
getEntity("light", "kitchen_light", "on", {
|
||||||
friendly_name: "Brightness Light",
|
friendly_name: "Brightness Light",
|
||||||
brightness: 80,
|
brightness: 200,
|
||||||
supported_features: SUPPORT_BRIGHTNESS,
|
supported_color_modes: [LightColorModes.BRIGHTNESS],
|
||||||
|
color_mode: LightColorModes.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_color_modes: [
|
||||||
|
LightColorModes.BRIGHTNESS,
|
||||||
|
LightColorModes.COLOR_TEMP,
|
||||||
|
],
|
||||||
|
color_mode: LightColorModes.COLOR_TEMP,
|
||||||
|
}),
|
||||||
|
getEntity("light", "color_hs_light", "on", {
|
||||||
|
friendly_name: "Color HS Light",
|
||||||
|
brightness: 255,
|
||||||
|
hs_color: [30, 100],
|
||||||
|
rgb_color: [30, 100, 255],
|
||||||
|
min_mireds: 30,
|
||||||
|
max_mireds: 150,
|
||||||
|
supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION,
|
||||||
|
supported_color_modes: [
|
||||||
|
LightColorModes.BRIGHTNESS,
|
||||||
|
LightColorModes.COLOR_TEMP,
|
||||||
|
LightColorModes.HS,
|
||||||
|
],
|
||||||
|
color_mode: LightColorModes.HS,
|
||||||
|
effect_list: ["random", "colorloop"],
|
||||||
|
}),
|
||||||
|
getEntity("light", "color_rgb_ct_light", "on", {
|
||||||
|
friendly_name: "Color RGB + CT Light",
|
||||||
|
brightness: 255,
|
||||||
|
color_temp: 75,
|
||||||
|
min_mireds: 30,
|
||||||
|
max_mireds: 150,
|
||||||
|
supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION,
|
||||||
|
supported_color_modes: [
|
||||||
|
LightColorModes.BRIGHTNESS,
|
||||||
|
LightColorModes.COLOR_TEMP,
|
||||||
|
LightColorModes.RGB,
|
||||||
|
],
|
||||||
|
color_mode: LightColorModes.COLOR_TEMP,
|
||||||
|
effect_list: ["random", "colorloop"],
|
||||||
|
}),
|
||||||
|
getEntity("light", "color_RGB_light", "on", {
|
||||||
|
friendly_name: "Color Effets Light",
|
||||||
|
brightness: 255,
|
||||||
|
rgb_color: [30, 100, 255],
|
||||||
|
supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION,
|
||||||
|
supported_color_modes: [LightColorModes.BRIGHTNESS, LightColorModes.RGB],
|
||||||
|
color_mode: LightColorModes.RGB,
|
||||||
|
effect_list: ["random", "colorloop"],
|
||||||
|
}),
|
||||||
|
getEntity("light", "color_rgbw_light", "on", {
|
||||||
|
friendly_name: "Color RGBW Light",
|
||||||
|
brightness: 255,
|
||||||
|
rgbw_color: [30, 100, 255, 125],
|
||||||
|
min_mireds: 30,
|
||||||
|
max_mireds: 150,
|
||||||
|
supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION,
|
||||||
|
supported_color_modes: [
|
||||||
|
LightColorModes.BRIGHTNESS,
|
||||||
|
LightColorModes.COLOR_TEMP,
|
||||||
|
LightColorModes.RGBW,
|
||||||
|
],
|
||||||
|
color_mode: LightColorModes.RGBW,
|
||||||
|
effect_list: ["random", "colorloop"],
|
||||||
|
}),
|
||||||
|
getEntity("light", "color_rgbww_light", "on", {
|
||||||
|
friendly_name: "Color RGBWW Light",
|
||||||
|
brightness: 255,
|
||||||
|
rgbww_color: [30, 100, 255, 125, 10],
|
||||||
|
min_mireds: 30,
|
||||||
|
max_mireds: 150,
|
||||||
|
supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION,
|
||||||
|
supported_color_modes: [
|
||||||
|
LightColorModes.BRIGHTNESS,
|
||||||
|
LightColorModes.COLOR_TEMP,
|
||||||
|
LightColorModes.RGBWW,
|
||||||
|
],
|
||||||
|
color_mode: LightColorModes.RGBWW,
|
||||||
|
effect_list: ["random", "colorloop"],
|
||||||
|
}),
|
||||||
|
getEntity("light", "color_xy_light", "on", {
|
||||||
|
friendly_name: "Color XY Light",
|
||||||
|
brightness: 255,
|
||||||
|
xy_color: [30, 100],
|
||||||
|
rgb_color: [30, 100, 255],
|
||||||
|
min_mireds: 30,
|
||||||
|
max_mireds: 150,
|
||||||
|
supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION,
|
||||||
|
supported_color_modes: [
|
||||||
|
LightColorModes.BRIGHTNESS,
|
||||||
|
LightColorModes.COLOR_TEMP,
|
||||||
|
LightColorModes.XY,
|
||||||
|
],
|
||||||
|
color_mode: LightColorModes.XY,
|
||||||
|
effect_list: ["random", "colorloop"],
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoMoreInfoLight extends PolymerElement {
|
@customElement("demo-more-info-light")
|
||||||
static get template() {
|
class DemoMoreInfoLight extends LitElement {
|
||||||
|
@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="[[hass]]"
|
.hass=${this.hass}
|
||||||
entities="[[_entities]]"
|
.entities=${ENTITIES.map((ent) => ent.entityId)}
|
||||||
></demo-more-infos>
|
></demo-more-infos>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
return {
|
super.firstUpdated(changedProperties);
|
||||||
_entities: {
|
const hass = provideHass(this._demoRoot);
|
||||||
type: Array,
|
hass.updateTranslations(null, "en");
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-more-info-light", DemoMoreInfoLight);
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-more-info-light": DemoMoreInfoLight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
import "@material/mwc-button";
|
import "@material/mwc-button";
|
||||||
import { html, LitElement, TemplateResult } from "lit-element";
|
import { html, LitElement, TemplateResult } from "lit";
|
||||||
|
import { customElement } from "lit/decorators";
|
||||||
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`
|
||||||
@@ -20,7 +22,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>
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
@@ -62,5 +64,3 @@ export class DemoUtilLongPress extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-util-long-press", DemoUtilLongPress);
|
|
||||||
|
@@ -14,8 +14,6 @@ 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`
|
||||||
@@ -113,29 +111,9 @@ class HaGallery extends PolymerElement {
|
|||||||
</template>
|
</template>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
|
|
||||||
<ha-card header="More Info Demos">
|
<ha-card header="Other Demos">
|
||||||
<div class="card-content intro">
|
<div class="card-content intro"></div>
|
||||||
<p>
|
<template is="dom-repeat" items="[[_restDemos]]">
|
||||||
More info screens show up when an entity is clicked.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<template is="dom-repeat" items="[[_moreInfoDemos]]">
|
|
||||||
<a href="#[[item]]">
|
|
||||||
<paper-item>
|
|
||||||
<paper-item-body>{{ item }}</paper-item-body>
|
|
||||||
<ha-icon icon="hass:chevron-right"></ha-icon>
|
|
||||||
</paper-item>
|
|
||||||
</a>
|
|
||||||
</template>
|
|
||||||
</ha-card>
|
|
||||||
|
|
||||||
<ha-card header="Util Demos">
|
|
||||||
<div class="card-content intro">
|
|
||||||
<p>
|
|
||||||
Test pages for our utility functions.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<template is="dom-repeat" items="[[_utilDemos]]">
|
|
||||||
<a href="#[[item]]">
|
<a href="#[[item]]">
|
||||||
<paper-item>
|
<paper-item>
|
||||||
<paper-item-body>{{ item }}</paper-item-body>
|
<paper-item-body>{{ item }}</paper-item-body>
|
||||||
@@ -180,13 +158,9 @@ class HaGallery extends PolymerElement {
|
|||||||
type: Array,
|
type: Array,
|
||||||
computed: "_computeLovelace(_demos)",
|
computed: "_computeLovelace(_demos)",
|
||||||
},
|
},
|
||||||
_moreInfoDemos: {
|
_restDemos: {
|
||||||
type: Array,
|
type: Array,
|
||||||
computed: "_computeMoreInfos(_demos)",
|
computed: "_computeRest(_demos)",
|
||||||
},
|
|
||||||
_utilDemos: {
|
|
||||||
type: Array,
|
|
||||||
computed: "_computeUtil(_demos)",
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -239,12 +213,8 @@ class HaGallery extends PolymerElement {
|
|||||||
return demos.filter((demo) => demo.includes("hui"));
|
return demos.filter((demo) => demo.includes("hui"));
|
||||||
}
|
}
|
||||||
|
|
||||||
_computeMoreInfos(demos) {
|
_computeRest(demos) {
|
||||||
return demos.filter((demo) => demo.includes("more-info"));
|
return demos.filter((demo) => !demo.includes("hui"));
|
||||||
}
|
|
||||||
|
|
||||||
_computeUtil(demos) {
|
|
||||||
return demos.filter((demo) => demo.includes("util"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,12 +1,6 @@
|
|||||||
import { mdiArrowUpBoldCircle, mdiPuzzle } from "@mdi/js";
|
import { mdiArrowUpBoldCircle, mdiPuzzle } from "@mdi/js";
|
||||||
import {
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
css,
|
import { property } from "lit/decorators";
|
||||||
CSSResultArray,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
property,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { atLeastVersion } from "../../../src/common/config/version";
|
import { atLeastVersion } from "../../../src/common/config/version";
|
||||||
import { navigate } from "../../../src/common/navigate";
|
import { navigate } from "../../../src/common/navigate";
|
||||||
@@ -15,6 +9,7 @@ import {
|
|||||||
HassioAddonInfo,
|
HassioAddonInfo,
|
||||||
HassioAddonRepository,
|
HassioAddonRepository,
|
||||||
} from "../../../src/data/hassio/addon";
|
} from "../../../src/data/hassio/addon";
|
||||||
|
import { Supervisor } from "../../../src/data/supervisor/supervisor";
|
||||||
import { HomeAssistant } from "../../../src/types";
|
import { HomeAssistant } from "../../../src/types";
|
||||||
import "../components/hassio-card-content";
|
import "../components/hassio-card-content";
|
||||||
import { filterAndSort } from "../components/hassio-filter-addons";
|
import { filterAndSort } from "../components/hassio-filter-addons";
|
||||||
@@ -23,6 +18,8 @@ import { hassioStyle } from "../resources/hassio-style";
|
|||||||
class HassioAddonRepositoryEl extends LitElement {
|
class HassioAddonRepositoryEl extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
@property({ attribute: false }) public repo!: HassioAddonRepository;
|
@property({ attribute: false }) public repo!: HassioAddonRepository;
|
||||||
|
|
||||||
@property({ attribute: false }) public addons!: HassioAddonInfo[];
|
@property({ attribute: false }) public addons!: HassioAddonInfo[];
|
||||||
@@ -44,9 +41,7 @@ class HassioAddonRepositoryEl extends LitElement {
|
|||||||
const repo = this.repo;
|
const repo = this.repo;
|
||||||
let _addons = this.addons;
|
let _addons = this.addons;
|
||||||
if (!this.hass.userData?.showAdvanced) {
|
if (!this.hass.userData?.showAdvanced) {
|
||||||
_addons = _addons.filter((addon) => {
|
_addons = _addons.filter((addon) => !addon.advanced);
|
||||||
return !addon.advanced;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
const addons = this._getAddons(_addons, this.filter);
|
const addons = this._getAddons(_addons, this.filter);
|
||||||
|
|
||||||
@@ -54,16 +49,18 @@ class HassioAddonRepositoryEl extends LitElement {
|
|||||||
return html`
|
return html`
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<p class="description">
|
<p class="description">
|
||||||
No results found in "${repo.name}."
|
${this.supervisor.localize(
|
||||||
|
"store.no_results_found",
|
||||||
|
"repository",
|
||||||
|
repo.name
|
||||||
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
return html`
|
return html`
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h1>
|
<h1>${repo.name}</h1>
|
||||||
${repo.name}
|
|
||||||
</h1>
|
|
||||||
<div class="card-group">
|
<div class="card-group">
|
||||||
${addons.map(
|
${addons.map(
|
||||||
(addon) => html`
|
(addon) => html`
|
||||||
@@ -83,11 +80,13 @@ class HassioAddonRepositoryEl extends LitElement {
|
|||||||
: mdiPuzzle}
|
: mdiPuzzle}
|
||||||
.iconTitle=${addon.installed
|
.iconTitle=${addon.installed
|
||||||
? addon.update_available
|
? addon.update_available
|
||||||
? "New version available"
|
? this.supervisor.localize(
|
||||||
: "Add-on is installed"
|
"common.new_version_available"
|
||||||
|
)
|
||||||
|
: this.supervisor.localize("addon.installed")
|
||||||
: addon.available
|
: addon.available
|
||||||
? "Add-on is not installed"
|
? this.supervisor.localize("addon.not_installed")
|
||||||
: "Add-on is not available on your system"}
|
: this.supervisor.localize("addon.not_available")}
|
||||||
.iconClass=${addon.installed
|
.iconClass=${addon.installed
|
||||||
? addon.update_available
|
? addon.update_available
|
||||||
? "update"
|
? "update"
|
||||||
@@ -124,7 +123,7 @@ class HassioAddonRepositoryEl extends LitElement {
|
|||||||
navigate(this, `/hassio/addon/${ev.currentTarget.addon.slug}`);
|
navigate(this, `/hassio/addon/${ev.currentTarget.addon.slug}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultArray {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
hassioStyle,
|
hassioStyle,
|
||||||
css`
|
css`
|
||||||
|
@@ -4,24 +4,27 @@ import "@material/mwc-list/mwc-list-item";
|
|||||||
import { mdiDotsVertical } from "@mdi/js";
|
import { mdiDotsVertical } from "@mdi/js";
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
CSSResult,
|
CSSResultGroup,
|
||||||
internalProperty,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
} from "lit-element";
|
TemplateResult,
|
||||||
import { html, TemplateResult } from "lit-html";
|
} from "lit";
|
||||||
|
import { property, state } from "lit/decorators";
|
||||||
|
import memoizeOne from "memoize-one";
|
||||||
import { atLeastVersion } from "../../../src/common/config/version";
|
import { atLeastVersion } from "../../../src/common/config/version";
|
||||||
|
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||||
|
import { navigate } from "../../../src/common/navigate";
|
||||||
import "../../../src/common/search/search-input";
|
import "../../../src/common/search/search-input";
|
||||||
|
import { extractSearchParam } from "../../../src/common/url/search-params";
|
||||||
import "../../../src/components/ha-button-menu";
|
import "../../../src/components/ha-button-menu";
|
||||||
import "../../../src/components/ha-svg-icon";
|
import "../../../src/components/ha-svg-icon";
|
||||||
import {
|
import {
|
||||||
fetchHassioAddonsInfo,
|
|
||||||
HassioAddonInfo,
|
HassioAddonInfo,
|
||||||
HassioAddonRepository,
|
HassioAddonRepository,
|
||||||
reloadHassioAddons,
|
reloadHassioAddons,
|
||||||
} from "../../../src/data/hassio/addon";
|
} from "../../../src/data/hassio/addon";
|
||||||
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
|
import { Supervisor } from "../../../src/data/supervisor/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";
|
||||||
@@ -49,58 +52,41 @@ const sortRepos = (a: HassioAddonRepository, b: HassioAddonRepository) => {
|
|||||||
class HassioAddonStore extends LitElement {
|
class HassioAddonStore extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
@property({ type: Boolean }) public narrow!: boolean;
|
@property({ type: Boolean }) public narrow!: boolean;
|
||||||
|
|
||||||
@property({ attribute: false }) public route!: Route;
|
@property({ attribute: false }) public route!: Route;
|
||||||
|
|
||||||
@property({ attribute: false }) private _addons?: HassioAddonInfo[];
|
@state() private _filter?: string;
|
||||||
|
|
||||||
@property({ attribute: false }) private _repos?: HassioAddonRepository[];
|
|
||||||
|
|
||||||
@internalProperty() private _filter?: string;
|
|
||||||
|
|
||||||
public async refreshData() {
|
public async refreshData() {
|
||||||
this._repos = undefined;
|
|
||||||
this._addons = undefined;
|
|
||||||
this._filter = undefined;
|
|
||||||
await reloadHassioAddons(this.hass);
|
await reloadHassioAddons(this.hass);
|
||||||
await this._loadData();
|
await this._loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
const repos: TemplateResult[] = [];
|
let repos: TemplateResult[] = [];
|
||||||
|
|
||||||
if (this._repos) {
|
if (this.supervisor.addon.repositories) {
|
||||||
for (const repo of this._repos) {
|
repos = this.addonRepositories(
|
||||||
const addons = this._addons!.filter(
|
this.supervisor.addon.repositories,
|
||||||
(addon) => addon.repository === repo.slug
|
this.supervisor.addon.addons,
|
||||||
);
|
this._filter
|
||||||
|
);
|
||||||
if (addons.length === 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
repos.push(html`
|
|
||||||
<hassio-addon-repository
|
|
||||||
.hass=${this.hass}
|
|
||||||
.repo=${repo}
|
|
||||||
.addons=${addons}
|
|
||||||
.filter=${this._filter!}
|
|
||||||
></hassio-addon-repository>
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<hass-tabs-subpage
|
<hass-tabs-subpage
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
|
.localizeFunc=${this.supervisor.localize}
|
||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
.route=${this.route}
|
.route=${this.route}
|
||||||
hassio
|
|
||||||
main-page
|
|
||||||
.tabs=${supervisorTabs}
|
.tabs=${supervisorTabs}
|
||||||
|
main-page
|
||||||
|
supervisor
|
||||||
>
|
>
|
||||||
<span slot="header">Add-on Store</span>
|
<span slot="header"> ${this.supervisor.localize("panel.store")} </span>
|
||||||
<ha-button-menu
|
<ha-button-menu
|
||||||
corner="BOTTOM_START"
|
corner="BOTTOM_START"
|
||||||
slot="toolbar-icon"
|
slot="toolbar-icon"
|
||||||
@@ -110,15 +96,15 @@ class HassioAddonStore extends LitElement {
|
|||||||
<ha-svg-icon .path=${mdiDotsVertical}></ha-svg-icon>
|
<ha-svg-icon .path=${mdiDotsVertical}></ha-svg-icon>
|
||||||
</mwc-icon-button>
|
</mwc-icon-button>
|
||||||
<mwc-list-item>
|
<mwc-list-item>
|
||||||
Repositories
|
${this.supervisor.localize("store.repositories")}
|
||||||
</mwc-list-item>
|
</mwc-list-item>
|
||||||
<mwc-list-item>
|
<mwc-list-item>
|
||||||
Reload
|
${this.supervisor.localize("common.reload")}
|
||||||
</mwc-list-item>
|
</mwc-list-item>
|
||||||
${this.hass.userData?.showAdvanced &&
|
${this.hass.userData?.showAdvanced &&
|
||||||
atLeastVersion(this.hass.config.version, 0, 117)
|
atLeastVersion(this.hass.config.version, 0, 117)
|
||||||
? html`<mwc-list-item>
|
? html`<mwc-list-item>
|
||||||
Registries
|
${this.supervisor.localize("store.registries")}
|
||||||
</mwc-list-item>`
|
</mwc-list-item>`
|
||||||
: ""}
|
: ""}
|
||||||
</ha-button-menu>
|
</ha-button-menu>
|
||||||
@@ -139,11 +125,9 @@ class HassioAddonStore extends LitElement {
|
|||||||
${!this.hass.userData?.showAdvanced
|
${!this.hass.userData?.showAdvanced
|
||||||
? html`
|
? html`
|
||||||
<div class="advanced">
|
<div class="advanced">
|
||||||
Missing add-ons? Enable advanced mode on
|
|
||||||
<a href="/profile" target="_top">
|
<a href="/profile" target="_top">
|
||||||
your profile page
|
${this.supervisor.localize("store.missing_addons")}
|
||||||
</a>
|
</a>
|
||||||
.
|
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
@@ -153,14 +137,45 @@ class HassioAddonStore extends LitElement {
|
|||||||
|
|
||||||
protected firstUpdated(changedProps: PropertyValues) {
|
protected firstUpdated(changedProps: PropertyValues) {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
|
const repositoryUrl = extractSearchParam("repository_url");
|
||||||
|
navigate(this, "/hassio/store", true);
|
||||||
|
if (repositoryUrl) {
|
||||||
|
this._manageRepositories(repositoryUrl);
|
||||||
|
}
|
||||||
|
|
||||||
this.addEventListener("hass-api-called", (ev) => this.apiCalled(ev));
|
this.addEventListener("hass-api-called", (ev) => this.apiCalled(ev));
|
||||||
this._loadData();
|
this._loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private addonRepositories = memoizeOne(
|
||||||
|
(
|
||||||
|
repositories: HassioAddonRepository[],
|
||||||
|
addons: HassioAddonInfo[],
|
||||||
|
filter?: string
|
||||||
|
) =>
|
||||||
|
repositories.sort(sortRepos).map((repo) => {
|
||||||
|
const filteredAddons = addons.filter(
|
||||||
|
(addon) => addon.repository === repo.slug
|
||||||
|
);
|
||||||
|
|
||||||
|
return filteredAddons.length !== 0
|
||||||
|
? html`
|
||||||
|
<hassio-addon-repository
|
||||||
|
.hass=${this.hass}
|
||||||
|
.repo=${repo}
|
||||||
|
.addons=${filteredAddons}
|
||||||
|
.filter=${filter!}
|
||||||
|
.supervisor=${this.supervisor}
|
||||||
|
></hassio-addon-repository>
|
||||||
|
`
|
||||||
|
: html``;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
private _handleAction(ev: CustomEvent<ActionDetail>) {
|
private _handleAction(ev: CustomEvent<ActionDetail>) {
|
||||||
switch (ev.detail.index) {
|
switch (ev.detail.index) {
|
||||||
case 0:
|
case 0:
|
||||||
this._manageRepositories();
|
this._manageRepositoriesClicked();
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
this.refreshData();
|
this.refreshData();
|
||||||
@@ -177,33 +192,33 @@ class HassioAddonStore extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _manageRepositories() {
|
private _manageRepositoriesClicked() {
|
||||||
|
this._manageRepositories();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _manageRepositories(url?: string) {
|
||||||
showRepositoriesDialog(this, {
|
showRepositoriesDialog(this, {
|
||||||
repos: this._repos!,
|
supervisor: this.supervisor,
|
||||||
loadData: () => this._loadData(),
|
url,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _manageRegistries() {
|
private async _manageRegistries() {
|
||||||
showRegistriesDialog(this);
|
showRegistriesDialog(this, { supervisor: this.supervisor });
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _loadData() {
|
private async _loadData() {
|
||||||
try {
|
fireEvent(this, "supervisor-collection-refresh", { collection: "addon" });
|
||||||
const addonsInfo = await fetchHassioAddonsInfo(this.hass);
|
fireEvent(this, "supervisor-collection-refresh", {
|
||||||
this._repos = addonsInfo.repositories;
|
collection: "supervisor",
|
||||||
this._repos.sort(sortRepos);
|
});
|
||||||
this._addons = addonsInfo.addons;
|
|
||||||
} catch (err) {
|
|
||||||
alert(extractApiErrorMessage(err));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _filterChanged(e) {
|
private async _filterChanged(e) {
|
||||||
this._filter = e.detail.value;
|
this._filter = e.detail.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResultGroup {
|
||||||
return css`
|
return css`
|
||||||
hassio-addon-repository {
|
hassio-addon-repository {
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
|
@@ -4,16 +4,15 @@ import "@polymer/paper-item/paper-item";
|
|||||||
import "@polymer/paper-listbox/paper-listbox";
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
CSSResult,
|
CSSResultGroup,
|
||||||
customElement,
|
|
||||||
html,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
|
||||||
internalProperty,
|
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
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,
|
||||||
@@ -24,36 +23,42 @@ import {
|
|||||||
fetchHassioHardwareAudio,
|
fetchHassioHardwareAudio,
|
||||||
HassioHardwareAudioDevice,
|
HassioHardwareAudioDevice,
|
||||||
} from "../../../../src/data/hassio/hardware";
|
} from "../../../../src/data/hassio/hardware";
|
||||||
|
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||||
import { haStyle } from "../../../../src/resources/styles";
|
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 {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
||||||
|
|
||||||
@internalProperty() private _error?: string;
|
@state() private _error?: string;
|
||||||
|
|
||||||
@internalProperty() private _inputDevices?: HassioHardwareAudioDevice[];
|
@state() private _inputDevices?: HassioHardwareAudioDevice[];
|
||||||
|
|
||||||
@internalProperty() private _outputDevices?: HassioHardwareAudioDevice[];
|
@state() private _outputDevices?: HassioHardwareAudioDevice[];
|
||||||
|
|
||||||
@internalProperty() private _selectedInput!: null | string;
|
@state() private _selectedInput!: null | string;
|
||||||
|
|
||||||
@internalProperty() private _selectedOutput!: null | string;
|
@state() private _selectedOutput!: null | string;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
return html`
|
return html`
|
||||||
<ha-card header="Audio">
|
<ha-card
|
||||||
|
.header=${this.supervisor.localize("addon.configuration.audio.header")}
|
||||||
|
>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
|
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
|
||||||
|
|
||||||
<paper-dropdown-menu
|
<paper-dropdown-menu
|
||||||
label="Input"
|
.label=${this.supervisor.localize(
|
||||||
|
"addon.configuration.audio.input"
|
||||||
|
)}
|
||||||
@iron-select=${this._setInputDevice}
|
@iron-select=${this._setInputDevice}
|
||||||
>
|
>
|
||||||
<paper-listbox
|
<paper-listbox
|
||||||
@@ -62,17 +67,19 @@ class HassioAddonAudio extends LitElement {
|
|||||||
.selected=${this._selectedInput!}
|
.selected=${this._selectedInput!}
|
||||||
>
|
>
|
||||||
${this._inputDevices &&
|
${this._inputDevices &&
|
||||||
this._inputDevices.map((item) => {
|
this._inputDevices.map(
|
||||||
return html`
|
(item) => html`
|
||||||
<paper-item device=${item.device || ""}
|
<paper-item device=${item.device || ""}>
|
||||||
>${item.name}</paper-item
|
${item.name}
|
||||||
>
|
</paper-item>
|
||||||
`;
|
`
|
||||||
})}
|
)}
|
||||||
</paper-listbox>
|
</paper-listbox>
|
||||||
</paper-dropdown-menu>
|
</paper-dropdown-menu>
|
||||||
<paper-dropdown-menu
|
<paper-dropdown-menu
|
||||||
label="Output"
|
.label=${this.supervisor.localize(
|
||||||
|
"addon.configuration.audio.output"
|
||||||
|
)}
|
||||||
@iron-select=${this._setOutputDevice}
|
@iron-select=${this._setOutputDevice}
|
||||||
>
|
>
|
||||||
<paper-listbox
|
<paper-listbox
|
||||||
@@ -81,26 +88,26 @@ class HassioAddonAudio extends LitElement {
|
|||||||
.selected=${this._selectedOutput!}
|
.selected=${this._selectedOutput!}
|
||||||
>
|
>
|
||||||
${this._outputDevices &&
|
${this._outputDevices &&
|
||||||
this._outputDevices.map((item) => {
|
this._outputDevices.map(
|
||||||
return html`
|
(item) => html`
|
||||||
<paper-item device=${item.device || ""}
|
<paper-item device=${item.device || ""}
|
||||||
>${item.name}</paper-item
|
>${item.name}</paper-item
|
||||||
>
|
>
|
||||||
`;
|
`
|
||||||
})}
|
)}
|
||||||
</paper-listbox>
|
</paper-listbox>
|
||||||
</paper-dropdown-menu>
|
</paper-dropdown-menu>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<ha-progress-button @click=${this._saveSettings}>
|
<ha-progress-button @click=${this._saveSettings}>
|
||||||
Save
|
${this.supervisor.localize("common.save")}
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
</div>
|
</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
hassioStyle,
|
hassioStyle,
|
||||||
@@ -152,7 +159,7 @@ class HassioAddonAudio extends LitElement {
|
|||||||
|
|
||||||
const noDevice: HassioHardwareAudioDevice = {
|
const noDevice: HassioHardwareAudioDevice = {
|
||||||
device: "default",
|
device: "default",
|
||||||
name: "Default",
|
name: this.supervisor.localize("addon.configuration.audio.default"),
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -189,7 +196,7 @@ class HassioAddonAudio extends LitElement {
|
|||||||
try {
|
try {
|
||||||
await setHassioAddonOption(this.hass, this.addon.slug, data);
|
await setHassioAddonOption(this.hass, this.addon.slug, data);
|
||||||
if (this.addon?.state === "started") {
|
if (this.addon?.state === "started") {
|
||||||
await suggestAddonRestart(this, this.hass, this.addon);
|
await suggestAddonRestart(this, this.hass, this.supervisor, this.addon);
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
this._error = "Failed to set addon audio device";
|
this._error = "Failed to set addon audio device";
|
||||||
|
@@ -1,17 +1,11 @@
|
|||||||
import {
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
css,
|
import { customElement, property } from "lit/decorators";
|
||||||
CSSResult,
|
import "../../../../src/components/ha-circular-progress";
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
property,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||||
|
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||||
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";
|
||||||
@@ -20,39 +14,56 @@ import "./hassio-addon-network";
|
|||||||
class HassioAddonConfigDashboard extends LitElement {
|
class HassioAddonConfigDashboard extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
@property({ attribute: false }) public addon?: HassioAddonDetails;
|
@property({ attribute: false }) public addon?: HassioAddonDetails;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
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 hasConfiguration =
|
||||||
|
(this.addon.options && Object.keys(this.addon.options).length) ||
|
||||||
|
(this.addon.schema && Object.keys(this.addon.schema).length);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<hassio-addon-config
|
${hasConfiguration || this.addon.network || this.addon.audio
|
||||||
.hass=${this.hass}
|
|
||||||
.addon=${this.addon}
|
|
||||||
></hassio-addon-config>
|
|
||||||
${this.addon.network
|
|
||||||
? html`
|
? html`
|
||||||
<hassio-addon-network
|
${hasConfiguration
|
||||||
.hass=${this.hass}
|
? html`
|
||||||
.addon=${this.addon}
|
<hassio-addon-config
|
||||||
></hassio-addon-network>
|
.hass=${this.hass}
|
||||||
|
.addon=${this.addon}
|
||||||
|
.supervisor=${this.supervisor}
|
||||||
|
></hassio-addon-config>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
${this.addon.network
|
||||||
|
? html`
|
||||||
|
<hassio-addon-network
|
||||||
|
.hass=${this.hass}
|
||||||
|
.addon=${this.addon}
|
||||||
|
.supervisor=${this.supervisor}
|
||||||
|
></hassio-addon-network>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
${this.addon.audio
|
||||||
|
? html`
|
||||||
|
<hassio-addon-audio
|
||||||
|
.hass=${this.hass}
|
||||||
|
.addon=${this.addon}
|
||||||
|
.supervisor=${this.supervisor}
|
||||||
|
></hassio-addon-audio>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
`
|
`
|
||||||
: ""}
|
: this.supervisor.localize("addon.configuration.no_configuration")}
|
||||||
${this.addon.audio
|
|
||||||
? html`
|
|
||||||
<hassio-addon-audio
|
|
||||||
.hass=${this.hass}
|
|
||||||
.addon=${this.addon}
|
|
||||||
></hassio-addon-audio>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
hassioStyle,
|
hassioStyle,
|
||||||
|
@@ -1,20 +1,26 @@
|
|||||||
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,
|
||||||
CSSResult,
|
CSSResultGroup,
|
||||||
customElement,
|
|
||||||
html,
|
html,
|
||||||
internalProperty,
|
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
query,
|
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit";
|
||||||
|
import { customElement, property, state, query } from "lit/decorators";
|
||||||
|
import memoizeOne from "memoize-one";
|
||||||
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 type { HaFormSchema } from "../../../../src/components/ha-form/ha-form";
|
||||||
|
import "../../../../src/components/ha-formfield";
|
||||||
|
import "../../../../src/components/ha-switch";
|
||||||
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 {
|
||||||
@@ -23,62 +29,193 @@ import {
|
|||||||
setHassioAddonOption,
|
setHassioAddonOption,
|
||||||
} 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 { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||||
import { showConfirmationDialog } from "../../../../src/dialogs/generic/show-dialog-box";
|
import { showConfirmationDialog } from "../../../../src/dialogs/generic/show-dialog-box";
|
||||||
import { haStyle } from "../../../../src/resources/styles";
|
import { haStyle } from "../../../../src/resources/styles";
|
||||||
import type { HomeAssistant } from "../../../../src/types";
|
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;
|
||||||
|
|
||||||
@internalProperty() private _error?: string;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
@property({ type: Boolean }) private _configHasChanged = false;
|
@property({ type: Boolean }) private _configHasChanged = false;
|
||||||
|
|
||||||
@property({ type: Boolean }) private _valid = true;
|
@property({ type: Boolean }) private _valid = true;
|
||||||
|
|
||||||
@query("ha-yaml-editor", true) private _editor!: HaYamlEditor;
|
@state() private _canShowSchema = false;
|
||||||
|
|
||||||
|
@state() private _showOptional = false;
|
||||||
|
|
||||||
|
@state() private _error?: string;
|
||||||
|
|
||||||
|
@state() private _options?: Record<string, unknown>;
|
||||||
|
|
||||||
|
@state() private _yamlMode = false;
|
||||||
|
|
||||||
|
@query("ha-yaml-editor") private _editor?: HaYamlEditor;
|
||||||
|
|
||||||
|
public computeLabel = (entry: HaFormSchema): string =>
|
||||||
|
this.addon.translations[this.hass.language]?.configuration?.[entry.name]
|
||||||
|
?.name ||
|
||||||
|
this.addon.translations.en?.configuration?.[entry.name].name ||
|
||||||
|
entry.name;
|
||||||
|
|
||||||
|
private _filteredShchema = memoizeOne(
|
||||||
|
(options: Record<string, unknown>, schema: HaFormSchema[]) =>
|
||||||
|
schema.filter((entry) => entry.name in options || entry.required)
|
||||||
|
);
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
|
const showForm =
|
||||||
|
!this._yamlMode && this._canShowSchema && this.addon.schema;
|
||||||
|
const hasHiddenOptions =
|
||||||
|
showForm &&
|
||||||
|
JSON.stringify(this.addon.schema) !==
|
||||||
|
JSON.stringify(
|
||||||
|
this._filteredShchema(this.addon.options, this.addon.schema!)
|
||||||
|
);
|
||||||
return html`
|
return html`
|
||||||
<h1>${this.addon.name}</h1>
|
<h1>${this.addon.name}</h1>
|
||||||
<ha-card header="Configuration">
|
<ha-card>
|
||||||
<div class="card-content">
|
<div class="header">
|
||||||
<ha-yaml-editor
|
<h2>
|
||||||
@value-changed=${this._configChanged}
|
${this.supervisor.localize("addon.configuration.options.header")}
|
||||||
></ha-yaml-editor>
|
</h2>
|
||||||
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
|
<div class="card-menu">
|
||||||
${this._valid ? "" : html` <div class="errors">Invalid YAML</div> `}
|
<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
|
||||||
|
? this.supervisor.localize(
|
||||||
|
"addon.configuration.options.edit_in_ui"
|
||||||
|
)
|
||||||
|
: this.supervisor.localize(
|
||||||
|
"addon.configuration.options.edit_in_yaml"
|
||||||
|
)}
|
||||||
|
</mwc-list-item>
|
||||||
|
<mwc-list-item class="warning">
|
||||||
|
${this.supervisor.localize("common.reset_defaults")}
|
||||||
|
</mwc-list-item>
|
||||||
|
</ha-button-menu>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
|
||||||
<ha-progress-button class="warning" @click=${this._resetTapped}>
|
<div class="card-content">
|
||||||
Reset to defaults
|
${showForm
|
||||||
</ha-progress-button>
|
? html`<ha-form
|
||||||
|
.data=${this._options!}
|
||||||
|
@value-changed=${this._configChanged}
|
||||||
|
.computeLabel=${this.computeLabel}
|
||||||
|
.schema=${this._showOptional
|
||||||
|
? this.addon.schema!
|
||||||
|
: this._filteredShchema(
|
||||||
|
this.addon.options,
|
||||||
|
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._yamlMode ||
|
||||||
|
(this._canShowSchema && this.addon.schema) ||
|
||||||
|
this._valid
|
||||||
|
? ""
|
||||||
|
: html`
|
||||||
|
<div class="errors">
|
||||||
|
${this.supervisor.localize(
|
||||||
|
"addon.configuration.options.invalid_yaml"
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
`}
|
||||||
|
</div>
|
||||||
|
${hasHiddenOptions
|
||||||
|
? html`<ha-formfield
|
||||||
|
class="show-additional"
|
||||||
|
.label=${this.supervisor.localize(
|
||||||
|
"addon.configuration.options.show_unused_optional"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<ha-switch
|
||||||
|
@change=${this._toggleOptional}
|
||||||
|
.checked=${this._showOptional}
|
||||||
|
>
|
||||||
|
</ha-switch>
|
||||||
|
</ha-formfield>`
|
||||||
|
: ""}
|
||||||
|
<div class="card-actions right">
|
||||||
<ha-progress-button
|
<ha-progress-button
|
||||||
@click=${this._saveTapped}
|
@click=${this._saveTapped}
|
||||||
.disabled=${!this._configHasChanged || !this._valid}
|
.disabled=${!this._configHasChanged || !this._valid}
|
||||||
>
|
>
|
||||||
Save
|
${this.supervisor.localize("common.save")}
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
</div>
|
</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
super.updated(changedProperties);
|
|
||||||
if (changedProperties.has("addon")) {
|
if (changedProperties.has("addon")) {
|
||||||
this._editor.setValue(this.addon.options);
|
this._options = { ...this.addon.options };
|
||||||
|
}
|
||||||
|
super.updated(changedProperties);
|
||||||
|
if (
|
||||||
|
changedProperties.has("_yamlMode") ||
|
||||||
|
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 _toggleOptional() {
|
||||||
|
this._showOptional = !this._showOptional;
|
||||||
|
}
|
||||||
|
|
||||||
private _configChanged(ev): void {
|
private _configChanged(ev): void {
|
||||||
this._configHasChanged = true;
|
if (this.addon.schema && this._canShowSchema && !this._yamlMode) {
|
||||||
this._valid = ev.detail.isValid;
|
this._valid = true;
|
||||||
|
this._configHasChanged = true;
|
||||||
|
this._options! = ev.detail.value;
|
||||||
|
} else {
|
||||||
|
this._configHasChanged = true;
|
||||||
|
this._valid = ev.detail.isValid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _resetTapped(ev: CustomEvent): Promise<void> {
|
private async _resetTapped(ev: CustomEvent): Promise<void> {
|
||||||
@@ -86,10 +223,10 @@ class HassioAddonConfig extends LitElement {
|
|||||||
button.progress = true;
|
button.progress = true;
|
||||||
|
|
||||||
const confirmed = await showConfirmationDialog(this, {
|
const confirmed = await showConfirmationDialog(this, {
|
||||||
title: this.addon.name,
|
title: this.supervisor.localize("confirm.reset_options.title"),
|
||||||
text: "Are you sure you want to reset all your options?",
|
text: this.supervisor.localize("confirm.reset_options.text"),
|
||||||
confirmText: "reset options",
|
confirmText: this.supervisor.localize("common.reset_options"),
|
||||||
dismissText: "no",
|
dismissText: this.supervisor.localize("common.cancel"),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!confirmed) {
|
if (!confirmed) {
|
||||||
@@ -111,48 +248,48 @@ class HassioAddonConfig extends LitElement {
|
|||||||
};
|
};
|
||||||
fireEvent(this, "hass-api-called", eventdata);
|
fireEvent(this, "hass-api-called", eventdata);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._error = `Failed to reset addon configuration, ${extractApiErrorMessage(
|
this._error = this.supervisor.localize(
|
||||||
err
|
"addon.common.update_available",
|
||||||
)}`;
|
"error",
|
||||||
|
extractApiErrorMessage(err)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
button.progress = false;
|
button.progress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _saveTapped(ev: CustomEvent): Promise<void> {
|
private async _saveTapped(ev: CustomEvent): Promise<void> {
|
||||||
const button = ev.currentTarget as any;
|
const button = ev.currentTarget as any;
|
||||||
|
const eventdata = {
|
||||||
|
success: true,
|
||||||
|
response: undefined,
|
||||||
|
path: "options",
|
||||||
|
};
|
||||||
button.progress = true;
|
button.progress = true;
|
||||||
|
|
||||||
let data: HassioAddonSetOptionParams;
|
|
||||||
this._error = undefined;
|
this._error = undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
data = {
|
await setHassioAddonOption(this.hass, this.addon.slug, {
|
||||||
options: this._editor.value,
|
options: this._yamlMode ? this._editor?.value : this._options,
|
||||||
};
|
});
|
||||||
} catch (err) {
|
|
||||||
this._error = err;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
await setHassioAddonOption(this.hass, this.addon.slug, data);
|
|
||||||
this._configHasChanged = false;
|
this._configHasChanged = false;
|
||||||
const eventdata = {
|
|
||||||
success: true,
|
|
||||||
response: undefined,
|
|
||||||
path: "options",
|
|
||||||
};
|
|
||||||
fireEvent(this, "hass-api-called", eventdata);
|
|
||||||
if (this.addon?.state === "started") {
|
if (this.addon?.state === "started") {
|
||||||
await suggestAddonRestart(this, this.hass, this.addon);
|
await suggestAddonRestart(this, this.hass, this.supervisor, this.addon);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._error = `Failed to save addon configuration, ${extractApiErrorMessage(
|
this._error = this.supervisor.localize(
|
||||||
err
|
"addon.failed_to_save",
|
||||||
)}`;
|
"error",
|
||||||
|
extractApiErrorMessage(err)
|
||||||
|
);
|
||||||
|
eventdata.success = false;
|
||||||
}
|
}
|
||||||
button.progress = false;
|
button.progress = false;
|
||||||
|
fireEvent(this, "hass-api-called", eventdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
hassioStyle,
|
hassioStyle,
|
||||||
@@ -178,6 +315,36 @@ 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;
|
||||||
|
}
|
||||||
|
.card-actions.right {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.show-additional {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +1,13 @@
|
|||||||
import { PaperInputElement } from "@polymer/paper-input/paper-input";
|
import { PaperInputElement } from "@polymer/paper-input/paper-input";
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
CSSResult,
|
CSSResultGroup,
|
||||||
customElement,
|
|
||||||
html,
|
html,
|
||||||
internalProperty,
|
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
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-card";
|
import "../../../../src/components/ha-card";
|
||||||
@@ -19,6 +17,7 @@ import {
|
|||||||
setHassioAddonOption,
|
setHassioAddonOption,
|
||||||
} 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 { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||||
import { haStyle } from "../../../../src/resources/styles";
|
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";
|
||||||
@@ -38,11 +37,13 @@ interface NetworkItemInput extends PaperInputElement {
|
|||||||
class HassioAddonNetwork extends LitElement {
|
class HassioAddonNetwork extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
||||||
|
|
||||||
@internalProperty() private _error?: string;
|
@state() private _error?: string;
|
||||||
|
|
||||||
@internalProperty() private _config?: NetworkItem[];
|
@state() private _config?: NetworkItem[];
|
||||||
|
|
||||||
public connectedCallback(): void {
|
public connectedCallback(): void {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
@@ -55,43 +56,57 @@ class HassioAddonNetwork extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-card header="Network">
|
<ha-card
|
||||||
|
.header=${this.supervisor.localize(
|
||||||
|
"addon.configuration.network.header"
|
||||||
|
)}
|
||||||
|
>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
|
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Container</th>
|
<th>
|
||||||
<th>Host</th>
|
${this.supervisor.localize(
|
||||||
<th>Description</th>
|
"addon.configuration.network.container"
|
||||||
|
)}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
${this.supervisor.localize(
|
||||||
|
"addon.configuration.network.host"
|
||||||
|
)}
|
||||||
|
</th>
|
||||||
|
<th>${this.supervisor.localize("common.description")}</th>
|
||||||
</tr>
|
</tr>
|
||||||
${this._config!.map((item) => {
|
${this._config!.map(
|
||||||
return html`
|
(item) => html`
|
||||||
<tr>
|
<tr>
|
||||||
<td>${item.container}</td>
|
<td>${item.container}</td>
|
||||||
<td>
|
<td>
|
||||||
<paper-input
|
<paper-input
|
||||||
@value-changed=${this._configChanged}
|
@value-changed=${this._configChanged}
|
||||||
placeholder="disabled"
|
placeholder="${this.supervisor.localize(
|
||||||
|
"addon.configuration.network.disabled"
|
||||||
|
)}"
|
||||||
.value=${item.host ? String(item.host) : ""}
|
.value=${item.host ? String(item.host) : ""}
|
||||||
.container=${item.container}
|
.container=${item.container}
|
||||||
no-label-float
|
no-label-float
|
||||||
></paper-input>
|
></paper-input>
|
||||||
</td>
|
</td>
|
||||||
<td>${item.description}</td>
|
<td>${this._computeDescription(item)}</td>
|
||||||
</tr>
|
</tr>
|
||||||
`;
|
`
|
||||||
})}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<ha-progress-button class="warning" @click=${this._resetTapped}>
|
<ha-progress-button class="warning" @click=${this._resetTapped}>
|
||||||
Reset to defaults
|
${this.supervisor.localize("common.reset_defaults")}
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
<ha-progress-button @click=${this._saveTapped}>
|
<ha-progress-button @click=${this._saveTapped}>
|
||||||
Save
|
${this.supervisor.localize("common.save")}
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
</div>
|
</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
@@ -105,16 +120,20 @@ class HassioAddonNetwork extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _computeDescription = (item: NetworkItem): string =>
|
||||||
|
this.addon.translations[this.hass.language]?.network?.[item.container]
|
||||||
|
?.description ||
|
||||||
|
this.addon.translations.en?.network?.[item.container]?.description ||
|
||||||
|
item.description;
|
||||||
|
|
||||||
private _setNetworkConfig(): void {
|
private _setNetworkConfig(): void {
|
||||||
const network = this.addon.network || {};
|
const network = this.addon.network || {};
|
||||||
const description = this.addon.network_description || {};
|
const description = this.addon.network_description || {};
|
||||||
const items: NetworkItem[] = Object.keys(network).map((key) => {
|
const items: NetworkItem[] = Object.keys(network).map((key) => ({
|
||||||
return {
|
container: key,
|
||||||
container: key,
|
host: network[key],
|
||||||
host: network[key],
|
description: description[key],
|
||||||
description: description[key],
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
this._config = items.sort((a, b) => (a.container > b.container ? 1 : -1));
|
this._config = items.sort((a, b) => (a.container > b.container ? 1 : -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,12 +166,14 @@ class HassioAddonNetwork extends LitElement {
|
|||||||
};
|
};
|
||||||
fireEvent(this, "hass-api-called", eventdata);
|
fireEvent(this, "hass-api-called", eventdata);
|
||||||
if (this.addon?.state === "started") {
|
if (this.addon?.state === "started") {
|
||||||
await suggestAddonRestart(this, this.hass, this.addon);
|
await suggestAddonRestart(this, this.hass, this.supervisor, this.addon);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._error = `Failed to set addon network configuration, ${extractApiErrorMessage(
|
this._error = this.supervisor.localize(
|
||||||
err
|
"addon.failed_to_reset",
|
||||||
)}`;
|
"error",
|
||||||
|
extractApiErrorMessage(err)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
button.progress = false;
|
button.progress = false;
|
||||||
@@ -181,17 +202,19 @@ class HassioAddonNetwork extends LitElement {
|
|||||||
};
|
};
|
||||||
fireEvent(this, "hass-api-called", eventdata);
|
fireEvent(this, "hass-api-called", eventdata);
|
||||||
if (this.addon?.state === "started") {
|
if (this.addon?.state === "started") {
|
||||||
await suggestAddonRestart(this, this.hass, this.addon);
|
await suggestAddonRestart(this, this.hass, this.supervisor, this.addon);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._error = `Failed to set addon network configuration, ${extractApiErrorMessage(
|
this._error = this.supervisor.localize(
|
||||||
err
|
"addon.failed_to_save",
|
||||||
)}`;
|
"error",
|
||||||
|
extractApiErrorMessage(err)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
button.progress = false;
|
button.progress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
hassioStyle,
|
hassioStyle,
|
||||||
|
@@ -1,13 +1,5 @@
|
|||||||
import {
|
import "../../../../src/components/ha-card";
|
||||||
css,
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
CSSResult,
|
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
internalProperty,
|
|
||||||
LitElement,
|
|
||||||
property,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import "../../../../src/components/ha-circular-progress";
|
import "../../../../src/components/ha-circular-progress";
|
||||||
import "../../../../src/components/ha-markdown";
|
import "../../../../src/components/ha-markdown";
|
||||||
import {
|
import {
|
||||||
@@ -19,16 +11,20 @@ import "../../../../src/layouts/hass-loading-screen";
|
|||||||
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 { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
|
||||||
@customElement("hassio-addon-documentation-tab")
|
@customElement("hassio-addon-documentation-tab")
|
||||||
class HassioAddonDocumentationDashboard extends LitElement {
|
class HassioAddonDocumentationDashboard extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
@property({ attribute: false }) public addon?: HassioAddonDetails;
|
@property({ attribute: false }) public addon?: HassioAddonDetails;
|
||||||
|
|
||||||
@internalProperty() private _error?: string;
|
@state() private _error?: string;
|
||||||
|
|
||||||
@internalProperty() private _content?: string;
|
@state() private _content?: string;
|
||||||
|
|
||||||
public async connectedCallback(): Promise<void> {
|
public async connectedCallback(): Promise<void> {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
@@ -53,7 +49,7 @@ class HassioAddonDocumentationDashboard extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
hassioStyle,
|
hassioStyle,
|
||||||
@@ -81,9 +77,11 @@ class HassioAddonDocumentationDashboard extends LitElement {
|
|||||||
this.addon!.slug
|
this.addon!.slug
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._error = `Failed to get addon documentation, ${extractApiErrorMessage(
|
this._error = this.supervisor.localize(
|
||||||
err
|
"addon.documentation.get_logs",
|
||||||
)}`;
|
"error",
|
||||||
|
extractApiErrorMessage(err)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,22 +4,23 @@ import {
|
|||||||
mdiInformationVariant,
|
mdiInformationVariant,
|
||||||
mdiMathLog,
|
mdiMathLog,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import {
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
css,
|
import { customElement, property, state } from "lit/decorators";
|
||||||
CSSResult,
|
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
property,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
|
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||||
|
import { navigate } from "../../../src/common/navigate";
|
||||||
|
import { extractSearchParam } from "../../../src/common/url/search-params";
|
||||||
|
import "../../../src/components/ha-circular-progress";
|
||||||
import {
|
import {
|
||||||
fetchHassioAddonInfo,
|
fetchHassioAddonInfo,
|
||||||
|
fetchHassioAddonsInfo,
|
||||||
HassioAddonDetails,
|
HassioAddonDetails,
|
||||||
} from "../../../src/data/hassio/addon";
|
} from "../../../src/data/hassio/addon";
|
||||||
|
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
|
||||||
|
import { Supervisor } from "../../../src/data/supervisor/supervisor";
|
||||||
|
import "../../../src/layouts/hass-error-screen";
|
||||||
|
import "../../../src/layouts/hass-loading-screen";
|
||||||
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";
|
||||||
@@ -35,12 +36,16 @@ import "./log/hassio-addon-logs";
|
|||||||
class HassioAddonDashboard extends LitElement {
|
class HassioAddonDashboard extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
@property({ attribute: false }) public route!: Route;
|
@property({ attribute: false }) public route!: Route;
|
||||||
|
|
||||||
@property({ attribute: false }) public addon?: HassioAddonDetails;
|
@property({ attribute: false }) public addon?: HassioAddonDetails;
|
||||||
|
|
||||||
@property({ type: Boolean }) public narrow!: boolean;
|
@property({ type: Boolean }) public narrow!: boolean;
|
||||||
|
|
||||||
|
@state() _error?: string;
|
||||||
|
|
||||||
private _computeTail = memoizeOne((route: Route) => {
|
private _computeTail = memoizeOne((route: Route) => {
|
||||||
const dividerPos = route.path.indexOf("/", 1);
|
const dividerPos = route.path.indexOf("/", 1);
|
||||||
return dividerPos === -1
|
return dividerPos === -1
|
||||||
@@ -55,13 +60,19 @@ class HassioAddonDashboard extends LitElement {
|
|||||||
});
|
});
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
|
if (this._error) {
|
||||||
|
return html`<hass-error-screen
|
||||||
|
.error=${this._error}
|
||||||
|
></hass-error-screen>`;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.addon) {
|
if (!this.addon) {
|
||||||
return html`<ha-circular-progress active></ha-circular-progress>`;
|
return html`<hass-loading-screen></hass-loading-screen>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const addonTabs: PageNavigation[] = [
|
const addonTabs: PageNavigation[] = [
|
||||||
{
|
{
|
||||||
name: "Info",
|
translationKey: "addon.panel.info",
|
||||||
path: `/hassio/addon/${this.addon.slug}/info`,
|
path: `/hassio/addon/${this.addon.slug}/info`,
|
||||||
iconPath: mdiInformationVariant,
|
iconPath: mdiInformationVariant,
|
||||||
},
|
},
|
||||||
@@ -69,7 +80,7 @@ class HassioAddonDashboard extends LitElement {
|
|||||||
|
|
||||||
if (this.addon.documentation) {
|
if (this.addon.documentation) {
|
||||||
addonTabs.push({
|
addonTabs.push({
|
||||||
name: "Documentation",
|
translationKey: "addon.panel.documentation",
|
||||||
path: `/hassio/addon/${this.addon.slug}/documentation`,
|
path: `/hassio/addon/${this.addon.slug}/documentation`,
|
||||||
iconPath: mdiFileDocument,
|
iconPath: mdiFileDocument,
|
||||||
});
|
});
|
||||||
@@ -78,12 +89,12 @@ class HassioAddonDashboard extends LitElement {
|
|||||||
if (this.addon.version) {
|
if (this.addon.version) {
|
||||||
addonTabs.push(
|
addonTabs.push(
|
||||||
{
|
{
|
||||||
name: "Configuration",
|
translationKey: "addon.panel.configuration",
|
||||||
path: `/hassio/addon/${this.addon.slug}/config`,
|
path: `/hassio/addon/${this.addon.slug}/config`,
|
||||||
iconPath: mdiCogs,
|
iconPath: mdiCogs,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Log",
|
translationKey: "addon.panel.log",
|
||||||
path: `/hassio/addon/${this.addon.slug}/logs`,
|
path: `/hassio/addon/${this.addon.slug}/logs`,
|
||||||
iconPath: mdiMathLog,
|
iconPath: mdiMathLog,
|
||||||
}
|
}
|
||||||
@@ -95,24 +106,26 @@ class HassioAddonDashboard extends LitElement {
|
|||||||
return html`
|
return html`
|
||||||
<hass-tabs-subpage
|
<hass-tabs-subpage
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
|
.localizeFunc=${this.supervisor.localize}
|
||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
.backPath=${this.addon.version ? "/hassio/dashboard" : "/hassio/store"}
|
.backPath=${this.addon.version ? "/hassio/dashboard" : "/hassio/store"}
|
||||||
.route=${route}
|
.route=${route}
|
||||||
hassio
|
|
||||||
.tabs=${addonTabs}
|
.tabs=${addonTabs}
|
||||||
|
supervisor
|
||||||
>
|
>
|
||||||
<span slot="header">${this.addon.name}</span>
|
<span slot="header">${this.addon.name}</span>
|
||||||
<hassio-addon-router
|
<hassio-addon-router
|
||||||
.route=${route}
|
.route=${route}
|
||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
|
.supervisor=${this.supervisor}
|
||||||
.addon=${this.addon}
|
.addon=${this.addon}
|
||||||
></hassio-addon-router>
|
></hassio-addon-router>
|
||||||
</hass-tabs-subpage>
|
</hass-tabs-subpage>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
hassioStyle,
|
hassioStyle,
|
||||||
@@ -152,30 +165,65 @@ class HassioAddonDashboard extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async firstUpdated(): Promise<void> {
|
protected async firstUpdated(): Promise<void> {
|
||||||
await this._routeDataChanged(this.route);
|
if (this.route.path === "") {
|
||||||
|
const requestedAddon = extractSearchParam("addon");
|
||||||
|
if (requestedAddon) {
|
||||||
|
const addonsInfo = await fetchHassioAddonsInfo(this.hass);
|
||||||
|
const validAddon = addonsInfo.addons.some(
|
||||||
|
(addon) => addon.slug === requestedAddon
|
||||||
|
);
|
||||||
|
if (!validAddon) {
|
||||||
|
this._error = this.supervisor.localize("my.error_addon_not_found");
|
||||||
|
} else {
|
||||||
|
navigate(this, `/hassio/addon/${requestedAddon}`, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
this.addEventListener("hass-api-called", (ev) => this._apiCalled(ev));
|
this.addEventListener("hass-api-called", (ev) => this._apiCalled(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _apiCalled(ev): Promise<void> {
|
private async _apiCalled(ev): Promise<void> {
|
||||||
const path: string = ev.detail.path;
|
if (!ev.detail.success) {
|
||||||
|
|
||||||
if (!path) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pathSplit: string[] = ev.detail.path?.split("/");
|
||||||
|
|
||||||
|
if (!pathSplit || pathSplit.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const path: string = pathSplit[pathSplit.length - 1];
|
||||||
|
|
||||||
|
if (["uninstall", "install", "update", "start", "stop"].includes(path)) {
|
||||||
|
fireEvent(this, "supervisor-collection-refresh", {
|
||||||
|
collection: "supervisor",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (path === "uninstall") {
|
if (path === "uninstall") {
|
||||||
history.back();
|
window.history.back();
|
||||||
} else {
|
} else {
|
||||||
await this._routeDataChanged(this.route);
|
await this._routeDataChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _routeDataChanged(routeData: Route): Promise<void> {
|
protected updated(changedProperties) {
|
||||||
const addon = routeData.path.split("/")[1];
|
if (changedProperties.has("route") && !this.addon) {
|
||||||
|
this._routeDataChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _routeDataChanged(): Promise<void> {
|
||||||
|
const addon = this.route.path.split("/")[1];
|
||||||
|
if (!addon) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const addoninfo = await fetchHassioAddonInfo(this.hass, addon);
|
const addoninfo = await fetchHassioAddonInfo(this.hass, addon);
|
||||||
this.addon = addoninfo;
|
this.addon = addoninfo;
|
||||||
} catch {
|
} catch (err) {
|
||||||
|
this._error = `Error fetching addon info: ${extractApiErrorMessage(err)}`;
|
||||||
this.addon = undefined;
|
this.addon = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import { customElement, property } from "lit-element";
|
import { customElement, property } from "lit/decorators";
|
||||||
import { HassioAddonDetails } from "../../../src/data/hassio/addon";
|
import { HassioAddonDetails } from "../../../src/data/hassio/addon";
|
||||||
|
import { Supervisor } from "../../../src/data/supervisor/supervisor";
|
||||||
import {
|
import {
|
||||||
HassRouterPage,
|
HassRouterPage,
|
||||||
RouterOptions,
|
RouterOptions,
|
||||||
@@ -17,6 +18,8 @@ class HassioAddonRouter extends HassRouterPage {
|
|||||||
|
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
||||||
|
|
||||||
protected routerOptions: RouterOptions = {
|
protected routerOptions: RouterOptions = {
|
||||||
@@ -41,6 +44,7 @@ class HassioAddonRouter extends HassRouterPage {
|
|||||||
protected updatePageEl(el) {
|
protected updatePageEl(el) {
|
||||||
el.route = this.routeTail;
|
el.route = this.routeTail;
|
||||||
el.hass = this.hass;
|
el.hass = this.hass;
|
||||||
|
el.supervisor = this.supervisor;
|
||||||
el.addon = this.addon;
|
el.addon = this.addon;
|
||||||
el.narrow = this.narrow;
|
el.narrow = this.narrow;
|
||||||
}
|
}
|
||||||
|
@@ -1,14 +1,8 @@
|
|||||||
import {
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
css,
|
import { customElement, property } from "lit/decorators";
|
||||||
CSSResult,
|
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
property,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
|
||||||
import "../../../../src/components/ha-circular-progress";
|
import "../../../../src/components/ha-circular-progress";
|
||||||
|
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||||
|
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||||
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";
|
||||||
@@ -20,6 +14,8 @@ class HassioAddonInfoDashboard extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
@property({ attribute: false }) public addon?: HassioAddonDetails;
|
@property({ attribute: false }) public addon?: HassioAddonDetails;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
@@ -32,13 +28,14 @@ class HassioAddonInfoDashboard extends LitElement {
|
|||||||
<hassio-addon-info
|
<hassio-addon-info
|
||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
|
.supervisor=${this.supervisor}
|
||||||
.addon=${this.addon}
|
.addon=${this.addon}
|
||||||
></hassio-addon-info>
|
></hassio-addon-info>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
hassioStyle,
|
hassioStyle,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,8 @@
|
|||||||
import {
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
css,
|
import { customElement, property } from "lit/decorators";
|
||||||
CSSResult,
|
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
property,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
|
||||||
import "../../../../src/components/ha-circular-progress";
|
import "../../../../src/components/ha-circular-progress";
|
||||||
|
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||||
|
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||||
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";
|
||||||
@@ -18,6 +12,8 @@ import "./hassio-addon-logs";
|
|||||||
class HassioAddonLogDashboard extends LitElement {
|
class HassioAddonLogDashboard extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
@property({ attribute: false }) public addon?: HassioAddonDetails;
|
@property({ attribute: false }) public addon?: HassioAddonDetails;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
@@ -28,13 +24,14 @@ class HassioAddonLogDashboard extends LitElement {
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<hassio-addon-logs
|
<hassio-addon-logs
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
|
.supervisor=${this.supervisor}
|
||||||
.addon=${this.addon}
|
.addon=${this.addon}
|
||||||
></hassio-addon-logs>
|
></hassio-addon-logs>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
hassioStyle,
|
hassioStyle,
|
||||||
|
@@ -1,20 +1,13 @@
|
|||||||
import "@material/mwc-button";
|
import "@material/mwc-button";
|
||||||
import {
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
css,
|
import { customElement, property, state } from "lit/decorators";
|
||||||
CSSResult,
|
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
internalProperty,
|
|
||||||
LitElement,
|
|
||||||
property,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import "../../../../src/components/ha-card";
|
import "../../../../src/components/ha-card";
|
||||||
import {
|
import {
|
||||||
fetchHassioAddonLogs,
|
fetchHassioAddonLogs,
|
||||||
HassioAddonDetails,
|
HassioAddonDetails,
|
||||||
} 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 { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||||
import { haStyle } from "../../../../src/resources/styles";
|
import { haStyle } from "../../../../src/resources/styles";
|
||||||
import { HomeAssistant } from "../../../../src/types";
|
import { HomeAssistant } from "../../../../src/types";
|
||||||
import "../../components/hassio-ansi-to-html";
|
import "../../components/hassio-ansi-to-html";
|
||||||
@@ -24,11 +17,13 @@ import { hassioStyle } from "../../resources/hassio-style";
|
|||||||
class HassioAddonLogs extends LitElement {
|
class HassioAddonLogs extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
||||||
|
|
||||||
@internalProperty() private _error?: string;
|
@state() private _error?: string;
|
||||||
|
|
||||||
@internalProperty() private _content?: string;
|
@state() private _content?: string;
|
||||||
|
|
||||||
public async connectedCallback(): Promise<void> {
|
public async connectedCallback(): Promise<void> {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
@@ -48,13 +43,15 @@ class HassioAddonLogs extends LitElement {
|
|||||||
: ""}
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<mwc-button @click=${this._refresh}>Refresh</mwc-button>
|
<mwc-button @click=${this._refresh}>
|
||||||
|
${this.supervisor.localize("common.refresh")}
|
||||||
|
</mwc-button>
|
||||||
</div>
|
</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
hassioStyle,
|
hassioStyle,
|
||||||
@@ -76,7 +73,11 @@ class HassioAddonLogs extends LitElement {
|
|||||||
try {
|
try {
|
||||||
this._content = await fetchHassioAddonLogs(this.hass, this.addon.slug);
|
this._content = await fetchHassioAddonLogs(this.hass, this.addon.slug);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._error = `Failed to get addon logs, ${extractApiErrorMessage(err)}`;
|
this._error = this.supervisor.localize(
|
||||||
|
"addon.logs.get_logs",
|
||||||
|
"error",
|
||||||
|
extractApiErrorMessage(err)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,12 +1,5 @@
|
|||||||
import {
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
css,
|
import { customElement, property } from "lit/decorators";
|
||||||
CSSResult,
|
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
property,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
bold: boolean;
|
bold: boolean;
|
||||||
@@ -25,7 +18,7 @@ class HassioAnsiToHtml extends LitElement {
|
|||||||
return html`${this._parseTextToColoredPre(this.content)}`;
|
return html`${this._parseTextToColoredPre(this.content)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResultGroup {
|
||||||
return css`
|
return css`
|
||||||
pre {
|
pre {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
@@ -1,13 +1,6 @@
|
|||||||
import { mdiHelpCircle } from "@mdi/js";
|
import { mdiHelpCircle } from "@mdi/js";
|
||||||
import {
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
css,
|
import { customElement, property } from "lit/decorators";
|
||||||
CSSResult,
|
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
property,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import "../../../src/components/ha-relative-time";
|
import "../../../src/components/ha-relative-time";
|
||||||
import "../../../src/components/ha-svg-icon";
|
import "../../../src/components/ha-svg-icon";
|
||||||
import { HomeAssistant } from "../../../src/types";
|
import { HomeAssistant } from "../../../src/types";
|
||||||
@@ -44,7 +37,7 @@ class HassioCardContent extends LitElement {
|
|||||||
${this.iconImage
|
${this.iconImage
|
||||||
? html`
|
? html`
|
||||||
<div class="icon_image ${this.iconClass}">
|
<div class="icon_image ${this.iconClass}">
|
||||||
<img src="${this.iconImage}" title="${this.iconTitle}" />
|
<img src="${this.iconImage}" .title=${this.iconTitle} />
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
@@ -56,13 +49,13 @@ class HassioCardContent extends LitElement {
|
|||||||
></ha-svg-icon>
|
></ha-svg-icon>
|
||||||
`}
|
`}
|
||||||
<div>
|
<div>
|
||||||
<div class="title">
|
<div class="title">${this.title}</div>
|
||||||
${this.title}
|
|
||||||
</div>
|
|
||||||
<div class="addition">
|
<div class="addition">
|
||||||
${this.description}
|
${this.description}
|
||||||
${/* treat as available when undefined */
|
${
|
||||||
this.available === false ? " (Not available)" : ""}
|
/* treat as available when undefined */
|
||||||
|
this.available === false ? " (Not available)" : ""
|
||||||
|
}
|
||||||
${this.datetime
|
${this.datetime
|
||||||
? html`
|
? html`
|
||||||
<ha-relative-time
|
<ha-relative-time
|
||||||
@@ -77,7 +70,7 @@ class HassioCardContent extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResultGroup {
|
||||||
return css`
|
return css`
|
||||||
ha-svg-icon {
|
ha-svg-icon {
|
||||||
margin-right: 24px;
|
margin-right: 24px;
|
||||||
|
@@ -2,13 +2,8 @@ import "@material/mwc-icon-button/mwc-icon-button";
|
|||||||
import { mdiFolderUpload } from "@mdi/js";
|
import { mdiFolderUpload } from "@mdi/js";
|
||||||
import "@polymer/iron-input/iron-input";
|
import "@polymer/iron-input/iron-input";
|
||||||
import "@polymer/paper-input/paper-input-container";
|
import "@polymer/paper-input/paper-input-container";
|
||||||
import {
|
import { html, LitElement, TemplateResult } from "lit";
|
||||||
customElement,
|
import { customElement, state } from "lit/decorators";
|
||||||
html,
|
|
||||||
internalProperty,
|
|
||||||
LitElement,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||||
import "../../../src/components/ha-circular-progress";
|
import "../../../src/components/ha-circular-progress";
|
||||||
import "../../../src/components/ha-file-upload";
|
import "../../../src/components/ha-file-upload";
|
||||||
@@ -33,9 +28,9 @@ const MAX_FILE_SIZE = 1 * 1024 * 1024 * 1024; // 1GB
|
|||||||
export class HassioUploadSnapshot extends LitElement {
|
export class HassioUploadSnapshot extends LitElement {
|
||||||
public hass!: HomeAssistant;
|
public hass!: HomeAssistant;
|
||||||
|
|
||||||
@internalProperty() public value: string | null = null;
|
@state() public value: string | null = null;
|
||||||
|
|
||||||
@internalProperty() private _uploading = false;
|
@state() private _uploading = false;
|
||||||
|
|
||||||
public render(): TemplateResult {
|
public render(): TemplateResult {
|
||||||
return html`
|
return html`
|
||||||
|
76
hassio/src/components/supervisor-metric.ts
Normal file
76
hassio/src/components/supervisor-metric.ts
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
|
import { customElement, property } from "lit/decorators";
|
||||||
|
import { classMap } from "lit/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(): CSSResultGroup {
|
||||||
|
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: 48px;
|
||||||
|
padding-right: 4px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"supervisor-metric": SupervisorMetric;
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user