Compare commits
555 Commits
websocket_
...
20250326.0
Author | SHA1 | Date | |
---|---|---|---|
![]() |
615b228827 | ||
![]() |
1819c04c27 | ||
![]() |
05e303d771 | ||
![]() |
53bb8251fa | ||
![]() |
f6467a35db | ||
![]() |
7cc6397324 | ||
![]() |
f6e3e312bb | ||
![]() |
be1e1ff9fc | ||
![]() |
2717e1e6cb | ||
![]() |
2e9f72867f | ||
![]() |
ff6b318fc9 | ||
![]() |
386b8ba747 | ||
![]() |
e27b97abc0 | ||
![]() |
772a2658cb | ||
![]() |
1a076061da | ||
![]() |
1cb71ed379 | ||
![]() |
fb11c21518 | ||
![]() |
9cfcd21a93 | ||
![]() |
e3f5e921d6 | ||
![]() |
df4e81be75 | ||
![]() |
1519e1b90c | ||
![]() |
4c8b7a30f4 | ||
![]() |
1e513281f4 | ||
![]() |
3c28764264 | ||
![]() |
82be98dad6 | ||
![]() |
3320cf1880 | ||
![]() |
f7cb83482a | ||
![]() |
a9ddaf1bd7 | ||
![]() |
eb7923fa49 | ||
![]() |
2ae70e9b54 | ||
![]() |
3857c53b7f | ||
![]() |
620fb6375e | ||
![]() |
e18f853f7e | ||
![]() |
bbe549fa86 | ||
![]() |
586a137037 | ||
![]() |
60010c82bd | ||
![]() |
d77f962087 | ||
![]() |
4c952c191a | ||
![]() |
e0fbd3cd1f | ||
![]() |
9f05f4df50 | ||
![]() |
6fbc7b2efe | ||
![]() |
8dab7c598e | ||
![]() |
b24f185d62 | ||
![]() |
dc5bb899d2 | ||
![]() |
420477e416 | ||
![]() |
cd9faf7d67 | ||
![]() |
852207a5f5 | ||
![]() |
1f705c07b2 | ||
![]() |
39ee84b54e | ||
![]() |
de402e7c1a | ||
![]() |
9b74cdebc2 | ||
![]() |
ebe8e54046 | ||
![]() |
2bac7455cc | ||
![]() |
3cbeef070a | ||
![]() |
bae0c232be | ||
![]() |
e65b5ae91e | ||
![]() |
4a166b6c23 | ||
![]() |
fe17bb89eb | ||
![]() |
888b2472df | ||
![]() |
ef7f499364 | ||
![]() |
5d9a53dcd5 | ||
![]() |
7ce166e40f | ||
![]() |
2c0c48106d | ||
![]() |
0e8be25a60 | ||
![]() |
27379c98df | ||
![]() |
4076e5655a | ||
![]() |
858b8b90d8 | ||
![]() |
d61c771e35 | ||
![]() |
ddbf57d541 | ||
![]() |
a5b7bb8391 | ||
![]() |
5803ab68c2 | ||
![]() |
64b9104199 | ||
![]() |
7aaea37db7 | ||
![]() |
3c11323ea4 | ||
![]() |
4f7d5053ec | ||
![]() |
7009482057 | ||
![]() |
d1090e8ad3 | ||
![]() |
06b969f6b6 | ||
![]() |
d8b6de2afd | ||
![]() |
dfd5e80436 | ||
![]() |
9d4df46d5f | ||
![]() |
5f4cb9e3c1 | ||
![]() |
96e6169b8d | ||
![]() |
0906d7aa5a | ||
![]() |
02fce1f40a | ||
![]() |
05aa55bfb9 | ||
![]() |
d4717f1293 | ||
![]() |
f6a7e40d4a | ||
![]() |
d73e677bea | ||
![]() |
356b74607a | ||
![]() |
8cb248223d | ||
![]() |
24eed2e5fa | ||
![]() |
c8a21a7a2f | ||
![]() |
54cc096b1a | ||
![]() |
49b1198cb7 | ||
![]() |
91e9836423 | ||
![]() |
6aa2a576b3 | ||
![]() |
9712f04662 | ||
![]() |
731a9a2e07 | ||
![]() |
d42bd36a3e | ||
![]() |
28c355812c | ||
![]() |
e09dbb474b | ||
![]() |
ee10f9080d | ||
![]() |
4f9ec622bf | ||
![]() |
dba269f2a3 | ||
![]() |
46c9af75fd | ||
![]() |
df934cfed9 | ||
![]() |
e871dc8151 | ||
![]() |
69026cbecf | ||
![]() |
dda7de3301 | ||
![]() |
1e000d2740 | ||
![]() |
1d747c0901 | ||
![]() |
8ef769559f | ||
![]() |
e141b4dbee | ||
![]() |
d0545fe827 | ||
![]() |
4ef3a25479 | ||
![]() |
616c1fda81 | ||
![]() |
e8805be561 | ||
![]() |
1b6d2ac08e | ||
![]() |
de4a8a0a72 | ||
![]() |
58dd778b3d | ||
![]() |
a4cdb294b1 | ||
![]() |
07c4296771 | ||
![]() |
95a99c7857 | ||
![]() |
fee215fe96 | ||
![]() |
5e9341bf4e | ||
![]() |
58b7c76b90 | ||
![]() |
6ed26407be | ||
![]() |
1ac0092d4e | ||
![]() |
a4e8ea366a | ||
![]() |
fe70355dde | ||
![]() |
01f07f6476 | ||
![]() |
9ef72e4afc | ||
![]() |
022ef982ca | ||
![]() |
f132a32fd4 | ||
![]() |
782df0473c | ||
![]() |
690cd47945 | ||
![]() |
8fe55b9bc0 | ||
![]() |
913fdfd0eb | ||
![]() |
c97916bea4 | ||
![]() |
cdfe4b53bf | ||
![]() |
75edc5132b | ||
![]() |
c79164992b | ||
![]() |
68960ba03d | ||
![]() |
c3a60a9c3f | ||
![]() |
4783720aaa | ||
![]() |
d55b806ce5 | ||
![]() |
e2ff8ce302 | ||
![]() |
b26bc1dcf0 | ||
![]() |
76b03d3a40 | ||
![]() |
c581d6d028 | ||
![]() |
d899711a48 | ||
![]() |
b7be74e722 | ||
![]() |
e53961d395 | ||
![]() |
03b08fefb7 | ||
![]() |
79374f6052 | ||
![]() |
ba19849182 | ||
![]() |
48338e0886 | ||
![]() |
3b87fc84a9 | ||
![]() |
61effc3f70 | ||
![]() |
e5b460c259 | ||
![]() |
7a56731f56 | ||
![]() |
bfe20d3760 | ||
![]() |
5a37087231 | ||
![]() |
dbe5bffe22 | ||
![]() |
62da09d045 | ||
![]() |
75d7676b36 | ||
![]() |
0bea89db91 | ||
![]() |
7ad759dd95 | ||
![]() |
5377c9e75d | ||
![]() |
bf206aa12b | ||
![]() |
73669e27f4 | ||
![]() |
1b5f4d3432 | ||
![]() |
49379b49d0 | ||
![]() |
2827421c9f | ||
![]() |
1a5a183410 | ||
![]() |
88a1de9aaf | ||
![]() |
4ad64ce2c8 | ||
![]() |
3f1ca32d13 | ||
![]() |
a6f7ee6b28 | ||
![]() |
0294198fba | ||
![]() |
7120200fd4 | ||
![]() |
209d0ae5f4 | ||
![]() |
81bafba4e4 | ||
![]() |
819225d32b | ||
![]() |
7f7575dcbc | ||
![]() |
56eef4bf31 | ||
![]() |
a384bc2273 | ||
![]() |
9d5d0e448f | ||
![]() |
f020269447 | ||
![]() |
99f86bb9cf | ||
![]() |
587751f5b4 | ||
![]() |
52b199c92b | ||
![]() |
ed6659ad8f | ||
![]() |
f1d04e5178 | ||
![]() |
807e87fce0 | ||
![]() |
cafab61727 | ||
![]() |
88e6906b6b | ||
![]() |
ebc1259e39 | ||
![]() |
c1f2e6d82b | ||
![]() |
ef964fd23e | ||
![]() |
13105c2d6f | ||
![]() |
5b9262487d | ||
![]() |
4ec6e324f8 | ||
![]() |
20f385e053 | ||
![]() |
dd441f882b | ||
![]() |
3a1d371b0b | ||
![]() |
5caa47acc1 | ||
![]() |
7833a680a9 | ||
![]() |
92681e7036 | ||
![]() |
ac18c6c018 | ||
![]() |
7e0cd35ea8 | ||
![]() |
45dee566b7 | ||
![]() |
71a4dceedc | ||
![]() |
27d883c1f6 | ||
![]() |
014db0e60f | ||
![]() |
c80247d992 | ||
![]() |
df33e97996 | ||
![]() |
8848911b34 | ||
![]() |
51193cf441 | ||
![]() |
a5b7f2466e | ||
![]() |
3d9bde548d | ||
![]() |
dfa98a4ba8 | ||
![]() |
20fe5b1b71 | ||
![]() |
9250ecb16f | ||
![]() |
e21d1399ea | ||
![]() |
5dded38ccc | ||
![]() |
54cc8f025c | ||
![]() |
0d215e65cd | ||
![]() |
f9824a3b3b | ||
![]() |
197c9219bd | ||
![]() |
4974a12221 | ||
![]() |
a13bcac0aa | ||
![]() |
cf288f7cd1 | ||
![]() |
1c8284609f | ||
![]() |
1fdadbf1b8 | ||
![]() |
3b272ae411 | ||
![]() |
a048c36861 | ||
![]() |
2a6c1773f3 | ||
![]() |
bf17012753 | ||
![]() |
bbaf23e049 | ||
![]() |
34b7929165 | ||
![]() |
8f06e70a11 | ||
![]() |
50ac60b35e | ||
![]() |
4caca19e32 | ||
![]() |
a7b1c45c00 | ||
![]() |
10c3e4c6f8 | ||
![]() |
1f50c359dc | ||
![]() |
a3e24a3dc0 | ||
![]() |
a906285a03 | ||
![]() |
5c933a43b2 | ||
![]() |
151a7fbc40 | ||
![]() |
4fa915c869 | ||
![]() |
d47e5c847b | ||
![]() |
db5036aed3 | ||
![]() |
bb672d0272 | ||
![]() |
e26d3d39f0 | ||
![]() |
e54c3a69af | ||
![]() |
cc04457d72 | ||
![]() |
9e1d64e728 | ||
![]() |
0cfe7f8d12 | ||
![]() |
2b1f301db6 | ||
![]() |
fc4996412e | ||
![]() |
ece4a6345f | ||
![]() |
a4c08a78b9 | ||
![]() |
a438fc5e41 | ||
![]() |
783132ae46 | ||
![]() |
680d81001c | ||
![]() |
a917383d7a | ||
![]() |
455a6761cd | ||
![]() |
acf42d7637 | ||
![]() |
3857c7321a | ||
![]() |
5eec814988 | ||
![]() |
4a1b7d46ca | ||
![]() |
75fadcca42 | ||
![]() |
41c93f5f7e | ||
![]() |
99559ff716 | ||
![]() |
753fe719e3 | ||
![]() |
5c14afd944 | ||
![]() |
23f1925c84 | ||
![]() |
edd37565a6 | ||
![]() |
fb3f779121 | ||
![]() |
4d7634ac67 | ||
![]() |
ba5c1133c6 | ||
![]() |
0a05dd8f71 | ||
![]() |
400106ec09 | ||
![]() |
a7a4194e09 | ||
![]() |
0bd7d27c57 | ||
![]() |
8175e45921 | ||
![]() |
cae36b393b | ||
![]() |
f84ad92356 | ||
![]() |
fb1ee2ed1d | ||
![]() |
9073282174 | ||
![]() |
91bd5cba08 | ||
![]() |
a68bdbfe08 | ||
![]() |
f3d614b0d3 | ||
![]() |
f3c9e4a4a0 | ||
![]() |
d22a82c4a6 | ||
![]() |
5cddc6e5c6 | ||
![]() |
c5c067ef19 | ||
![]() |
694bb3088c | ||
![]() |
ad487470fd | ||
![]() |
2801d071ba | ||
![]() |
71b65f208f | ||
![]() |
ab4efb7412 | ||
![]() |
c7a46ec25b | ||
![]() |
83d4a408f6 | ||
![]() |
06932d1479 | ||
![]() |
24211d5f25 | ||
![]() |
d387f19a31 | ||
![]() |
347ee2a4c3 | ||
![]() |
1363884773 | ||
![]() |
0256da511d | ||
![]() |
c52217c1ce | ||
![]() |
cdd17eed2e | ||
![]() |
4546c6f624 | ||
![]() |
2c34760204 | ||
![]() |
0b64861297 | ||
![]() |
94a5e737cc | ||
![]() |
05163588fc | ||
![]() |
ee64536862 | ||
![]() |
695a6a506e | ||
![]() |
3ee3cfa6cb | ||
![]() |
00d0cb7afa | ||
![]() |
3ae34403bd | ||
![]() |
1434966170 | ||
![]() |
8dd70f7017 | ||
![]() |
84a0289e1b | ||
![]() |
a25e1d3f7f | ||
![]() |
f53ac41eee | ||
![]() |
b9acd40b0f | ||
![]() |
7524dc8709 | ||
![]() |
cbedf62c39 | ||
![]() |
63a98155cd | ||
![]() |
7369b7e0d5 | ||
![]() |
922abafabf | ||
![]() |
f1bb4a5694 | ||
![]() |
e0b9cb8ccb | ||
![]() |
06f27650da | ||
![]() |
a772eaffd7 | ||
![]() |
c39be4a9b8 | ||
![]() |
c68002214f | ||
![]() |
8dbc203130 | ||
![]() |
64274d7355 | ||
![]() |
c07f4de39d | ||
![]() |
37ee2bf308 | ||
![]() |
d9559b7f07 | ||
![]() |
fce07daa20 | ||
![]() |
5d6fcaf6bb | ||
![]() |
0abccb88d6 | ||
![]() |
5dc5879773 | ||
![]() |
41df7a3f4a | ||
![]() |
920ec035c5 | ||
![]() |
043e8d6e2e | ||
![]() |
d8e36894a0 | ||
![]() |
65b6a3c6a3 | ||
![]() |
b16f82cedb | ||
![]() |
02deeb4ce7 | ||
![]() |
0c6651c2c2 | ||
![]() |
abbf56db1d | ||
![]() |
bc0cc8b387 | ||
![]() |
b66f41db7d | ||
![]() |
05fbe204c5 | ||
![]() |
ee199fbbc0 | ||
![]() |
56ab29da81 | ||
![]() |
10abaa538d | ||
![]() |
f25dac7f68 | ||
![]() |
99065a689f | ||
![]() |
ac88d5993a | ||
![]() |
b09ce45d31 | ||
![]() |
78e2809fe7 | ||
![]() |
a631bf9854 | ||
![]() |
1349c8520c | ||
![]() |
6d1a55cc3a | ||
![]() |
23a9ae6835 | ||
![]() |
dbd1e928de | ||
![]() |
e86ad21ce2 | ||
![]() |
0d97afb3f2 | ||
![]() |
0ab9098f23 | ||
![]() |
4498747fb1 | ||
![]() |
76977b64fa | ||
![]() |
2ca7395733 | ||
![]() |
0900869957 | ||
![]() |
91e8750f44 | ||
![]() |
936f66c41c | ||
![]() |
9ab5be4730 | ||
![]() |
a30e501031 | ||
![]() |
dcb04067b8 | ||
![]() |
bf962b29af | ||
![]() |
0ae6fa0763 | ||
![]() |
03a415beff | ||
![]() |
44cc75afbc | ||
![]() |
748642a8d6 | ||
![]() |
3d5c65d652 | ||
![]() |
a26bf80b13 | ||
![]() |
497c6c35f1 | ||
![]() |
b0b06a2787 | ||
![]() |
f3d55447ca | ||
![]() |
1b3d4b77d3 | ||
![]() |
6ec4041c4c | ||
![]() |
d919e8d333 | ||
![]() |
af7bb85667 | ||
![]() |
9061e2039b | ||
![]() |
906e6f4a88 | ||
![]() |
73fbe9a69d | ||
![]() |
2a0f69a629 | ||
![]() |
9411a77f14 | ||
![]() |
de3bf2e088 | ||
![]() |
16181b48ae | ||
![]() |
8682debe61 | ||
![]() |
bdbc9bc1b4 | ||
![]() |
79b9f8d083 | ||
![]() |
3918194d2d | ||
![]() |
e9fef1f873 | ||
![]() |
35face602b | ||
![]() |
9d7d332790 | ||
![]() |
803ac496f6 | ||
![]() |
f1173dd84b | ||
![]() |
44dcca9923 | ||
![]() |
bd74d39dd8 | ||
![]() |
172d6c3079 | ||
![]() |
56539e8065 | ||
![]() |
8f6867f142 | ||
![]() |
d51f8995dd | ||
![]() |
f2e35dc70a | ||
![]() |
6487b9b7ea | ||
![]() |
e50b658db7 | ||
![]() |
6efe237639 | ||
![]() |
4a94cfc05b | ||
![]() |
7cbdb1dcfd | ||
![]() |
553bb61db7 | ||
![]() |
786ff787d1 | ||
![]() |
28b3f2970a | ||
![]() |
7d170a710e | ||
![]() |
cc40b50675 | ||
![]() |
b6eaff46e9 | ||
![]() |
674bb0d16a | ||
![]() |
6ff018afc9 | ||
![]() |
ad48732bb7 | ||
![]() |
fef162346a | ||
![]() |
72d208d1ac | ||
![]() |
5a8b1b0fd4 | ||
![]() |
4cfc651799 | ||
![]() |
b4a3f4cb2c | ||
![]() |
f0507a88a6 | ||
![]() |
fe041e442d | ||
![]() |
e5fea98460 | ||
![]() |
31180e3a9e | ||
![]() |
ce0f02a45b | ||
![]() |
53f090356e | ||
![]() |
776c4da688 | ||
![]() |
849922f7be | ||
![]() |
a26701808f | ||
![]() |
904ee2e418 | ||
![]() |
11ae3a77e8 | ||
![]() |
3a12019b64 | ||
![]() |
6c2cf1ff60 | ||
![]() |
02ae0b5864 | ||
![]() |
85fe2213c1 | ||
![]() |
7dbc78f1d6 | ||
![]() |
f965a3504f | ||
![]() |
077f5efe7e | ||
![]() |
ef3bea71a0 | ||
![]() |
fcf655b0ec | ||
![]() |
b263b74916 | ||
![]() |
0f4b6b423a | ||
![]() |
72df585c5e | ||
![]() |
4698a63642 | ||
![]() |
6eb43a7d61 | ||
![]() |
af35b15400 | ||
![]() |
0d50d2664f | ||
![]() |
ff1159402e | ||
![]() |
f8742ae690 | ||
![]() |
c786d26542 | ||
![]() |
3f8ff94002 | ||
![]() |
64a968543b | ||
![]() |
aea98f702b | ||
![]() |
863ff622be | ||
![]() |
730cea6646 | ||
![]() |
7d1f8d618a | ||
![]() |
67b970fcaa | ||
![]() |
38bcdaa6f6 | ||
![]() |
8f1389de66 | ||
![]() |
37ac796c8f | ||
![]() |
716cd19d41 | ||
![]() |
173725f011 | ||
![]() |
ad561b885b | ||
![]() |
d77bdf4ac6 | ||
![]() |
ac3796ec31 | ||
![]() |
8c3fdfb6fb | ||
![]() |
b7c7d0b4b5 | ||
![]() |
8b0e6eed3a | ||
![]() |
603f884e8c | ||
![]() |
97dfccf4c7 | ||
![]() |
fd1e31c0cc | ||
![]() |
1de740e7b5 | ||
![]() |
5abfb90b16 | ||
![]() |
6b691063a8 | ||
![]() |
d1d746e7e6 | ||
![]() |
2fcb64d4a1 | ||
![]() |
3769f8c7c0 | ||
![]() |
f0a56e75f5 | ||
![]() |
15f33e1f19 | ||
![]() |
181122177b | ||
![]() |
684cd0f627 | ||
![]() |
277202e363 | ||
![]() |
b388d1fd42 | ||
![]() |
251e6399f5 | ||
![]() |
f44c5d7a63 | ||
![]() |
cae1ca52f0 | ||
![]() |
f8de2c64a5 | ||
![]() |
34ef5be720 | ||
![]() |
1402802031 | ||
![]() |
816989ab4d | ||
![]() |
d4497ca39c | ||
![]() |
6e39242ca3 | ||
![]() |
0197e32783 | ||
![]() |
87dfed4beb | ||
![]() |
dae991dc89 | ||
![]() |
6197e3483b | ||
![]() |
b2a6c8bd36 | ||
![]() |
938855e13c | ||
![]() |
a8712e3b8e | ||
![]() |
b15b577057 | ||
![]() |
653aeae3d8 | ||
![]() |
0aea6141ad | ||
![]() |
5243c1d871 | ||
![]() |
9449f5ad0a | ||
![]() |
c337bc5f97 | ||
![]() |
6aab60cf45 | ||
![]() |
52e9bc3213 | ||
![]() |
e48b2383cf | ||
![]() |
002a249777 | ||
![]() |
10498ce18d | ||
![]() |
6a5936b2b2 | ||
![]() |
dc68aaa803 | ||
![]() |
e7931ce049 | ||
![]() |
59b2582fe3 | ||
![]() |
8577b0721c | ||
![]() |
91319be855 | ||
![]() |
0dff538298 | ||
![]() |
6ac6d9c6eb | ||
![]() |
6ba0071296 | ||
![]() |
fef5dc4232 | ||
![]() |
ce58962dbb | ||
![]() |
9fb1e1d2ed | ||
![]() |
a29544c1e6 | ||
![]() |
b2b71edd04 | ||
![]() |
028472fc7b | ||
![]() |
b056ce228b | ||
![]() |
0cd4256c0e | ||
![]() |
e274c5b23f | ||
![]() |
ea57846465 | ||
![]() |
3f2e2bc659 | ||
![]() |
e3f2f66206 |
@@ -5,12 +5,15 @@
|
|||||||
"context": ".."
|
"context": ".."
|
||||||
},
|
},
|
||||||
"appPort": "8124:8123",
|
"appPort": "8124:8123",
|
||||||
"postCreateCommand": "sudo apt update && sudo apt upgrade -y && sudo apt install -y libpcap-dev",
|
"postCreateCommand": "./.devcontainer/post_create.sh",
|
||||||
"postStartCommand": "script/bootstrap",
|
"postStartCommand": "script/bootstrap",
|
||||||
"containerEnv": {
|
"containerEnv": {
|
||||||
"DEV_CONTAINER": "1",
|
"DEV_CONTAINER": "1",
|
||||||
"WORKSPACE_DIRECTORY": "${containerWorkspaceFolder}"
|
"WORKSPACE_DIRECTORY": "${containerWorkspaceFolder}"
|
||||||
},
|
},
|
||||||
|
"remoteEnv": {
|
||||||
|
"NODE_OPTIONS": "--max_old_space_size=8192"
|
||||||
|
},
|
||||||
"customizations": {
|
"customizations": {
|
||||||
"vscode": {
|
"vscode": {
|
||||||
"extensions": [
|
"extensions": [
|
||||||
|
22
.devcontainer/post_create.sh
Executable file
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This script will run after the container is created
|
||||||
|
|
||||||
|
# add github cli
|
||||||
|
(type -p wget >/dev/null || (sudo apt update && sudo apt-get install wget -y)) \
|
||||||
|
&& sudo mkdir -p -m 755 /etc/apt/keyrings \
|
||||||
|
&& out=$(mktemp) && wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg \
|
||||||
|
&& cat $out | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
|
||||||
|
&& sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
|
||||||
|
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
|
||||||
|
|
||||||
|
# Update package lists
|
||||||
|
sudo apt-get update
|
||||||
|
|
||||||
|
sudo apt upgrade -y
|
||||||
|
|
||||||
|
# Install necessary packages
|
||||||
|
sudo apt-get install -y libpcap-dev gh
|
||||||
|
|
||||||
|
# Display a message
|
||||||
|
echo "Post-create script has been executed successfully."
|
4
.github/workflows/cast_deployment.yaml
vendored
@@ -26,7 +26,7 @@ jobs:
|
|||||||
ref: dev
|
ref: dev
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
cache: yarn
|
cache: yarn
|
||||||
@@ -62,7 +62,7 @@ jobs:
|
|||||||
ref: master
|
ref: master
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
14
.github/workflows/ci.yaml
vendored
@@ -26,7 +26,7 @@ jobs:
|
|||||||
- name: Check out files from GitHub
|
- name: Check out files from GitHub
|
||||||
uses: actions/checkout@v4.2.2
|
uses: actions/checkout@v4.2.2
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
cache: yarn
|
cache: yarn
|
||||||
@@ -37,7 +37,7 @@ jobs:
|
|||||||
- name: Build resources
|
- name: Build resources
|
||||||
run: ./node_modules/.bin/gulp gen-icons-json build-translations build-locale-data gather-gallery-pages
|
run: ./node_modules/.bin/gulp gen-icons-json build-translations build-locale-data gather-gallery-pages
|
||||||
- name: Setup lint cache
|
- name: Setup lint cache
|
||||||
uses: actions/cache@v4.2.0
|
uses: actions/cache@v4.2.3
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
node_modules/.cache/prettier
|
node_modules/.cache/prettier
|
||||||
@@ -60,7 +60,7 @@ jobs:
|
|||||||
- name: Check out files from GitHub
|
- name: Check out files from GitHub
|
||||||
uses: actions/checkout@v4.2.2
|
uses: actions/checkout@v4.2.2
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
cache: yarn
|
cache: yarn
|
||||||
@@ -78,7 +78,7 @@ jobs:
|
|||||||
- name: Check out files from GitHub
|
- name: Check out files from GitHub
|
||||||
uses: actions/checkout@v4.2.2
|
uses: actions/checkout@v4.2.2
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
cache: yarn
|
cache: yarn
|
||||||
@@ -89,7 +89,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
IS_TEST: "true"
|
IS_TEST: "true"
|
||||||
- name: Upload bundle stats
|
- name: Upload bundle stats
|
||||||
uses: actions/upload-artifact@v4.6.0
|
uses: actions/upload-artifact@v4.6.2
|
||||||
with:
|
with:
|
||||||
name: frontend-bundle-stats
|
name: frontend-bundle-stats
|
||||||
path: build/stats/*.json
|
path: build/stats/*.json
|
||||||
@@ -102,7 +102,7 @@ jobs:
|
|||||||
- name: Check out files from GitHub
|
- name: Check out files from GitHub
|
||||||
uses: actions/checkout@v4.2.2
|
uses: actions/checkout@v4.2.2
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
cache: yarn
|
cache: yarn
|
||||||
@@ -113,7 +113,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
IS_TEST: "true"
|
IS_TEST: "true"
|
||||||
- name: Upload bundle stats
|
- name: Upload bundle stats
|
||||||
uses: actions/upload-artifact@v4.6.0
|
uses: actions/upload-artifact@v4.6.2
|
||||||
with:
|
with:
|
||||||
name: supervisor-bundle-stats
|
name: supervisor-bundle-stats
|
||||||
path: build/stats/*.json
|
path: build/stats/*.json
|
||||||
|
4
.github/workflows/demo_deployment.yaml
vendored
@@ -27,7 +27,7 @@ jobs:
|
|||||||
ref: dev
|
ref: dev
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
cache: yarn
|
cache: yarn
|
||||||
@@ -63,7 +63,7 @@ jobs:
|
|||||||
ref: master
|
ref: master
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
2
.github/workflows/design_deployment.yaml
vendored
@@ -19,7 +19,7 @@ jobs:
|
|||||||
uses: actions/checkout@v4.2.2
|
uses: actions/checkout@v4.2.2
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
2
.github/workflows/design_preview.yaml
vendored
@@ -24,7 +24,7 @@ jobs:
|
|||||||
uses: actions/checkout@v4.2.2
|
uses: actions/checkout@v4.2.2
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
6
.github/workflows/nightly.yaml
vendored
@@ -28,7 +28,7 @@ jobs:
|
|||||||
python-version: ${{ env.PYTHON_VERSION }}
|
python-version: ${{ env.PYTHON_VERSION }}
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
cache: yarn
|
cache: yarn
|
||||||
@@ -57,14 +57,14 @@ jobs:
|
|||||||
run: tar -czvf translations.tar.gz translations
|
run: tar -czvf translations.tar.gz translations
|
||||||
|
|
||||||
- name: Upload build artifacts
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@v4.6.0
|
uses: actions/upload-artifact@v4.6.2
|
||||||
with:
|
with:
|
||||||
name: wheels
|
name: wheels
|
||||||
path: dist/home_assistant_frontend*.whl
|
path: dist/home_assistant_frontend*.whl
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload translations
|
- name: Upload translations
|
||||||
uses: actions/upload-artifact@v4.6.0
|
uses: actions/upload-artifact@v4.6.2
|
||||||
with:
|
with:
|
||||||
name: translations
|
name: translations
|
||||||
path: translations.tar.gz
|
path: translations.tar.gz
|
||||||
|
2
.github/workflows/relative-ci.yaml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Send bundle stats and build information to RelativeCI
|
- name: Send bundle stats and build information to RelativeCI
|
||||||
uses: relative-ci/agent-action@v2.1.14
|
uses: relative-ci/agent-action@v2.2.0
|
||||||
with:
|
with:
|
||||||
key: ${{ secrets[format('RELATIVE_CI_KEY_{0}_{1}', matrix.bundle, matrix.build)] }}
|
key: ${{ secrets[format('RELATIVE_CI_KEY_{0}_{1}', matrix.bundle, matrix.build)] }}
|
||||||
token: ${{ github.token }}
|
token: ${{ github.token }}
|
||||||
|
8
.github/workflows/release.yaml
vendored
@@ -34,7 +34,7 @@ jobs:
|
|||||||
uses: home-assistant/actions/helpers/verify-version@master
|
uses: home-assistant/actions/helpers/verify-version@master
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
cache: yarn
|
cache: yarn
|
||||||
@@ -74,7 +74,7 @@ jobs:
|
|||||||
echo "home-assistant-frontend==$version" > ./requirements.txt
|
echo "home-assistant-frontend==$version" > ./requirements.txt
|
||||||
|
|
||||||
- name: Build wheels
|
- name: Build wheels
|
||||||
uses: home-assistant/wheels@2024.11.0
|
uses: home-assistant/wheels@2025.02.0
|
||||||
with:
|
with:
|
||||||
abi: cp313
|
abi: cp313
|
||||||
tag: musllinux_1_2
|
tag: musllinux_1_2
|
||||||
@@ -92,7 +92,7 @@ jobs:
|
|||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@v4.2.2
|
uses: actions/checkout@v4.2.2
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
cache: yarn
|
cache: yarn
|
||||||
@@ -121,7 +121,7 @@ jobs:
|
|||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@v4.2.2
|
uses: actions/checkout@v4.2.2
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4.2.0
|
uses: actions/setup-node@v4.3.0
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
42
.vscode/tasks.json
vendored
@@ -1,6 +1,42 @@
|
|||||||
{
|
{
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"tasks": [
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "Develop and serve Frontend",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "script/develop_and_serve -c ${input:coreUrl}",
|
||||||
|
// Sync changes here to other tasks until issue resolved
|
||||||
|
// https://github.com/Microsoft/vscode/issues/61497
|
||||||
|
"problemMatcher": {
|
||||||
|
"owner": "ha-build",
|
||||||
|
"source": "ha-build",
|
||||||
|
"fileLocation": "absolute",
|
||||||
|
"severity": "error",
|
||||||
|
"pattern": [
|
||||||
|
{
|
||||||
|
"regexp": "(SyntaxError): (.+): (.+) \\((\\d+):(\\d+)\\)",
|
||||||
|
"severity": 1,
|
||||||
|
"file": 2,
|
||||||
|
"message": 3,
|
||||||
|
"line": 4,
|
||||||
|
"column": 5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"background": {
|
||||||
|
"activeOnStart": true,
|
||||||
|
"beginsPattern": "Changes detected. Starting compilation",
|
||||||
|
"endsPattern": "Build done @"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"isBackground": true,
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"runOptions": {
|
||||||
|
"instanceLimit": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": "Develop Frontend",
|
"label": "Develop Frontend",
|
||||||
"type": "gulp",
|
"type": "gulp",
|
||||||
@@ -241,6 +277,12 @@
|
|||||||
"id": "supervisorToken",
|
"id": "supervisorToken",
|
||||||
"type": "promptString",
|
"type": "promptString",
|
||||||
"description": "The token for the Remote API proxy add-on"
|
"description": "The token for the Remote API proxy add-on"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "coreUrl",
|
||||||
|
"type": "promptString",
|
||||||
|
"description": "The URL of the Home Assistant Core instance",
|
||||||
|
"default": "http://127.0.0.1:8123"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -6,4 +6,4 @@ enableGlobalCache: false
|
|||||||
|
|
||||||
nodeLinker: node-modules
|
nodeLinker: node-modules
|
||||||
|
|
||||||
yarnPath: .yarn/releases/yarn-4.6.0.cjs
|
yarnPath: .yarn/releases/yarn-4.7.0.cjs
|
||||||
|
@@ -18,7 +18,7 @@ module.exports.sourceMapURL = () => {
|
|||||||
module.exports.ignorePackages = () => [];
|
module.exports.ignorePackages = () => [];
|
||||||
|
|
||||||
// Files from NPM packages that we should replace with empty file
|
// Files from NPM packages that we should replace with empty file
|
||||||
module.exports.emptyPackages = ({ latestBuild, isHassioBuild }) =>
|
module.exports.emptyPackages = ({ isHassioBuild }) =>
|
||||||
[
|
[
|
||||||
// Contains all color definitions for all material color sets.
|
// Contains all color definitions for all material color sets.
|
||||||
// We don't use it
|
// We don't use it
|
||||||
@@ -28,12 +28,6 @@ module.exports.emptyPackages = ({ latestBuild, isHassioBuild }) =>
|
|||||||
require.resolve("@polymer/font-roboto/roboto.js"),
|
require.resolve("@polymer/font-roboto/roboto.js"),
|
||||||
require.resolve("@vaadin/vaadin-material-styles/typography.js"),
|
require.resolve("@vaadin/vaadin-material-styles/typography.js"),
|
||||||
require.resolve("@vaadin/vaadin-material-styles/font-icons.js"),
|
require.resolve("@vaadin/vaadin-material-styles/font-icons.js"),
|
||||||
// Compatibility not needed for latest builds
|
|
||||||
latestBuild &&
|
|
||||||
// wrapped in require.resolve so it blows up if file no longer exists
|
|
||||||
require.resolve(
|
|
||||||
path.resolve(paths.polymer_dir, "src/resources/compatibility.ts")
|
|
||||||
),
|
|
||||||
// Icons in supervisor conflict with icons in HA so we don't load.
|
// Icons in supervisor conflict with icons in HA so we don't load.
|
||||||
isHassioBuild &&
|
isHassioBuild &&
|
||||||
require.resolve(
|
require.resolve(
|
||||||
@@ -55,7 +49,7 @@ module.exports.definedVars = ({ isProdBuild, latestBuild, defineOverlay }) => ({
|
|||||||
__STATIC_PATH__: "/static/",
|
__STATIC_PATH__: "/static/",
|
||||||
__HASS_URL__: `\`${
|
__HASS_URL__: `\`${
|
||||||
"HASS_URL" in process.env
|
"HASS_URL" in process.env
|
||||||
? process.env["HASS_URL"]
|
? process.env.HASS_URL
|
||||||
: "${location.protocol}//${location.host}"
|
: "${location.protocol}//${location.host}"
|
||||||
}\``,
|
}\``,
|
||||||
"process.env.NODE_ENV": JSON.stringify(
|
"process.env.NODE_ENV": JSON.stringify(
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
|
import tseslint from "typescript-eslint";
|
||||||
import rootConfig from "../eslint.config.mjs";
|
import rootConfig from "../eslint.config.mjs";
|
||||||
|
|
||||||
export default [
|
export default tseslint.config(...rootConfig, {
|
||||||
...rootConfig,
|
|
||||||
{
|
|
||||||
rules: {
|
rules: {
|
||||||
"no-console": "off",
|
"no-console": "off",
|
||||||
"import/no-extraneous-dependencies": "off",
|
"import/no-extraneous-dependencies": "off",
|
||||||
@@ -12,5 +13,4 @@ export default [
|
|||||||
"@typescript-eslint/no-require-imports": "off",
|
"@typescript-eslint/no-require-imports": "off",
|
||||||
"prefer-arrow-callback": "off",
|
"prefer-arrow-callback": "off",
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
];
|
|
||||||
|
@@ -56,6 +56,7 @@ const getCommonTemplateVars = () => {
|
|||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
modernRegex: compileRegex(browserRegexes.concat(haMacOSRegex)).toString(),
|
modernRegex: compileRegex(browserRegexes.concat(haMacOSRegex)).toString(),
|
||||||
|
hassUrl: process.env.HASS_URL || "",
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -59,6 +59,11 @@ function copyPolyfills(staticDir) {
|
|||||||
npmPath("@webcomponents/webcomponentsjs/webcomponents-bundle.js.map"),
|
npmPath("@webcomponents/webcomponentsjs/webcomponents-bundle.js.map"),
|
||||||
staticPath("polyfills/")
|
staticPath("polyfills/")
|
||||||
);
|
);
|
||||||
|
// Lit polyfill support
|
||||||
|
fs.copySync(
|
||||||
|
npmPath("lit/polyfill-support.js"),
|
||||||
|
path.join(staticPath("polyfills/"), "lit-polyfill-support.js")
|
||||||
|
);
|
||||||
|
|
||||||
// dialog-polyfill css
|
// dialog-polyfill css
|
||||||
copyFileDir(
|
copyFileDir(
|
||||||
@@ -90,6 +95,10 @@ function copyMapPanel(staticDir) {
|
|||||||
npmPath("leaflet/dist/leaflet.css"),
|
npmPath("leaflet/dist/leaflet.css"),
|
||||||
staticPath("images/leaflet/")
|
staticPath("images/leaflet/")
|
||||||
);
|
);
|
||||||
|
copyFileDir(
|
||||||
|
npmPath("leaflet.markercluster/dist/MarkerCluster.css"),
|
||||||
|
staticPath("images/leaflet/")
|
||||||
|
);
|
||||||
fs.copySync(
|
fs.copySync(
|
||||||
npmPath("leaflet/dist/images"),
|
npmPath("leaflet/dist/images"),
|
||||||
staticPath("images/leaflet/images/")
|
staticPath("images/leaflet/images/")
|
||||||
|
@@ -40,8 +40,8 @@ class CustomJSON extends Transform {
|
|||||||
this._reviver = reviver;
|
this._reviver = reviver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
async _transform(file, _, callback) {
|
async _transform(file, _, callback) {
|
||||||
try {
|
|
||||||
let obj = JSON.parse(file.contents.toString(), this._reviver);
|
let obj = JSON.parse(file.contents.toString(), this._reviver);
|
||||||
if (this._func) obj = this._func(obj, file.path);
|
if (this._func) obj = this._func(obj, file.path);
|
||||||
for (const [outObj, dir] of Array.isArray(obj) ? obj : [[obj, ""]]) {
|
for (const [outObj, dir] of Array.isArray(obj) ? obj : [[obj, ""]]) {
|
||||||
@@ -51,9 +51,6 @@ class CustomJSON extends Transform {
|
|||||||
this.push(outFile);
|
this.push(outFile);
|
||||||
}
|
}
|
||||||
callback(null);
|
callback(null);
|
||||||
} catch (err) {
|
|
||||||
callback(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,25 +65,19 @@ class MergeJSON extends Transform {
|
|||||||
this._reviver = reviver;
|
this._reviver = reviver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
async _transform(file, _, callback) {
|
async _transform(file, _, callback) {
|
||||||
try {
|
|
||||||
this._objects.push(JSON.parse(file.contents.toString(), this._reviver));
|
this._objects.push(JSON.parse(file.contents.toString(), this._reviver));
|
||||||
if (!this._outFile) this._outFile = file.clone({ contents: false });
|
if (!this._outFile) this._outFile = file.clone({ contents: false });
|
||||||
callback(null);
|
callback(null);
|
||||||
} catch (err) {
|
|
||||||
callback(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
async _flush(callback) {
|
async _flush(callback) {
|
||||||
try {
|
|
||||||
const mergedObj = merge(this._startObj, ...this._objects);
|
const mergedObj = merge(this._startObj, ...this._objects);
|
||||||
this._outFile.contents = Buffer.from(JSON.stringify(mergedObj));
|
this._outFile.contents = Buffer.from(JSON.stringify(mergedObj));
|
||||||
this._outFile.stem = this._stem;
|
this._outFile.stem = this._stem;
|
||||||
callback(null, this._outFile);
|
callback(null, this._outFile);
|
||||||
} catch (err) {
|
|
||||||
callback(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,12 +1,17 @@
|
|||||||
const { existsSync } = require("fs");
|
const { existsSync } = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const rspack = require("@rspack/core");
|
const rspack = require("@rspack/core");
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
const { RsdoctorRspackPlugin } = require("@rsdoctor/rspack-plugin");
|
const { RsdoctorRspackPlugin } = require("@rsdoctor/rspack-plugin");
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
const { StatsWriterPlugin } = require("webpack-stats-plugin");
|
const { StatsWriterPlugin } = require("webpack-stats-plugin");
|
||||||
const filterStats = require("@bundle-stats/plugin-webpack-filter").default;
|
const filterStats = require("@bundle-stats/plugin-webpack-filter");
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
const TerserPlugin = require("terser-webpack-plugin");
|
const TerserPlugin = require("terser-webpack-plugin");
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
const { WebpackManifestPlugin } = require("rspack-manifest-plugin");
|
const { WebpackManifestPlugin } = require("rspack-manifest-plugin");
|
||||||
const log = require("fancy-log");
|
const log = require("fancy-log");
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
const WebpackBar = require("webpackbar/rspack");
|
const WebpackBar = require("webpackbar/rspack");
|
||||||
const paths = require("./paths.cjs");
|
const paths = require("./paths.cjs");
|
||||||
const bundle = require("./bundle.cjs");
|
const bundle = require("./bundle.cjs");
|
||||||
@@ -155,9 +160,7 @@ const createRspackConfig = ({
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
new rspack.NormalModuleReplacementPlugin(
|
new rspack.NormalModuleReplacementPlugin(
|
||||||
new RegExp(
|
new RegExp(bundle.emptyPackages({ isHassioBuild }).join("|")),
|
||||||
bundle.emptyPackages({ latestBuild, isHassioBuild }).join("|")
|
|
||||||
),
|
|
||||||
path.resolve(paths.polymer_dir, "src/util/empty.js")
|
path.resolve(paths.polymer_dir, "src/util/empty.js")
|
||||||
),
|
),
|
||||||
!isProdBuild && new LogStartCompilePlugin(),
|
!isProdBuild && new LogStartCompilePlugin(),
|
||||||
@@ -192,6 +195,7 @@ const createRspackConfig = ({
|
|||||||
"lit/directives/if-defined$": "lit/directives/if-defined.js",
|
"lit/directives/if-defined$": "lit/directives/if-defined.js",
|
||||||
"lit/directives/guard$": "lit/directives/guard.js",
|
"lit/directives/guard$": "lit/directives/guard.js",
|
||||||
"lit/directives/cache$": "lit/directives/cache.js",
|
"lit/directives/cache$": "lit/directives/cache.js",
|
||||||
|
"lit/directives/join$": "lit/directives/join.js",
|
||||||
"lit/directives/repeat$": "lit/directives/repeat.js",
|
"lit/directives/repeat$": "lit/directives/repeat.js",
|
||||||
"lit/directives/live$": "lit/directives/live.js",
|
"lit/directives/live$": "lit/directives/live.js",
|
||||||
"lit/directives/keyed$": "lit/directives/keyed.js",
|
"lit/directives/keyed$": "lit/directives/keyed.js",
|
||||||
|
@@ -5,7 +5,7 @@ import { until } from "lit/directives/until";
|
|||||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||||
import "../../../src/components/ha-card";
|
import "../../../src/components/ha-card";
|
||||||
import "../../../src/components/ha-button";
|
import "../../../src/components/ha-button";
|
||||||
import "../../../src/components/ha-circular-progress";
|
import "../../../src/components/ha-spinner";
|
||||||
import type { LovelaceCardConfig } from "../../../src/data/lovelace/config/card";
|
import type { LovelaceCardConfig } from "../../../src/data/lovelace/config/card";
|
||||||
import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
|
import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
|
||||||
import type {
|
import type {
|
||||||
@@ -44,9 +44,7 @@ export class HADemoCard extends LitElement implements LovelaceCard {
|
|||||||
<div class="picker">
|
<div class="picker">
|
||||||
<div class="label">
|
<div class="label">
|
||||||
${this._switching
|
${this._switching
|
||||||
? html`
|
? html`<ha-spinner></ha-spinner>`
|
||||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
|
||||||
`
|
|
||||||
: until(
|
: until(
|
||||||
selectedDemoConfig.then(
|
selectedDemoConfig.then(
|
||||||
(conf) => html`
|
(conf) => html`
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// Compat needs to be first import
|
|
||||||
import "../../src/resources/compatibility";
|
|
||||||
import { customElement } from "lit/decorators";
|
import { customElement } from "lit/decorators";
|
||||||
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";
|
||||||
@@ -65,6 +63,7 @@ export class HaDemo extends HomeAssistantAppEl {
|
|||||||
mockEntityRegistry(hass, [
|
mockEntityRegistry(hass, [
|
||||||
{
|
{
|
||||||
config_entry_id: "co2signal",
|
config_entry_id: "co2signal",
|
||||||
|
config_subentry_id: null,
|
||||||
device_id: "co2signal",
|
device_id: "co2signal",
|
||||||
area_id: null,
|
area_id: null,
|
||||||
disabled_by: null,
|
disabled_by: null,
|
||||||
@@ -85,6 +84,7 @@ export class HaDemo extends HomeAssistantAppEl {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
config_entry_id: "co2signal",
|
config_entry_id: "co2signal",
|
||||||
|
config_subentry_id: null,
|
||||||
device_id: "co2signal",
|
device_id: "co2signal",
|
||||||
area_id: null,
|
area_id: null,
|
||||||
disabled_by: null,
|
disabled_by: null,
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
|
import type { validateConfig } from "../../../src/data/config";
|
||||||
import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
|
import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
|
||||||
|
|
||||||
export const mockConfig = (hass: MockHomeAssistant) => {
|
export const mockConfig = (hass: MockHomeAssistant) => {
|
||||||
hass.mockWS("validate_config", () => ({
|
hass.mockWS<typeof validateConfig>("validate_config", () => ({
|
||||||
actions: { valid: true },
|
actions: { valid: true, error: null },
|
||||||
conditions: { valid: true },
|
conditions: { valid: true, error: null },
|
||||||
triggers: { valid: true },
|
triggers: { valid: true, error: null },
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
|
import type { getConfigEntries } from "../../../src/data/config_entries";
|
||||||
import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
|
import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
|
||||||
|
|
||||||
export const mockConfigEntries = (hass: MockHomeAssistant) => {
|
export const mockConfigEntries = (hass: MockHomeAssistant) => {
|
||||||
hass.mockWS("config_entries/get", () => ({
|
hass.mockWS<typeof getConfigEntries>("config_entries/get", () => [
|
||||||
entry_id: "co2signal",
|
{
|
||||||
|
entry_id: "mock-entry-co2signal",
|
||||||
domain: "co2signal",
|
domain: "co2signal",
|
||||||
title: "Electricity Maps",
|
title: "Electricity Maps",
|
||||||
source: "user",
|
source: "user",
|
||||||
@@ -11,9 +13,14 @@ export const mockConfigEntries = (hass: MockHomeAssistant) => {
|
|||||||
supports_remove_device: false,
|
supports_remove_device: false,
|
||||||
supports_unload: true,
|
supports_unload: true,
|
||||||
supports_reconfigure: true,
|
supports_reconfigure: true,
|
||||||
|
supported_subentry_types: {},
|
||||||
pref_disable_new_entities: false,
|
pref_disable_new_entities: false,
|
||||||
pref_disable_polling: false,
|
pref_disable_polling: false,
|
||||||
disabled_by: null,
|
disabled_by: null,
|
||||||
reason: null,
|
reason: null,
|
||||||
}));
|
num_subentries: 0,
|
||||||
|
error_reason_translation_key: null,
|
||||||
|
error_reason_translation_placeholders: null,
|
||||||
|
},
|
||||||
|
]);
|
||||||
};
|
};
|
||||||
|
@@ -1,11 +1,16 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
/* eslint-disable import/no-extraneous-dependencies */
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
import unusedImports from "eslint-plugin-unused-imports";
|
import unusedImports from "eslint-plugin-unused-imports";
|
||||||
import globals from "globals";
|
import globals from "globals";
|
||||||
import tsParser from "@typescript-eslint/parser";
|
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
import js from "@eslint/js";
|
import js from "@eslint/js";
|
||||||
import { FlatCompat } from "@eslint/eslintrc";
|
import { FlatCompat } from "@eslint/eslintrc";
|
||||||
|
import tseslint from "typescript-eslint";
|
||||||
|
import eslintConfigPrettier from "eslint-config-prettier";
|
||||||
|
import { configs as litConfigs } from "eslint-plugin-lit";
|
||||||
|
import { configs as wcConfigs } from "eslint-plugin-wc";
|
||||||
|
|
||||||
const _filename = fileURLToPath(import.meta.url);
|
const _filename = fileURLToPath(import.meta.url);
|
||||||
const _dirname = path.dirname(_filename);
|
const _dirname = path.dirname(_filename);
|
||||||
@@ -15,17 +20,14 @@ const compat = new FlatCompat({
|
|||||||
allConfig: js.configs.all,
|
allConfig: js.configs.all,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default [
|
export default tseslint.config(
|
||||||
...compat.extends(
|
...compat.extends("airbnb-base", "plugin:lit-a11y/recommended"),
|
||||||
"airbnb-base",
|
eslintConfigPrettier,
|
||||||
"plugin:@typescript-eslint/recommended",
|
litConfigs["flat/all"],
|
||||||
"plugin:@typescript-eslint/strict",
|
tseslint.configs.recommended,
|
||||||
"plugin:@typescript-eslint/stylistic",
|
tseslint.configs.strict,
|
||||||
"plugin:wc/recommended",
|
tseslint.configs.stylistic,
|
||||||
"plugin:lit/all",
|
wcConfigs["flat/recommended"],
|
||||||
"plugin:lit-a11y/recommended",
|
|
||||||
"prettier"
|
|
||||||
),
|
|
||||||
{
|
{
|
||||||
plugins: {
|
plugins: {
|
||||||
"unused-imports": unusedImports,
|
"unused-imports": unusedImports,
|
||||||
@@ -43,7 +45,7 @@ export default [
|
|||||||
Polymer: true,
|
Polymer: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
parser: tsParser,
|
parser: tseslint.parser,
|
||||||
ecmaVersion: 2020,
|
ecmaVersion: 2020,
|
||||||
sourceType: "module",
|
sourceType: "module",
|
||||||
|
|
||||||
@@ -184,5 +186,5 @@ export default [
|
|||||||
],
|
],
|
||||||
"no-use-before-define": "off",
|
"no-use-before-define": "off",
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
];
|
);
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
|
import tseslint from "typescript-eslint";
|
||||||
import rootConfig from "../eslint.config.mjs";
|
import rootConfig from "../eslint.config.mjs";
|
||||||
|
|
||||||
export default [
|
export default tseslint.config(...rootConfig, {
|
||||||
...rootConfig,
|
|
||||||
{
|
|
||||||
rules: {
|
rules: {
|
||||||
"no-console": "off",
|
"no-console": "off",
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
];
|
|
||||||
|
10
gallery/public/images/select_box/card.svg
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<svg width="94" height="64" viewBox="0 0 94 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="64" rx="8" fill="white"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="63" rx="7.5" stroke="black" stroke-opacity="0.12"/>
|
||||||
|
<path d="M8 14C8 10.6863 10.6863 8 14 8H33C36.3137 8 39 10.6863 39 14C39 17.3137 36.3137 20 33 20H14C10.6863 20 8 17.3137 8 14Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M8 27C8 25.3431 9.34315 24 11 24H31C32.6569 24 34 25.3431 34 27V29C34 30.6569 32.6569 32 31 32H11C9.34315 32 8 30.6569 8 29V27Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M38 27C38 25.3431 39.3431 24 41 24H83C84.6569 24 86 25.3431 86 27V29C86 30.6569 84.6569 32 83 32H41C39.3431 32 38 30.6569 38 29V27Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M8 39C8 37.3431 9.34315 36 11 36H53C54.6569 36 56 37.3431 56 39V41C56 42.6569 54.6569 44 53 44H11C9.34315 44 8 42.6569 8 41V39Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M60 39C60 37.3431 61.3431 36 63 36H83C84.6569 36 86 37.3431 86 39V41C86 42.6569 84.6569 44 83 44H63C61.3431 44 60 42.6569 60 41V39Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M8 51C8 49.3431 9.34315 48 11 48H31C32.6569 48 34 49.3431 34 51V53C34 54.6569 32.6569 56 31 56H11C9.34315 56 8 54.6569 8 53V51Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
7
gallery/public/images/select_box/text_only.svg
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<svg width="94" height="48" viewBox="0 0 94 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 11C0 9.34315 1.34315 8 3 8H23C24.6569 8 26 9.34315 26 11V13C26 14.6569 24.6569 16 23 16H3C1.34315 16 0 14.6569 0 13V11Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M30 11C30 9.34315 31.3431 8 33 8H91C92.6569 8 94 9.34315 94 11V13C94 14.6569 92.6569 16 91 16H33C31.3431 16 30 14.6569 30 13V11Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M0 23C0 21.3431 1.34315 20 3 20H61C62.6569 20 64 21.3431 64 23V25C64 26.6569 62.6569 28 61 28H3C1.34315 28 0 26.6569 0 25V23Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M68 23C68 21.3431 69.3431 20 71 20H91C92.6569 20 94 21.3431 94 23V25C94 26.6569 92.6569 28 91 28H71C69.3431 28 68 26.6569 68 25V23Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M0 35C0 33.3431 1.34315 32 3 32H23C24.6569 32 26 33.3431 26 35V37C26 38.6569 24.6569 40 23 40H3C1.34315 40 0 38.6569 0 37V35Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 964 B |
@@ -1,63 +0,0 @@
|
|||||||
import type { TemplateResult } from "lit";
|
|
||||||
import { html, css, LitElement } from "lit";
|
|
||||||
import { customElement, property } from "lit/decorators";
|
|
||||||
import "../../../../src/components/ha-bar";
|
|
||||||
import "../../../../src/components/ha-card";
|
|
||||||
import "../../../../src/components/ha-circular-progress";
|
|
||||||
import "@material/web/progress/circular-progress";
|
|
||||||
import type { HomeAssistant } from "../../../../src/types";
|
|
||||||
|
|
||||||
@customElement("demo-components-ha-circular-progress")
|
|
||||||
export class DemoHaCircularProgress extends LitElement {
|
|
||||||
@property({ attribute: false }) hass!: HomeAssistant;
|
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
return html`<ha-card header="Basic circular progress">
|
|
||||||
<div class="card-content">
|
|
||||||
<ha-circular-progress indeterminate></ha-circular-progress></div
|
|
||||||
></ha-card>
|
|
||||||
<ha-card header="Different circular progress sizes">
|
|
||||||
<div class="card-content">
|
|
||||||
<ha-circular-progress
|
|
||||||
indeterminate
|
|
||||||
size="tiny"
|
|
||||||
></ha-circular-progress>
|
|
||||||
<ha-circular-progress
|
|
||||||
indeterminate
|
|
||||||
size="small"
|
|
||||||
></ha-circular-progress>
|
|
||||||
<ha-circular-progress
|
|
||||||
indeterminate
|
|
||||||
size="medium"
|
|
||||||
></ha-circular-progress>
|
|
||||||
<ha-circular-progress
|
|
||||||
indeterminate
|
|
||||||
size="large"
|
|
||||||
></ha-circular-progress></div
|
|
||||||
></ha-card>
|
|
||||||
<ha-card header="Circular progress with an aria-label">
|
|
||||||
<div class="card-content">
|
|
||||||
<ha-circular-progress
|
|
||||||
indeterminate
|
|
||||||
aria-label="Doing something..."
|
|
||||||
></ha-circular-progress>
|
|
||||||
<ha-circular-progress
|
|
||||||
indeterminate
|
|
||||||
.ariaLabel=${"Doing something..."}
|
|
||||||
></ha-circular-progress></div
|
|
||||||
></ha-card>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
static styles = css`
|
|
||||||
ha-card {
|
|
||||||
max-width: 600px;
|
|
||||||
margin: 24px auto;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HTMLElementTagNameMap {
|
|
||||||
"demo-components-ha-circular-progress": DemoHaCircularProgress;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,4 +1,4 @@
|
|||||||
import { mdiPacMan } from "@mdi/js";
|
import { mdiLightbulbOn, mdiPacMan } from "@mdi/js";
|
||||||
import type { TemplateResult } from "lit";
|
import type { TemplateResult } from "lit";
|
||||||
import { css, html, LitElement } from "lit";
|
import { css, html, LitElement } from "lit";
|
||||||
import { customElement } from "lit/decorators";
|
import { customElement } from "lit/decorators";
|
||||||
@@ -125,6 +125,23 @@ const SAMPLES: {
|
|||||||
`;
|
`;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
template(slot, leftChevron) {
|
||||||
|
return html`
|
||||||
|
<ha-expansion-panel
|
||||||
|
slot=${slot}
|
||||||
|
.leftChevron=${leftChevron}
|
||||||
|
header="Attr Header with actions"
|
||||||
|
>
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="leading-icon"
|
||||||
|
.path=${mdiLightbulbOn}
|
||||||
|
></ha-svg-icon>
|
||||||
|
${SHORT_TEXT}
|
||||||
|
</ha-expansion-panel>
|
||||||
|
`;
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("demo-components-ha-expansion-panel")
|
@customElement("demo-components-ha-expansion-panel")
|
||||||
|
@@ -48,6 +48,7 @@ const DEVICES: DeviceRegistryEntry[] = [
|
|||||||
area_id: "bedroom",
|
area_id: "bedroom",
|
||||||
configuration_url: null,
|
configuration_url: null,
|
||||||
config_entries: ["config_entry_1"],
|
config_entries: ["config_entry_1"],
|
||||||
|
config_entries_subentries: {},
|
||||||
connections: [],
|
connections: [],
|
||||||
disabled_by: null,
|
disabled_by: null,
|
||||||
entry_type: null,
|
entry_type: null,
|
||||||
@@ -71,6 +72,7 @@ const DEVICES: DeviceRegistryEntry[] = [
|
|||||||
area_id: "backyard",
|
area_id: "backyard",
|
||||||
configuration_url: null,
|
configuration_url: null,
|
||||||
config_entries: ["config_entry_2"],
|
config_entries: ["config_entry_2"],
|
||||||
|
config_entries_subentries: {},
|
||||||
connections: [],
|
connections: [],
|
||||||
disabled_by: null,
|
disabled_by: null,
|
||||||
entry_type: null,
|
entry_type: null,
|
||||||
@@ -94,6 +96,7 @@ const DEVICES: DeviceRegistryEntry[] = [
|
|||||||
area_id: null,
|
area_id: null,
|
||||||
configuration_url: null,
|
configuration_url: null,
|
||||||
config_entries: ["config_entry_3"],
|
config_entries: ["config_entry_3"],
|
||||||
|
config_entries_subentries: {},
|
||||||
connections: [],
|
connections: [],
|
||||||
disabled_by: null,
|
disabled_by: null,
|
||||||
entry_type: null,
|
entry_type: null,
|
||||||
|
3
gallery/src/pages/components/ha-select-box.markdown
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
title: Select box
|
||||||
|
---
|
152
gallery/src/pages/components/ha-select-box.ts
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
import type { TemplateResult } from "lit";
|
||||||
|
import { css, html, LitElement } from "lit";
|
||||||
|
import { customElement, state } from "lit/decorators";
|
||||||
|
import { repeat } from "lit/directives/repeat";
|
||||||
|
import "../../../../src/components/ha-card";
|
||||||
|
import "../../../../src/components/ha-select-box";
|
||||||
|
import type { SelectBoxOption } from "../../../../src/components/ha-select-box";
|
||||||
|
|
||||||
|
const basicOptions: SelectBoxOption[] = [
|
||||||
|
{
|
||||||
|
value: "text-only",
|
||||||
|
label: "Text only",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "card",
|
||||||
|
label: "Card",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "disabled",
|
||||||
|
label: "Disabled option",
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const fullOptions: SelectBoxOption[] = [
|
||||||
|
{
|
||||||
|
value: "text-only",
|
||||||
|
label: "Text only",
|
||||||
|
description: "Only text, no border and background",
|
||||||
|
image: "/images/select_box/text_only.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "card",
|
||||||
|
label: "Card",
|
||||||
|
description: "With border and background",
|
||||||
|
image: "/images/select_box/card.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "disabled",
|
||||||
|
label: "Disabled",
|
||||||
|
description: "Option that can not be selected",
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const selects: {
|
||||||
|
id: string;
|
||||||
|
label: string;
|
||||||
|
class?: string;
|
||||||
|
options: SelectBoxOption[];
|
||||||
|
disabled?: boolean;
|
||||||
|
}[] = [
|
||||||
|
{
|
||||||
|
id: "basic",
|
||||||
|
label: "Basic",
|
||||||
|
options: basicOptions,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "full",
|
||||||
|
label: "With description and image",
|
||||||
|
options: fullOptions,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
@customElement("demo-components-ha-select-box")
|
||||||
|
export class DemoHaSelectBox extends LitElement {
|
||||||
|
@state() private value?: string = "off";
|
||||||
|
|
||||||
|
handleValueChanged(e: CustomEvent) {
|
||||||
|
this.value = e.detail.value as string;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
${repeat(selects, (select) => {
|
||||||
|
const { id, label, options } = select;
|
||||||
|
return html`
|
||||||
|
<ha-card>
|
||||||
|
<div class="card-content">
|
||||||
|
<label id=${id}>${label}</label>
|
||||||
|
<ha-select-box
|
||||||
|
.value=${this.value}
|
||||||
|
.options=${options}
|
||||||
|
@value-changed=${this.handleValueChanged}
|
||||||
|
>
|
||||||
|
</ha-select-box>
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
`;
|
||||||
|
})}
|
||||||
|
<ha-card>
|
||||||
|
<div class="card-content">
|
||||||
|
<p class="title"><b>Column layout</b></p>
|
||||||
|
<div class="vertical-selects">
|
||||||
|
${repeat(selects, (select) => {
|
||||||
|
const { options } = select;
|
||||||
|
return html`
|
||||||
|
<ha-select-box
|
||||||
|
.value=${this.value}
|
||||||
|
.options=${options}
|
||||||
|
.maxColumns=${1}
|
||||||
|
@value-changed=${this.handleValueChanged}
|
||||||
|
>
|
||||||
|
</ha-select-box>
|
||||||
|
`;
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static styles = css`
|
||||||
|
ha-card {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 24px auto;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.custom {
|
||||||
|
--mdc-icon-size: 24px;
|
||||||
|
--control-select-color: var(--state-fan-active-color);
|
||||||
|
--control-select-thickness: 130px;
|
||||||
|
--control-select-border-radius: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.title {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vertical-selects ha-select-box {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-components-ha-select-box": DemoHaSelectBox;
|
||||||
|
}
|
||||||
|
}
|
@@ -47,6 +47,7 @@ const DEVICES: DeviceRegistryEntry[] = [
|
|||||||
area_id: "bedroom",
|
area_id: "bedroom",
|
||||||
configuration_url: null,
|
configuration_url: null,
|
||||||
config_entries: ["config_entry_1"],
|
config_entries: ["config_entry_1"],
|
||||||
|
config_entries_subentries: {},
|
||||||
connections: [],
|
connections: [],
|
||||||
disabled_by: null,
|
disabled_by: null,
|
||||||
entry_type: null,
|
entry_type: null,
|
||||||
@@ -70,6 +71,7 @@ const DEVICES: DeviceRegistryEntry[] = [
|
|||||||
area_id: "backyard",
|
area_id: "backyard",
|
||||||
configuration_url: null,
|
configuration_url: null,
|
||||||
config_entries: ["config_entry_2"],
|
config_entries: ["config_entry_2"],
|
||||||
|
config_entries_subentries: {},
|
||||||
connections: [],
|
connections: [],
|
||||||
disabled_by: null,
|
disabled_by: null,
|
||||||
entry_type: null,
|
entry_type: null,
|
||||||
@@ -93,6 +95,7 @@ const DEVICES: DeviceRegistryEntry[] = [
|
|||||||
area_id: null,
|
area_id: null,
|
||||||
configuration_url: null,
|
configuration_url: null,
|
||||||
config_entries: ["config_entry_3"],
|
config_entries: ["config_entry_3"],
|
||||||
|
config_entries_subentries: {},
|
||||||
connections: [],
|
connections: [],
|
||||||
disabled_by: null,
|
disabled_by: null,
|
||||||
entry_type: null,
|
entry_type: null,
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
---
|
---
|
||||||
title: Circular Progress
|
title: Spinner
|
||||||
subtitle: Can be used to indicate an ongoing task.
|
subtitle: Can be used to indicate an ongoing task.
|
||||||
---
|
---
|
44
gallery/src/pages/components/ha-spinner.ts
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import type { TemplateResult } from "lit";
|
||||||
|
import { html, css, LitElement } from "lit";
|
||||||
|
import { customElement, property } from "lit/decorators";
|
||||||
|
import "../../../../src/components/ha-bar";
|
||||||
|
import "../../../../src/components/ha-card";
|
||||||
|
import "../../../../src/components/ha-spinner";
|
||||||
|
import type { HomeAssistant } from "../../../../src/types";
|
||||||
|
|
||||||
|
@customElement("demo-components-ha-spinner")
|
||||||
|
export class DemoHaSpinner extends LitElement {
|
||||||
|
@property({ attribute: false }) hass!: HomeAssistant;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`<ha-card header="Basic spinner">
|
||||||
|
<div class="card-content">
|
||||||
|
<ha-spinner></ha-spinner></div
|
||||||
|
></ha-card>
|
||||||
|
<ha-card header="Different spinner sizes">
|
||||||
|
<div class="card-content">
|
||||||
|
<ha-spinner size="tiny"></ha-spinner>
|
||||||
|
<ha-spinner size="small"></ha-spinner>
|
||||||
|
<ha-spinner size="medium"></ha-spinner>
|
||||||
|
<ha-spinner size="large"></ha-spinner></div
|
||||||
|
></ha-card>
|
||||||
|
<ha-card header="Spinner with an aria-label">
|
||||||
|
<div class="card-content">
|
||||||
|
<ha-spinner aria-label="Doing something..."></ha-spinner>
|
||||||
|
<ha-spinner .ariaLabel=${"Doing something..."}></ha-spinner></div
|
||||||
|
></ha-card>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static styles = css`
|
||||||
|
ha-card {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 24px auto;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-components-ha-spinner": DemoHaSpinner;
|
||||||
|
}
|
||||||
|
}
|
30
gallery/src/pages/components/ha-tooltip.markdown
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
title: Tooltip
|
||||||
|
---
|
||||||
|
|
||||||
|
A tooltip's target is its _first child element_, so you should only wrap one element inside of the tooltip. If you need the tooltip to show up for multiple elements, nest them inside a container first.
|
||||||
|
|
||||||
|
Tooltips use `display: contents` so they won't interfere with how elements are positioned in a flex or grid layout.
|
||||||
|
|
||||||
|
<ha-tooltip content="This is a tooltip">
|
||||||
|
<ha-button>Hover Me</ha-button>
|
||||||
|
</ha-tooltip>
|
||||||
|
|
||||||
|
```
|
||||||
|
<ha-tooltip content="This is a tooltip">
|
||||||
|
<ha-button>Hover Me</ha-button>
|
||||||
|
</ha-tooltip>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
This element is based on sholace `sl-tooltip` it only sets some css tokens and has a custom show/hide animation.
|
||||||
|
|
||||||
|
<a href="https://shoelace.style/components/tooltip" target="_blank" rel="noopener noreferrer">Shoelace documentation</a>
|
||||||
|
|
||||||
|
### HA style tokens
|
||||||
|
|
||||||
|
In your theme settings use this without the prefixed `--`.
|
||||||
|
|
||||||
|
- `--ha-tooltip-border-radius` (Default: 4px)
|
||||||
|
- `--ha-tooltip-arrow-size` (Default: 8px)
|
2
gallery/src/pages/components/ha-tooltip.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import "../../../../src/components/ha-tooltip";
|
||||||
|
import "../../../../src/components/ha-button";
|
@@ -32,6 +32,8 @@ const createConfigEntry = (
|
|||||||
supports_remove_device: false,
|
supports_remove_device: false,
|
||||||
supports_unload: true,
|
supports_unload: true,
|
||||||
supports_reconfigure: true,
|
supports_reconfigure: true,
|
||||||
|
supported_subentry_types: {},
|
||||||
|
num_subentries: 0,
|
||||||
disabled_by: null,
|
disabled_by: null,
|
||||||
pref_disable_new_entities: false,
|
pref_disable_new_entities: false,
|
||||||
pref_disable_polling: false,
|
pref_disable_polling: false,
|
||||||
@@ -188,6 +190,7 @@ const createEntityRegistryEntries = (
|
|||||||
): EntityRegistryEntry[] => [
|
): EntityRegistryEntry[] => [
|
||||||
{
|
{
|
||||||
config_entry_id: item.entry_id,
|
config_entry_id: item.entry_id,
|
||||||
|
config_subentry_id: null,
|
||||||
device_id: "mock-device-id",
|
device_id: "mock-device-id",
|
||||||
area_id: null,
|
area_id: null,
|
||||||
disabled_by: null,
|
disabled_by: null,
|
||||||
@@ -214,6 +217,7 @@ const createDeviceRegistryEntries = (
|
|||||||
{
|
{
|
||||||
entry_type: null,
|
entry_type: null,
|
||||||
config_entries: [item.entry_id],
|
config_entries: [item.entry_id],
|
||||||
|
config_entries_subentries: {},
|
||||||
connections: [],
|
connections: [],
|
||||||
manufacturer: "ESPHome",
|
manufacturer: "ESPHome",
|
||||||
model: "Mock Device",
|
model: "Mock Device",
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||||
import { css, html, LitElement } from "lit";
|
import { css, html, LitElement } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
import "../../../../src/components/ha-circular-progress";
|
import "../../../../src/components/ha-spinner";
|
||||||
import type { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
import type { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||||
import type { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
import type { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||||
import { haStyle } from "../../../../src/resources/styles";
|
import { haStyle } from "../../../../src/resources/styles";
|
||||||
@@ -21,7 +21,7 @@ class HassioAddonConfigDashboard extends LitElement {
|
|||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (!this.addon) {
|
if (!this.addon) {
|
||||||
return html`<ha-circular-progress indeterminate></ha-circular-progress>`;
|
return html`<ha-spinner></ha-spinner>`;
|
||||||
}
|
}
|
||||||
const hasConfiguration =
|
const hasConfiguration =
|
||||||
(this.addon.options && Object.keys(this.addon.options).length) ||
|
(this.addon.options && Object.keys(this.addon.options).length) ||
|
||||||
|
@@ -113,8 +113,9 @@ class HassioAddonConfig extends LitElement {
|
|||||||
required: entry.required,
|
required: entry.required,
|
||||||
selector: {
|
selector: {
|
||||||
text: {
|
text: {
|
||||||
type:
|
type: entry.format
|
||||||
entry.format || MASKED_FIELDS.includes(entry.name)
|
? entry.format
|
||||||
|
: MASKED_FIELDS.includes(entry.name)
|
||||||
? "password"
|
? "password"
|
||||||
: "text",
|
: "text",
|
||||||
},
|
},
|
||||||
|
@@ -2,7 +2,7 @@ import "../../../../src/components/ha-card";
|
|||||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||||
import { css, html, LitElement } from "lit";
|
import { css, html, LitElement } from "lit";
|
||||||
import "../../../../src/components/ha-alert";
|
import "../../../../src/components/ha-alert";
|
||||||
import "../../../../src/components/ha-circular-progress";
|
import "../../../../src/components/ha-spinner";
|
||||||
import "../../../../src/components/ha-markdown";
|
import "../../../../src/components/ha-markdown";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import type { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
import type { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||||
@@ -33,7 +33,7 @@ class HassioAddonDocumentationDashboard extends LitElement {
|
|||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (!this.addon) {
|
if (!this.addon) {
|
||||||
return html`<ha-circular-progress indeterminate></ha-circular-progress>`;
|
return html`<ha-spinner></ha-spinner>`;
|
||||||
}
|
}
|
||||||
return html`
|
return html`
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
@@ -11,7 +11,6 @@ import memoizeOne from "memoize-one";
|
|||||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||||
import { navigate } from "../../../src/common/navigate";
|
import { navigate } from "../../../src/common/navigate";
|
||||||
import { extractSearchParam } from "../../../src/common/url/search-params";
|
import { extractSearchParam } from "../../../src/common/url/search-params";
|
||||||
import "../../../src/components/ha-circular-progress";
|
|
||||||
import type { HassioAddonDetails } from "../../../src/data/hassio/addon";
|
import type { HassioAddonDetails } from "../../../src/data/hassio/addon";
|
||||||
import {
|
import {
|
||||||
fetchAddonInfo,
|
fetchAddonInfo,
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||||
import { css, html, LitElement } from "lit";
|
import { css, html, LitElement } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
import "../../../../src/components/ha-circular-progress";
|
import "../../../../src/components/ha-spinner";
|
||||||
import type { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
import type { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||||
import type { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
import type { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||||
import { haStyle } from "../../../../src/resources/styles";
|
import { haStyle } from "../../../../src/resources/styles";
|
||||||
@@ -23,7 +23,7 @@ class HassioAddonInfoDashboard extends LitElement {
|
|||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (!this.addon) {
|
if (!this.addon) {
|
||||||
return html`<ha-circular-progress indeterminate></ha-circular-progress>`;
|
return html`<ha-spinner></ha-spinner>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
|
@@ -1331,6 +1331,12 @@ class HassioAddonInfo extends LitElement {
|
|||||||
ha-alert mwc-button {
|
ha-alert mwc-button {
|
||||||
--mdc-theme-primary: var(--primary-text-color);
|
--mdc-theme-primary: var(--primary-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:host > ha-alert {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,7 @@ import {
|
|||||||
type TemplateResult,
|
type TemplateResult,
|
||||||
} from "lit";
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import "../../../../src/components/ha-circular-progress";
|
import "../../../../src/components/ha-spinner";
|
||||||
import type { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
import type { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||||
import type { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
import type { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||||
import { haStyle } from "../../../../src/resources/styles";
|
import { haStyle } from "../../../../src/resources/styles";
|
||||||
@@ -28,9 +28,7 @@ class HassioAddonLogDashboard extends LitElement {
|
|||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (!this.addon) {
|
if (!this.addon) {
|
||||||
return html`
|
return html` <ha-spinner></ha-spinner> `;
|
||||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
return html`
|
return html`
|
||||||
<div class="search">
|
<div class="search">
|
||||||
|
@@ -253,13 +253,9 @@ export class HassioBackups extends LitElement {
|
|||||||
"backup.delete_selected"
|
"backup.delete_selected"
|
||||||
)}
|
)}
|
||||||
.path=${mdiDelete}
|
.path=${mdiDelete}
|
||||||
id="delete-btn"
|
|
||||||
class="warning"
|
class="warning"
|
||||||
@click=${this._deleteSelected}
|
@click=${this._deleteSelected}
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
<simple-tooltip animation-delay="0" for="delete-btn">
|
|
||||||
${this.supervisor.localize("backup.delete_selected")}
|
|
||||||
</simple-tooltip>
|
|
||||||
`}
|
`}
|
||||||
</div>
|
</div>
|
||||||
</div> `
|
</div> `
|
||||||
|
@@ -1,8 +1,6 @@
|
|||||||
import type { IFuseOptions } from "fuse.js";
|
import type { IFuseOptions } from "fuse.js";
|
||||||
import Fuse from "fuse.js";
|
import Fuse from "fuse.js";
|
||||||
import { stripDiacritics } from "../../../src/common/string/strip-diacritics";
|
|
||||||
import type { StoreAddon } from "../../../src/data/supervisor/store";
|
import type { StoreAddon } from "../../../src/data/supervisor/store";
|
||||||
import { getStripDiacriticsFn } from "../../../src/util/fuse";
|
|
||||||
|
|
||||||
export function filterAndSort(addons: StoreAddon[], filter: string) {
|
export function filterAndSort(addons: StoreAddon[], filter: string) {
|
||||||
const options: IFuseOptions<StoreAddon> = {
|
const options: IFuseOptions<StoreAddon> = {
|
||||||
@@ -10,8 +8,8 @@ export function filterAndSort(addons: StoreAddon[], filter: string) {
|
|||||||
isCaseSensitive: false,
|
isCaseSensitive: false,
|
||||||
minMatchCharLength: Math.min(filter.length, 2),
|
minMatchCharLength: Math.min(filter.length, 2),
|
||||||
threshold: 0.2,
|
threshold: 0.2,
|
||||||
getFn: getStripDiacriticsFn,
|
ignoreDiacritics: true,
|
||||||
};
|
};
|
||||||
const fuse = new Fuse(addons, options);
|
const fuse = new Fuse(addons, options);
|
||||||
return fuse.search(stripDiacritics(filter)).map((result) => result.item);
|
return fuse.search(filter).map((result) => result.item);
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,6 @@ import type { TemplateResult } from "lit";
|
|||||||
import { html, LitElement } from "lit";
|
import { html, LitElement } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
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/ha-circular-progress";
|
|
||||||
import "../../../src/components/ha-file-upload";
|
import "../../../src/components/ha-file-upload";
|
||||||
import type { HassioBackup } from "../../../src/data/hassio/backup";
|
import type { HassioBackup } from "../../../src/data/hassio/backup";
|
||||||
import { uploadBackup } from "../../../src/data/hassio/backup";
|
import { uploadBackup } from "../../../src/data/hassio/backup";
|
||||||
@@ -14,7 +13,7 @@ import type { LocalizeFunc } from "../../../src/common/translations/localize";
|
|||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HASSDomEvents {
|
interface HASSDomEvents {
|
||||||
"backup-uploaded": { backup: HassioBackup };
|
"hassio-backup-uploaded": { backup: HassioBackup };
|
||||||
"backup-cleared": undefined;
|
"backup-cleared": undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,7 +69,7 @@ export class HassioUploadBackup extends LitElement {
|
|||||||
this._uploading = true;
|
this._uploading = true;
|
||||||
try {
|
try {
|
||||||
const backup = await uploadBackup(this.hass, file);
|
const backup = await uploadBackup(this.hass, file);
|
||||||
fireEvent(this, "backup-uploaded", { backup: backup.data });
|
fireEvent(this, "hassio-backup-uploaded", { backup: backup.data });
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
title: "Upload failed",
|
title: "Upload failed",
|
||||||
|
@@ -5,7 +5,6 @@ import { customElement, property, query } from "lit/decorators";
|
|||||||
import { atLeastVersion } from "../../../src/common/config/version";
|
import { atLeastVersion } from "../../../src/common/config/version";
|
||||||
import { formatDate } from "../../../src/common/datetime/format_date";
|
import { formatDate } from "../../../src/common/datetime/format_date";
|
||||||
import { formatDateTime } from "../../../src/common/datetime/format_date_time";
|
import { formatDateTime } from "../../../src/common/datetime/format_date_time";
|
||||||
import type { LocalizeFunc } from "../../../src/common/translations/localize";
|
|
||||||
import "../../../src/components/ha-checkbox";
|
import "../../../src/components/ha-checkbox";
|
||||||
import "../../../src/components/ha-formfield";
|
import "../../../src/components/ha-formfield";
|
||||||
import "../../../src/components/ha-textfield";
|
import "../../../src/components/ha-textfield";
|
||||||
@@ -19,13 +18,10 @@ import type {
|
|||||||
} from "../../../src/data/hassio/backup";
|
} from "../../../src/data/hassio/backup";
|
||||||
import type { Supervisor } from "../../../src/data/supervisor/supervisor";
|
import type { Supervisor } from "../../../src/data/supervisor/supervisor";
|
||||||
import { mdiHomeAssistant } from "../../../src/resources/home-assistant-logo-svg";
|
import { mdiHomeAssistant } from "../../../src/resources/home-assistant-logo-svg";
|
||||||
import type { HomeAssistant, TranslationDict } from "../../../src/types";
|
import type { HomeAssistant } from "../../../src/types";
|
||||||
import "./supervisor-formfield-label";
|
import "./supervisor-formfield-label";
|
||||||
import type { HaTextField } from "../../../src/components/ha-textfield";
|
import type { HaTextField } from "../../../src/components/ha-textfield";
|
||||||
|
|
||||||
type BackupOrRestoreKey = keyof TranslationDict["supervisor"]["backup"] &
|
|
||||||
keyof TranslationDict["ui"]["panel"]["page-onboarding"]["restore"];
|
|
||||||
|
|
||||||
interface CheckboxItem {
|
interface CheckboxItem {
|
||||||
slug: string;
|
slug: string;
|
||||||
checked: boolean;
|
checked: boolean;
|
||||||
@@ -67,8 +63,6 @@ const _computeAddons = (addons): AddonCheckboxItem[] =>
|
|||||||
export class SupervisorBackupContent extends LitElement {
|
export class SupervisorBackupContent extends LitElement {
|
||||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||||
|
|
||||||
@property({ attribute: false }) public localize?: LocalizeFunc;
|
|
||||||
|
|
||||||
@property({ attribute: false }) public supervisor?: Supervisor;
|
@property({ attribute: false }) public supervisor?: Supervisor;
|
||||||
|
|
||||||
@property({ attribute: false }) public backup?: HassioBackupDetail;
|
@property({ attribute: false }) public backup?: HassioBackupDetail;
|
||||||
@@ -115,10 +109,6 @@ export class SupervisorBackupContent extends LitElement {
|
|||||||
this._focusTarget?.focus();
|
this._focusTarget?.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _localize = (key: BackupOrRestoreKey) =>
|
|
||||||
this.supervisor?.localize(`backup.${key}`) ||
|
|
||||||
this.localize!(`ui.panel.page-onboarding.restore.${key}`);
|
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
if (!this.onboarding && !this.supervisor) {
|
if (!this.onboarding && !this.supervisor) {
|
||||||
return nothing;
|
return nothing;
|
||||||
@@ -132,8 +122,8 @@ export class SupervisorBackupContent extends LitElement {
|
|||||||
${this.backup
|
${this.backup
|
||||||
? html`<div class="details">
|
? html`<div class="details">
|
||||||
${this.backup.type === "full"
|
${this.backup.type === "full"
|
||||||
? this._localize("full_backup")
|
? this.supervisor?.localize("backup.full_backup")
|
||||||
: this._localize("partial_backup")}
|
: this.supervisor?.localize("backup.partial_backup")}
|
||||||
(${Math.ceil(this.backup.size * 10) / 10 + " MB"})<br />
|
(${Math.ceil(this.backup.size * 10) / 10 + " MB"})<br />
|
||||||
${this.hass
|
${this.hass
|
||||||
? formatDateTime(
|
? formatDateTime(
|
||||||
@@ -145,7 +135,7 @@ export class SupervisorBackupContent extends LitElement {
|
|||||||
</div>`
|
</div>`
|
||||||
: html`<ha-textfield
|
: html`<ha-textfield
|
||||||
name="backupName"
|
name="backupName"
|
||||||
.label=${this._localize("name")}
|
.label=${this.supervisor?.localize("backup.name")}
|
||||||
.value=${this.backupName}
|
.value=${this.backupName}
|
||||||
@change=${this._handleTextValueChanged}
|
@change=${this._handleTextValueChanged}
|
||||||
>
|
>
|
||||||
@@ -153,11 +143,13 @@ export class SupervisorBackupContent extends LitElement {
|
|||||||
${!this.backup || this.backup.type === "full"
|
${!this.backup || this.backup.type === "full"
|
||||||
? html`<div class="sub-header">
|
? html`<div class="sub-header">
|
||||||
${!this.backup
|
${!this.backup
|
||||||
? this._localize("type")
|
? this.supervisor?.localize("backup.type")
|
||||||
: this._localize("select_type")}
|
: this.supervisor?.localize("backup.select_type")}
|
||||||
</div>
|
</div>
|
||||||
<div class="backup-types">
|
<div class="backup-types">
|
||||||
<ha-formfield .label=${this._localize("full_backup")}>
|
<ha-formfield
|
||||||
|
.label=${this.supervisor?.localize("backup.full_backup")}
|
||||||
|
>
|
||||||
<ha-radio
|
<ha-radio
|
||||||
@change=${this._handleRadioValueChanged}
|
@change=${this._handleRadioValueChanged}
|
||||||
value="full"
|
value="full"
|
||||||
@@ -166,7 +158,9 @@ export class SupervisorBackupContent extends LitElement {
|
|||||||
>
|
>
|
||||||
</ha-radio>
|
</ha-radio>
|
||||||
</ha-formfield>
|
</ha-formfield>
|
||||||
<ha-formfield .label=${this._localize("partial_backup")}>
|
<ha-formfield
|
||||||
|
.label=${this.supervisor?.localize("backup.partial_backup")}
|
||||||
|
>
|
||||||
<ha-radio
|
<ha-radio
|
||||||
@change=${this._handleRadioValueChanged}
|
@change=${this._handleRadioValueChanged}
|
||||||
value="partial"
|
value="partial"
|
||||||
@@ -202,7 +196,7 @@ export class SupervisorBackupContent extends LitElement {
|
|||||||
? html`
|
? html`
|
||||||
<ha-formfield
|
<ha-formfield
|
||||||
.label=${html`<supervisor-formfield-label
|
.label=${html`<supervisor-formfield-label
|
||||||
.label=${this._localize("folders")}
|
.label=${this.supervisor?.localize("backup.folders")}
|
||||||
.iconPath=${mdiFolder}
|
.iconPath=${mdiFolder}
|
||||||
>
|
>
|
||||||
</supervisor-formfield-label>`}
|
</supervisor-formfield-label>`}
|
||||||
@@ -222,7 +216,7 @@ export class SupervisorBackupContent extends LitElement {
|
|||||||
? html`
|
? html`
|
||||||
<ha-formfield
|
<ha-formfield
|
||||||
.label=${html`<supervisor-formfield-label
|
.label=${html`<supervisor-formfield-label
|
||||||
.label=${this._localize("addons")}
|
.label=${this.supervisor?.localize("backup.addons")}
|
||||||
.iconPath=${mdiPuzzle}
|
.iconPath=${mdiPuzzle}
|
||||||
>
|
>
|
||||||
</supervisor-formfield-label>`}
|
</supervisor-formfield-label>`}
|
||||||
@@ -247,7 +241,7 @@ export class SupervisorBackupContent extends LitElement {
|
|||||||
${!this.backup
|
${!this.backup
|
||||||
? html`<ha-formfield
|
? html`<ha-formfield
|
||||||
class="password"
|
class="password"
|
||||||
.label=${this._localize("password_protection")}
|
.label=${this.supervisor?.localize("backup.password_protection")}
|
||||||
>
|
>
|
||||||
<ha-checkbox
|
<ha-checkbox
|
||||||
.checked=${this.backupHasPassword}
|
.checked=${this.backupHasPassword}
|
||||||
@@ -259,7 +253,7 @@ export class SupervisorBackupContent extends LitElement {
|
|||||||
${this.backupHasPassword
|
${this.backupHasPassword
|
||||||
? html`
|
? html`
|
||||||
<ha-password-field
|
<ha-password-field
|
||||||
.label=${this._localize("password")}
|
.label=${this.supervisor?.localize("backup.password")}
|
||||||
name="backupPassword"
|
name="backupPassword"
|
||||||
.value=${this.backupPassword}
|
.value=${this.backupPassword}
|
||||||
@change=${this._handleTextValueChanged}
|
@change=${this._handleTextValueChanged}
|
||||||
@@ -267,7 +261,7 @@ export class SupervisorBackupContent extends LitElement {
|
|||||||
</ha-password-field>
|
</ha-password-field>
|
||||||
${!this.backup
|
${!this.backup
|
||||||
? html`<ha-password-field
|
? html`<ha-password-field
|
||||||
.label=${this._localize("confirm_password")}
|
.label=${this.supervisor?.localize("backup.confirm_password")}
|
||||||
name="confirmBackupPassword"
|
name="confirmBackupPassword"
|
||||||
.value=${this.confirmBackupPassword}
|
.value=${this.confirmBackupPassword}
|
||||||
@change=${this._handleTextValueChanged}
|
@change=${this._handleTextValueChanged}
|
||||||
|
@@ -72,7 +72,7 @@ export class DialogHassioBackupUpload
|
|||||||
</ha-header-bar>
|
</ha-header-bar>
|
||||||
</div>
|
</div>
|
||||||
<hassio-upload-backup
|
<hassio-upload-backup
|
||||||
@backup-uploaded=${this._backupUploaded}
|
@hassio-backup-uploaded=${this._backupUploaded}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
></hassio-upload-backup>
|
></hassio-upload-backup>
|
||||||
</ha-dialog>
|
</ha-dialog>
|
||||||
|
@@ -12,6 +12,7 @@ import "../../../../src/components/ha-md-dialog";
|
|||||||
import "../../../../src/components/ha-dialog-header";
|
import "../../../../src/components/ha-dialog-header";
|
||||||
import "../../../../src/components/buttons/ha-progress-button";
|
import "../../../../src/components/buttons/ha-progress-button";
|
||||||
import "../../../../src/components/ha-alert";
|
import "../../../../src/components/ha-alert";
|
||||||
|
import "../../../../src/components/ha-spinner";
|
||||||
import "../../../../src/components/ha-button";
|
import "../../../../src/components/ha-button";
|
||||||
import "../../../../src/components/ha-button-menu";
|
import "../../../../src/components/ha-button-menu";
|
||||||
import "../../../../src/components/ha-header-bar";
|
import "../../../../src/components/ha-header-bar";
|
||||||
@@ -35,7 +36,6 @@ import { fileDownload } from "../../../../src/util/file_download";
|
|||||||
import "../../components/supervisor-backup-content";
|
import "../../components/supervisor-backup-content";
|
||||||
import type { SupervisorBackupContent } from "../../components/supervisor-backup-content";
|
import type { SupervisorBackupContent } from "../../components/supervisor-backup-content";
|
||||||
import type { HassioBackupDialogParams } from "./show-dialog-hassio-backup";
|
import type { HassioBackupDialogParams } from "./show-dialog-hassio-backup";
|
||||||
import type { BackupOrRestoreKey } from "../../util/translations";
|
|
||||||
import type { HaMdDialog } from "../../../../src/components/ha-md-dialog";
|
import type { HaMdDialog } from "../../../../src/components/ha-md-dialog";
|
||||||
|
|
||||||
@customElement("dialog-hassio-backup")
|
@customElement("dialog-hassio-backup")
|
||||||
@@ -43,7 +43,7 @@ class HassioBackupDialog
|
|||||||
extends LitElement
|
extends LitElement
|
||||||
implements HassDialog<HassioBackupDialogParams>
|
implements HassDialog<HassioBackupDialogParams>
|
||||||
{
|
{
|
||||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@state() private _error?: string;
|
@state() private _error?: string;
|
||||||
|
|
||||||
@@ -62,9 +62,13 @@ class HassioBackupDialog
|
|||||||
this._dialogParams = dialogParams;
|
this._dialogParams = dialogParams;
|
||||||
this._backup = await fetchHassioBackupInfo(this.hass, dialogParams.slug);
|
this._backup = await fetchHassioBackupInfo(this.hass, dialogParams.slug);
|
||||||
if (!this._backup) {
|
if (!this._backup) {
|
||||||
this._error = this._localize("no_backup_found");
|
this._error = this._dialogParams.supervisor?.localize(
|
||||||
|
"backup.no_backup_found"
|
||||||
|
);
|
||||||
} else if (this._dialogParams.onboarding && !this._backup.homeassistant) {
|
} else if (this._dialogParams.onboarding && !this._backup.homeassistant) {
|
||||||
this._error = this._localize("restore_no_home_assistant");
|
this._error = this._dialogParams.supervisor?.localize(
|
||||||
|
"backup.restore_no_home_assistant"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
this._restoringBackup = false;
|
this._restoringBackup = false;
|
||||||
}
|
}
|
||||||
@@ -82,13 +86,6 @@ class HassioBackupDialog
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _localize(key: BackupOrRestoreKey) {
|
|
||||||
return (
|
|
||||||
this._dialogParams!.supervisor?.localize(`backup.${key}`) ||
|
|
||||||
this._dialogParams!.localize!(`ui.panel.page-onboarding.restore.${key}`)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
if (!this._dialogParams || !this._backup) {
|
if (!this._dialogParams || !this._backup) {
|
||||||
return nothing;
|
return nothing;
|
||||||
@@ -102,7 +99,7 @@ class HassioBackupDialog
|
|||||||
<ha-dialog-header slot="headline">
|
<ha-dialog-header slot="headline">
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
slot="navigationIcon"
|
slot="navigationIcon"
|
||||||
.label=${this._localize("close")}
|
.label=${this._dialogParams.supervisor?.localize("backup.close")}
|
||||||
.path=${mdiClose}
|
.path=${mdiClose}
|
||||||
@click=${this.closeDialog}
|
@click=${this.closeDialog}
|
||||||
.disabled=${this._restoringBackup}
|
.disabled=${this._restoringBackup}
|
||||||
@@ -142,7 +139,7 @@ class HassioBackupDialog
|
|||||||
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
||||||
: this._restoringBackup
|
: this._restoringBackup
|
||||||
? html`<div class="loading">
|
? html`<div class="loading">
|
||||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
<ha-spinner></ha-spinner>
|
||||||
</div>`
|
</div>`
|
||||||
: html`
|
: html`
|
||||||
<supervisor-backup-content
|
<supervisor-backup-content
|
||||||
@@ -150,7 +147,6 @@ class HassioBackupDialog
|
|||||||
.supervisor=${this._dialogParams.supervisor}
|
.supervisor=${this._dialogParams.supervisor}
|
||||||
.backup=${this._backup}
|
.backup=${this._backup}
|
||||||
.onboarding=${this._dialogParams.onboarding || false}
|
.onboarding=${this._dialogParams.onboarding || false}
|
||||||
.localize=${this._dialogParams.localize}
|
|
||||||
dialogInitialFocus
|
dialogInitialFocus
|
||||||
>
|
>
|
||||||
</supervisor-backup-content>
|
</supervisor-backup-content>
|
||||||
@@ -161,7 +157,7 @@ class HassioBackupDialog
|
|||||||
.disabled=${this._restoringBackup || !!this._error}
|
.disabled=${this._restoringBackup || !!this._error}
|
||||||
@click=${this._restoreClicked}
|
@click=${this._restoreClicked}
|
||||||
>
|
>
|
||||||
${this._localize("restore")}
|
${this._dialogParams.supervisor?.localize("backup.restore")}
|
||||||
</ha-button>
|
</ha-button>
|
||||||
</div>
|
</div>
|
||||||
</ha-md-dialog>
|
</ha-md-dialog>
|
||||||
@@ -196,18 +192,22 @@ class HassioBackupDialog
|
|||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
!(await showConfirmationDialog(this, {
|
!(await showConfirmationDialog(this, {
|
||||||
title: this._localize(
|
title: supervisor?.localize(
|
||||||
|
`backup.${
|
||||||
this._backup!.type === "full"
|
this._backup!.type === "full"
|
||||||
? "confirm_restore_full_backup_title"
|
? "confirm_restore_full_backup_title"
|
||||||
: "confirm_restore_partial_backup_title"
|
: "confirm_restore_partial_backup_title"
|
||||||
|
}`
|
||||||
),
|
),
|
||||||
text: this._localize(
|
text: supervisor?.localize(
|
||||||
|
`backup.${
|
||||||
this._backup!.type === "full"
|
this._backup!.type === "full"
|
||||||
? "confirm_restore_full_backup_text"
|
? "confirm_restore_full_backup_text"
|
||||||
: "confirm_restore_partial_backup_text"
|
: "confirm_restore_partial_backup_text"
|
||||||
|
}`
|
||||||
),
|
),
|
||||||
confirmText: this._localize("restore"),
|
confirmText: supervisor?.localize("backup.restore"),
|
||||||
dismissText: this._localize("cancel"),
|
dismissText: supervisor?.localize("backup.cancel"),
|
||||||
}))
|
}))
|
||||||
) {
|
) {
|
||||||
this._restoringBackup = false;
|
this._restoringBackup = false;
|
||||||
@@ -227,7 +227,8 @@ class HassioBackupDialog
|
|||||||
this.closeDialog();
|
this.closeDialog();
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
this._error =
|
this._error =
|
||||||
error?.body?.message || this._localize("restore_start_failed");
|
error?.body?.message ||
|
||||||
|
supervisor?.localize("backup.restore_start_failed");
|
||||||
} finally {
|
} finally {
|
||||||
this._restoringBackup = false;
|
this._restoringBackup = false;
|
||||||
}
|
}
|
||||||
@@ -286,7 +287,7 @@ class HassioBackupDialog
|
|||||||
title: supervisor.localize("backup.remote_download_title"),
|
title: supervisor.localize("backup.remote_download_title"),
|
||||||
text: supervisor.localize("backup.remote_download_text"),
|
text: supervisor.localize("backup.remote_download_text"),
|
||||||
confirmText: supervisor.localize("backup.download"),
|
confirmText: supervisor.localize("backup.download"),
|
||||||
dismissText: this._localize("cancel"),
|
dismissText: supervisor?.localize("backup.cancel"),
|
||||||
});
|
});
|
||||||
if (!confirm) {
|
if (!confirm) {
|
||||||
return;
|
return;
|
||||||
@@ -302,7 +303,7 @@ class HassioBackupDialog
|
|||||||
private get _computeName() {
|
private get _computeName() {
|
||||||
return this._backup
|
return this._backup
|
||||||
? this._backup.name || this._backup.slug
|
? this._backup.name || this._backup.slug
|
||||||
: this._localize("unnamed_backup");
|
: this._dialogParams!.supervisor?.localize("backup.unnamed_backup") || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
@@ -310,10 +311,6 @@ class HassioBackupDialog
|
|||||||
haStyle,
|
haStyle,
|
||||||
haStyleDialog,
|
haStyleDialog,
|
||||||
css`
|
css`
|
||||||
ha-circular-progress {
|
|
||||||
display: block;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
ha-header-bar {
|
ha-header-bar {
|
||||||
--mdc-theme-on-primary: var(--primary-text-color);
|
--mdc-theme-on-primary: var(--primary-text-color);
|
||||||
--mdc-theme-primary: var(--mdc-theme-surface);
|
--mdc-theme-primary: var(--mdc-theme-surface);
|
||||||
|
@@ -5,6 +5,7 @@ import { customElement, property, query, 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-alert";
|
import "../../../../src/components/ha-alert";
|
||||||
|
import "../../../../src/components/ha-spinner";
|
||||||
import { createCloseHeading } from "../../../../src/components/ha-dialog";
|
import { createCloseHeading } from "../../../../src/components/ha-dialog";
|
||||||
import {
|
import {
|
||||||
createHassioFullBackup,
|
createHassioFullBackup,
|
||||||
@@ -58,7 +59,7 @@ class HassioCreateBackupDialog extends LitElement {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
${this._creatingBackup
|
${this._creatingBackup
|
||||||
? html`<ha-circular-progress indeterminate></ha-circular-progress>`
|
? html`<ha-spinner></ha-spinner>`
|
||||||
: html`<supervisor-backup-content
|
: html`<supervisor-backup-content
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.supervisor=${this._dialogParams.supervisor}
|
.supervisor=${this._dialogParams.supervisor}
|
||||||
@@ -142,10 +143,6 @@ class HassioCreateBackupDialog extends LitElement {
|
|||||||
:host {
|
:host {
|
||||||
direction: var(--direction);
|
direction: var(--direction);
|
||||||
}
|
}
|
||||||
ha-circular-progress {
|
|
||||||
display: block;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||||
import type { LocalizeFunc } from "../../../../src/common/translations/localize";
|
|
||||||
import type { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
import type { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||||
|
|
||||||
export interface HassioBackupDialogParams {
|
export interface HassioBackupDialogParams {
|
||||||
@@ -8,7 +7,6 @@ export interface HassioBackupDialogParams {
|
|||||||
onRestoring?: () => void;
|
onRestoring?: () => void;
|
||||||
onboarding?: boolean;
|
onboarding?: boolean;
|
||||||
supervisor?: Supervisor;
|
supervisor?: Supervisor;
|
||||||
localize?: LocalizeFunc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const showHassioBackupDialog = (
|
export const showHassioBackupDialog = (
|
||||||
|
@@ -4,7 +4,7 @@ import { css, html, LitElement, nothing } from "lit";
|
|||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
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-spinner";
|
||||||
import "../../../../src/components/ha-select";
|
import "../../../../src/components/ha-select";
|
||||||
import "../../../../src/components/ha-dialog";
|
import "../../../../src/components/ha-dialog";
|
||||||
import {
|
import {
|
||||||
@@ -69,12 +69,7 @@ class HassioDatadiskDialog extends LitElement {
|
|||||||
?hideActions=${this.moving}
|
?hideActions=${this.moving}
|
||||||
>
|
>
|
||||||
${this.moving
|
${this.moving
|
||||||
? html` <ha-circular-progress
|
? html`<ha-spinner aria-label="Moving" size="large"></ha-spinner>
|
||||||
aria-label="Moving"
|
|
||||||
size="large"
|
|
||||||
indeterminate
|
|
||||||
>
|
|
||||||
</ha-circular-progress>
|
|
||||||
<p class="progress-text">
|
<p class="progress-text">
|
||||||
${this.dialogParams.supervisor.localize(
|
${this.dialogParams.supervisor.localize(
|
||||||
"dialog.datadisk_move.moving_desc"
|
"dialog.datadisk_move.moving_desc"
|
||||||
@@ -166,7 +161,7 @@ class HassioDatadiskDialog extends LitElement {
|
|||||||
ha-select {
|
ha-select {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
ha-circular-progress {
|
ha-spinner {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 32px;
|
margin: 32px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@@ -10,7 +10,7 @@ import { customElement, property, state } from "lit/decorators";
|
|||||||
import { cache } from "lit/directives/cache";
|
import { cache } from "lit/directives/cache";
|
||||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||||
import "../../../../src/components/ha-alert";
|
import "../../../../src/components/ha-alert";
|
||||||
import "../../../../src/components/ha-circular-progress";
|
import "../../../../src/components/ha-spinner";
|
||||||
import "../../../../src/components/ha-dialog";
|
import "../../../../src/components/ha-dialog";
|
||||||
import "../../../../src/components/ha-expansion-panel";
|
import "../../../../src/components/ha-expansion-panel";
|
||||||
import "../../../../src/components/ha-formfield";
|
import "../../../../src/components/ha-formfield";
|
||||||
@@ -161,12 +161,8 @@ export class DialogHassioNetwork
|
|||||||
.disabled=${this._scanning}
|
.disabled=${this._scanning}
|
||||||
>
|
>
|
||||||
${this._scanning
|
${this._scanning
|
||||||
? html`<ha-circular-progress
|
? html`<ha-spinner aria-label="Scanning" size="small">
|
||||||
aria-label="Scanning"
|
</ha-spinner>`
|
||||||
indeterminate
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
</ha-circular-progress>`
|
|
||||||
: this.supervisor.localize("dialog.network.scan_ap")}
|
: this.supervisor.localize("dialog.network.scan_ap")}
|
||||||
</mwc-button>
|
</mwc-button>
|
||||||
${this._accessPoints &&
|
${this._accessPoints &&
|
||||||
@@ -282,8 +278,7 @@ export class DialogHassioNetwork
|
|||||||
</mwc-button>
|
</mwc-button>
|
||||||
<mwc-button @click=${this._updateNetwork} .disabled=${!this._dirty}>
|
<mwc-button @click=${this._updateNetwork} .disabled=${!this._dirty}>
|
||||||
${this._processing
|
${this._processing
|
||||||
? html`<ha-circular-progress indeterminate size="small">
|
? html`<ha-spinner size="small"> </ha-spinner>`
|
||||||
</ha-circular-progress>`
|
|
||||||
: this.supervisor.localize("common.save")}
|
: this.supervisor.localize("common.save")}
|
||||||
</mwc-button>
|
</mwc-button>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import "@material/mwc-button/mwc-button";
|
import "@material/mwc-button/mwc-button";
|
||||||
import { mdiDelete, mdiDeleteOff } from "@mdi/js";
|
import { mdiDelete, mdiDeleteOff } from "@mdi/js";
|
||||||
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
|
|
||||||
import type { CSSResultGroup } from "lit";
|
import type { CSSResultGroup } from "lit";
|
||||||
import { css, html, LitElement, nothing } from "lit";
|
import { css, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
@@ -8,7 +7,8 @@ import memoizeOne from "memoize-one";
|
|||||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||||
import { caseInsensitiveStringCompare } from "../../../../src/common/string/compare";
|
import { caseInsensitiveStringCompare } from "../../../../src/common/string/compare";
|
||||||
import "../../../../src/components/ha-alert";
|
import "../../../../src/components/ha-alert";
|
||||||
import "../../../../src/components/ha-circular-progress";
|
import "../../../../src/components/ha-tooltip";
|
||||||
|
import "../../../../src/components/ha-spinner";
|
||||||
import { createCloseHeading } from "../../../../src/components/ha-dialog";
|
import { createCloseHeading } from "../../../../src/components/ha-dialog";
|
||||||
import "../../../../src/components/ha-icon-button";
|
import "../../../../src/components/ha-icon-button";
|
||||||
import type {
|
import type {
|
||||||
@@ -118,7 +118,16 @@ class HassioRepositoriesDialog extends LitElement {
|
|||||||
<div>${repo.maintainer}</div>
|
<div>${repo.maintainer}</div>
|
||||||
<div>${repo.url}</div>
|
<div>${repo.url}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="delete" slot="end">
|
<ha-tooltip
|
||||||
|
class="delete"
|
||||||
|
slot="end"
|
||||||
|
.content=${this._dialogParams!.supervisor.localize(
|
||||||
|
usedRepositories.includes(repo.slug)
|
||||||
|
? "dialog.repositories.used"
|
||||||
|
: "dialog.repositories.remove"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
.disabled=${usedRepositories.includes(repo.slug)}
|
.disabled=${usedRepositories.includes(repo.slug)}
|
||||||
.slug=${repo.slug}
|
.slug=${repo.slug}
|
||||||
@@ -128,18 +137,8 @@ class HassioRepositoriesDialog extends LitElement {
|
|||||||
@click=${this._removeRepository}
|
@click=${this._removeRepository}
|
||||||
>
|
>
|
||||||
</ha-icon-button>
|
</ha-icon-button>
|
||||||
<simple-tooltip
|
|
||||||
animation-delay="0"
|
|
||||||
position="bottom"
|
|
||||||
offset="1"
|
|
||||||
>
|
|
||||||
${this._dialogParams!.supervisor.localize(
|
|
||||||
usedRepositories.includes(repo.slug)
|
|
||||||
? "dialog.repositories.used"
|
|
||||||
: "dialog.repositories.remove"
|
|
||||||
)}
|
|
||||||
</simple-tooltip>
|
|
||||||
</div>
|
</div>
|
||||||
|
</ha-tooltip>
|
||||||
</ha-md-list-item>
|
</ha-md-list-item>
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
@@ -162,10 +161,7 @@ class HassioRepositoriesDialog extends LitElement {
|
|||||||
></ha-textfield>
|
></ha-textfield>
|
||||||
<mwc-button @click=${this._addRepository}>
|
<mwc-button @click=${this._addRepository}>
|
||||||
${this._processing
|
${this._processing
|
||||||
? html`<ha-circular-progress
|
? html`<ha-spinner size="small"></ha-spinner>`
|
||||||
indeterminate
|
|
||||||
size="small"
|
|
||||||
></ha-circular-progress>`
|
|
||||||
: this._dialogParams!.supervisor.localize(
|
: this._dialogParams!.supervisor.localize(
|
||||||
"dialog.repositories.add"
|
"dialog.repositories.add"
|
||||||
)}
|
)}
|
||||||
@@ -203,7 +199,7 @@ class HassioRepositoriesDialog extends LitElement {
|
|||||||
margin-inline-start: 8px;
|
margin-inline-start: 8px;
|
||||||
margin-inline-end: initial;
|
margin-inline-end: initial;
|
||||||
}
|
}
|
||||||
ha-circular-progress {
|
ha-spinner {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 32px;
|
margin: 32px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// Compat needs to be first import
|
|
||||||
import "../../src/resources/compatibility";
|
|
||||||
import "./hassio-main";
|
import "./hassio-main";
|
||||||
|
|
||||||
import("../../src/resources/ha-style");
|
import("../../src/resources/ha-style");
|
||||||
|
@@ -15,6 +15,7 @@ import "../../../src/components/buttons/ha-progress-button";
|
|||||||
import "../../../src/components/ha-alert";
|
import "../../../src/components/ha-alert";
|
||||||
import "../../../src/components/ha-button-menu";
|
import "../../../src/components/ha-button-menu";
|
||||||
import "../../../src/components/ha-card";
|
import "../../../src/components/ha-card";
|
||||||
|
import "../../../src/components/ha-spinner";
|
||||||
import "../../../src/components/ha-checkbox";
|
import "../../../src/components/ha-checkbox";
|
||||||
import "../../../src/components/ha-faded";
|
import "../../../src/components/ha-faded";
|
||||||
import "../../../src/components/ha-icon-button";
|
import "../../../src/components/ha-icon-button";
|
||||||
@@ -192,12 +193,10 @@ class UpdateAvailableCard extends LitElement {
|
|||||||
`
|
`
|
||||||
: nothing}
|
: nothing}
|
||||||
`
|
`
|
||||||
: html`<ha-circular-progress
|
: html`<ha-spinner
|
||||||
aria-label="Updating"
|
aria-label="Updating"
|
||||||
size="large"
|
size="large"
|
||||||
indeterminate
|
></ha-spinner>
|
||||||
>
|
|
||||||
</ha-circular-progress>
|
|
||||||
<p class="progress-text">
|
<p class="progress-text">
|
||||||
${this.supervisor.localize("update_available.updating", {
|
${this.supervisor.localize("update_available.updating", {
|
||||||
name: this._name,
|
name: this._name,
|
||||||
@@ -465,7 +464,7 @@ class UpdateAvailableCard extends LitElement {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
ha-circular-progress {
|
ha-spinner {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 32px;
|
margin: 32px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@@ -1,4 +0,0 @@
|
|||||||
import type { TranslationDict } from "../../../src/types";
|
|
||||||
|
|
||||||
export type BackupOrRestoreKey = keyof TranslationDict["supervisor"]["backup"] &
|
|
||||||
keyof TranslationDict["ui"]["panel"]["page-onboarding"]["restore"];
|
|
@@ -22,6 +22,8 @@ import {
|
|||||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||||
import { fileDownload } from "../../../src/util/file_download";
|
import { fileDownload } from "../../../src/util/file_download";
|
||||||
import { getSupervisorLogs, getSupervisorLogsFollow } from "../data/supervisor";
|
import { getSupervisorLogs, getSupervisorLogsFollow } from "../data/supervisor";
|
||||||
|
import { waitForSeconds } from "../../../src/common/util/wait";
|
||||||
|
import { ASSUME_CORE_START_SECONDS } from "../ha-landing-page";
|
||||||
|
|
||||||
const ERROR_CHECK = /^[\d\s-:]+(ERROR|CRITICAL)(.*)/gm;
|
const ERROR_CHECK = /^[\d\s-:]+(ERROR|CRITICAL)(.*)/gm;
|
||||||
declare global {
|
declare global {
|
||||||
@@ -216,7 +218,7 @@ class LandingPageLogs extends LitElement {
|
|||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|
||||||
// fallback to observerlogs if there is a problem with supervisor
|
// fallback to observer logs if there is a problem with supervisor
|
||||||
this._loadObserverLogs();
|
this._loadObserverLogs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -251,6 +253,9 @@ class LandingPageLogs extends LitElement {
|
|||||||
|
|
||||||
this._scheduleObserverLogs();
|
this._scheduleObserverLogs();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
// wait because there is a moment where landingpage is down and core is not up yet
|
||||||
|
await waitForSeconds(ASSUME_CORE_START_SECONDS);
|
||||||
|
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this._error = true;
|
this._error = true;
|
||||||
|
@@ -1,13 +1,7 @@
|
|||||||
import "@material/mwc-linear-progress/mwc-linear-progress";
|
import "@material/mwc-linear-progress/mwc-linear-progress";
|
||||||
import {
|
import memoizeOne from "memoize-one";
|
||||||
type CSSResultGroup,
|
import { type CSSResultGroup, LitElement, css, html, nothing } from "lit";
|
||||||
LitElement,
|
import { customElement, property } from "lit/decorators";
|
||||||
type PropertyValues,
|
|
||||||
css,
|
|
||||||
html,
|
|
||||||
nothing,
|
|
||||||
} from "lit";
|
|
||||||
import { customElement, property, state } from "lit/decorators";
|
|
||||||
import type {
|
import type {
|
||||||
LandingPageKeys,
|
LandingPageKeys,
|
||||||
LocalizeFunc,
|
LocalizeFunc,
|
||||||
@@ -16,33 +10,24 @@ import "../../../src/components/ha-button";
|
|||||||
import "../../../src/components/ha-alert";
|
import "../../../src/components/ha-alert";
|
||||||
import {
|
import {
|
||||||
ALTERNATIVE_DNS_SERVERS,
|
ALTERNATIVE_DNS_SERVERS,
|
||||||
getSupervisorNetworkInfo,
|
|
||||||
setSupervisorNetworkDns,
|
setSupervisorNetworkDns,
|
||||||
|
type NetworkInfo,
|
||||||
} from "../data/supervisor";
|
} from "../data/supervisor";
|
||||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
|
||||||
import { showAlertDialog } from "../../../src/dialogs/generic/show-dialog-box";
|
import { showAlertDialog } from "../../../src/dialogs/generic/show-dialog-box";
|
||||||
|
import type { NetworkInterface } from "../../../src/data/hassio/network";
|
||||||
const SCHEDULE_FETCH_NETWORK_INFO_SECONDS = 5;
|
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||||
|
|
||||||
@customElement("landing-page-network")
|
@customElement("landing-page-network")
|
||||||
class LandingPageNetwork extends LitElement {
|
class LandingPageNetwork extends LitElement {
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public localize!: LocalizeFunc<LandingPageKeys>;
|
public localize!: LocalizeFunc<LandingPageKeys>;
|
||||||
|
|
||||||
@state() private _networkIssue = false;
|
@property({ attribute: false }) public networkInfo?: NetworkInfo;
|
||||||
|
|
||||||
@state() private _getNetworkInfoError = false;
|
@property({ type: Boolean }) public error = false;
|
||||||
|
|
||||||
@state() private _dnsPrimaryInterfaceNameservers?: string;
|
|
||||||
|
|
||||||
@state() private _dnsPrimaryInterface?: string;
|
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
if (!this._networkIssue && !this._getNetworkInfoError) {
|
if (this.error) {
|
||||||
return nothing;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._getNetworkInfoError) {
|
|
||||||
return html`
|
return html`
|
||||||
<ha-alert alert-type="error">
|
<ha-alert alert-type="error">
|
||||||
<p>${this.localize("network_issue.error_get_network_info")}</p>
|
<p>${this.localize("network_issue.error_get_network_info")}</p>
|
||||||
@@ -50,6 +35,16 @@ class LandingPageNetwork extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let dnsPrimaryInterfaceNameservers: string | undefined;
|
||||||
|
|
||||||
|
const primaryInterface = this._getPrimaryInterface(
|
||||||
|
this.networkInfo?.interfaces
|
||||||
|
);
|
||||||
|
if (primaryInterface) {
|
||||||
|
dnsPrimaryInterfaceNameservers =
|
||||||
|
this._getPrimaryNameservers(primaryInterface);
|
||||||
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-alert
|
<ha-alert
|
||||||
alert-type="warning"
|
alert-type="warning"
|
||||||
@@ -57,11 +52,11 @@ class LandingPageNetwork extends LitElement {
|
|||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
${this.localize("network_issue.description", {
|
${this.localize("network_issue.description", {
|
||||||
dns: this._dnsPrimaryInterfaceNameservers || "?",
|
dns: dnsPrimaryInterfaceNameservers || "?",
|
||||||
})}
|
})}
|
||||||
</p>
|
</p>
|
||||||
<p>${this.localize("network_issue.resolve_different")}</p>
|
<p>${this.localize("network_issue.resolve_different")}</p>
|
||||||
${!this._dnsPrimaryInterfaceNameservers
|
${!dnsPrimaryInterfaceNameservers
|
||||||
? html`
|
? html`
|
||||||
<p>
|
<p>
|
||||||
<b>${this.localize("network_issue.no_primary_interface")} </b>
|
<b>${this.localize("network_issue.no_primary_interface")} </b>
|
||||||
@@ -73,7 +68,7 @@ class LandingPageNetwork extends LitElement {
|
|||||||
({ translationKey }, key) =>
|
({ translationKey }, key) =>
|
||||||
html`<ha-button
|
html`<ha-button
|
||||||
.index=${key}
|
.index=${key}
|
||||||
.disabled=${!this._dnsPrimaryInterfaceNameservers}
|
.disabled=${!dnsPrimaryInterfaceNameservers}
|
||||||
@click=${this._setDns}
|
@click=${this._setDns}
|
||||||
>${this.localize(translationKey)}</ha-button
|
>${this.localize(translationKey)}</ha-button
|
||||||
>`
|
>`
|
||||||
@@ -83,76 +78,40 @@ class LandingPageNetwork extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(_changedProperties: PropertyValues): void {
|
private _getPrimaryInterface = memoizeOne((interfaces?: NetworkInterface[]) =>
|
||||||
super.firstUpdated(_changedProperties);
|
interfaces?.find((intf) => intf.primary && intf.enabled)
|
||||||
this._fetchSupervisorInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
private _scheduleFetchSupervisorInfo() {
|
|
||||||
setTimeout(
|
|
||||||
() => this._fetchSupervisorInfo(),
|
|
||||||
SCHEDULE_FETCH_NETWORK_INFO_SECONDS * 1000
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
private async _fetchSupervisorInfo() {
|
private _getPrimaryNameservers = memoizeOne(
|
||||||
let data;
|
(primaryInterface: NetworkInterface) =>
|
||||||
try {
|
[
|
||||||
const response = await getSupervisorNetworkInfo();
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Failed to fetch network info");
|
|
||||||
}
|
|
||||||
|
|
||||||
({ data } = await response.json());
|
|
||||||
} catch (err) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error(err);
|
|
||||||
this._getNetworkInfoError = true;
|
|
||||||
this._dnsPrimaryInterfaceNameservers = undefined;
|
|
||||||
this._dnsPrimaryInterface = undefined;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._getNetworkInfoError = false;
|
|
||||||
|
|
||||||
const primaryInterface = data.interfaces.find(
|
|
||||||
(intf) => intf.primary && intf.enabled
|
|
||||||
);
|
|
||||||
if (primaryInterface) {
|
|
||||||
this._dnsPrimaryInterfaceNameservers = [
|
|
||||||
...(primaryInterface.ipv4?.nameservers || []),
|
...(primaryInterface.ipv4?.nameservers || []),
|
||||||
...(primaryInterface.ipv6?.nameservers || []),
|
...(primaryInterface.ipv6?.nameservers || []),
|
||||||
].join(", ");
|
].join(", ")
|
||||||
|
);
|
||||||
this._dnsPrimaryInterface = primaryInterface.interface;
|
|
||||||
} else {
|
|
||||||
this._dnsPrimaryInterfaceNameservers = undefined;
|
|
||||||
this._dnsPrimaryInterface = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!data.host_internet) {
|
|
||||||
this._networkIssue = true;
|
|
||||||
} else {
|
|
||||||
this._networkIssue = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fireEvent(this, "value-changed", {
|
|
||||||
value: this._networkIssue,
|
|
||||||
});
|
|
||||||
this._scheduleFetchSupervisorInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _setDns(ev) {
|
private async _setDns(ev) {
|
||||||
|
const primaryInterface = this._getPrimaryInterface(
|
||||||
|
this.networkInfo?.interfaces
|
||||||
|
);
|
||||||
|
|
||||||
const index = ev.target?.index;
|
const index = ev.target?.index;
|
||||||
try {
|
try {
|
||||||
|
const dnsPrimaryInterface = primaryInterface?.interface;
|
||||||
|
if (!dnsPrimaryInterface) {
|
||||||
|
throw new Error("No primary interface found");
|
||||||
|
}
|
||||||
|
|
||||||
const response = await setSupervisorNetworkDns(
|
const response = await setSupervisorNetworkDns(
|
||||||
index,
|
index,
|
||||||
this._dnsPrimaryInterface!
|
dnsPrimaryInterface
|
||||||
);
|
);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error("Failed to set DNS");
|
throw new Error("Failed to set DNS");
|
||||||
}
|
}
|
||||||
this._networkIssue = false;
|
|
||||||
|
// notify landing page to trigger a network info reload
|
||||||
|
fireEvent(this, "dns-set");
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error(err);
|
console.error(err);
|
||||||
@@ -183,4 +142,7 @@ declare global {
|
|||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
"landing-page-network": LandingPageNetwork;
|
"landing-page-network": LandingPageNetwork;
|
||||||
}
|
}
|
||||||
|
interface HASSDomEvents {
|
||||||
|
"dns-set": undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,17 @@
|
|||||||
import type { LandingPageKeys } from "../../../src/common/translations/localize";
|
import type { LandingPageKeys } from "../../../src/common/translations/localize";
|
||||||
|
import type { HassioResponse } from "../../../src/data/hassio/common";
|
||||||
|
import type {
|
||||||
|
DockerNetwork,
|
||||||
|
NetworkInterface,
|
||||||
|
} from "../../../src/data/hassio/network";
|
||||||
|
import { handleFetchPromise } from "../../../src/util/hass-call-api";
|
||||||
|
|
||||||
|
export interface NetworkInfo {
|
||||||
|
interfaces: NetworkInterface[];
|
||||||
|
docker: DockerNetwork;
|
||||||
|
host_internet: boolean;
|
||||||
|
supervisor_internet: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export const ALTERNATIVE_DNS_SERVERS: {
|
export const ALTERNATIVE_DNS_SERVERS: {
|
||||||
ipv4: string[];
|
ipv4: string[];
|
||||||
@@ -18,7 +31,7 @@ export const ALTERNATIVE_DNS_SERVERS: {
|
|||||||
];
|
];
|
||||||
|
|
||||||
export async function getSupervisorLogs(lines = 100) {
|
export async function getSupervisorLogs(lines = 100) {
|
||||||
return fetch(`/supervisor/supervisor/logs?lines=${lines}`, {
|
return fetch(`/supervisor-api/supervisor/logs?lines=${lines}`, {
|
||||||
headers: {
|
headers: {
|
||||||
Accept: "text/plain",
|
Accept: "text/plain",
|
||||||
},
|
},
|
||||||
@@ -26,22 +39,29 @@ export async function getSupervisorLogs(lines = 100) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getSupervisorLogsFollow(lines = 500) {
|
export async function getSupervisorLogsFollow(lines = 500) {
|
||||||
return fetch(`/supervisor/supervisor/logs/follow?lines=${lines}`, {
|
return fetch(`/supervisor-api/supervisor/logs/follow?lines=${lines}`, {
|
||||||
headers: {
|
headers: {
|
||||||
Accept: "text/plain",
|
Accept: "text/plain",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getSupervisorNetworkInfo() {
|
export async function pingSupervisor() {
|
||||||
return fetch("/supervisor/network/info");
|
return fetch("/supervisor-api/supervisor/ping");
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getSupervisorNetworkInfo(): Promise<NetworkInfo> {
|
||||||
|
const responseData = await handleFetchPromise<HassioResponse<NetworkInfo>>(
|
||||||
|
fetch("/supervisor-api/network/info")
|
||||||
|
);
|
||||||
|
return responseData?.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const setSupervisorNetworkDns = async (
|
export const setSupervisorNetworkDns = async (
|
||||||
dnsServerIndex: number,
|
dnsServerIndex: number,
|
||||||
primaryInterface: string
|
primaryInterface: string
|
||||||
) =>
|
) =>
|
||||||
fetch(`/supervisor/network/interface/${primaryInterface}/update`, {
|
fetch(`/supervisor-api/network/interface/${primaryInterface}/update`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
ipv4: {
|
ipv4: {
|
||||||
|
@@ -10,36 +10,56 @@ import { extractSearchParam } from "../../src/common/url/search-params";
|
|||||||
import { onBoardingStyles } from "../../src/onboarding/styles";
|
import { onBoardingStyles } from "../../src/onboarding/styles";
|
||||||
import { makeDialogManager } from "../../src/dialogs/make-dialog-manager";
|
import { makeDialogManager } from "../../src/dialogs/make-dialog-manager";
|
||||||
import { LandingPageBaseElement } from "./landing-page-base-element";
|
import { LandingPageBaseElement } from "./landing-page-base-element";
|
||||||
|
import {
|
||||||
|
getSupervisorNetworkInfo,
|
||||||
|
pingSupervisor,
|
||||||
|
type NetworkInfo,
|
||||||
|
} from "./data/supervisor";
|
||||||
|
|
||||||
const SCHEDULE_CORE_CHECK_SECONDS = 5;
|
export const ASSUME_CORE_START_SECONDS = 60;
|
||||||
|
const SCHEDULE_CORE_CHECK_SECONDS = 1;
|
||||||
|
const SCHEDULE_FETCH_NETWORK_INFO_SECONDS = 5;
|
||||||
|
|
||||||
@customElement("ha-landing-page")
|
@customElement("ha-landing-page")
|
||||||
class HaLandingPage extends LandingPageBaseElement {
|
class HaLandingPage extends LandingPageBaseElement {
|
||||||
@property({ attribute: false }) public translationFragment = "landing-page";
|
@property({ attribute: false }) public translationFragment = "landing-page";
|
||||||
|
|
||||||
@state() private _networkIssue = false;
|
|
||||||
|
|
||||||
@state() private _supervisorError = false;
|
@state() private _supervisorError = false;
|
||||||
|
|
||||||
|
@state() private _networkInfo?: NetworkInfo;
|
||||||
|
|
||||||
|
@state() private _coreStatusChecked = false;
|
||||||
|
|
||||||
|
@state() private _networkInfoError = false;
|
||||||
|
|
||||||
|
@state() private _coreCheckActive = false;
|
||||||
|
|
||||||
private _mobileApp =
|
private _mobileApp =
|
||||||
extractSearchParam("redirect_uri") === "homeassistant://auth-callback";
|
extractSearchParam("redirect_uri") === "homeassistant://auth-callback";
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const networkIssue = this._networkInfo && !this._networkInfo.host_internet;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-card>
|
<ha-card>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<h1>${this.localize("header")}</h1>
|
<h1>${this.localize("header")}</h1>
|
||||||
${!this._networkIssue && !this._supervisorError
|
${!networkIssue && !this._supervisorError
|
||||||
? html`
|
? html`
|
||||||
<p>${this.localize("subheader")}</p>
|
<p>${this.localize("subheader")}</p>
|
||||||
<mwc-linear-progress indeterminate></mwc-linear-progress>
|
<mwc-linear-progress indeterminate></mwc-linear-progress>
|
||||||
`
|
`
|
||||||
: nothing}
|
: nothing}
|
||||||
|
${networkIssue || this._networkInfoError
|
||||||
|
? html`
|
||||||
<landing-page-network
|
<landing-page-network
|
||||||
@value-changed=${this._networkInfoChanged}
|
|
||||||
.localize=${this.localize}
|
.localize=${this.localize}
|
||||||
|
.networkInfo=${this._networkInfo}
|
||||||
|
.error=${this._networkInfoError}
|
||||||
|
@dns-set=${this._fetchSupervisorInfo}
|
||||||
></landing-page-network>
|
></landing-page-network>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
${this._supervisorError
|
${this._supervisorError
|
||||||
? html`
|
? html`
|
||||||
<ha-alert
|
<ha-alert
|
||||||
@@ -88,24 +108,66 @@ class HaLandingPage extends LandingPageBaseElement {
|
|||||||
}
|
}
|
||||||
import("../../src/components/ha-language-picker");
|
import("../../src/components/ha-language-picker");
|
||||||
|
|
||||||
this._scheduleCoreCheck();
|
this._fetchSupervisorInfo(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _scheduleCoreCheck() {
|
private _scheduleFetchSupervisorInfo() {
|
||||||
setTimeout(
|
setTimeout(
|
||||||
() => this._checkCoreAvailability(),
|
() => this._fetchSupervisorInfo(true),
|
||||||
SCHEDULE_CORE_CHECK_SECONDS * 1000
|
// on assumed core start check every second, otherwise every 5 seconds
|
||||||
|
(this._coreCheckActive
|
||||||
|
? SCHEDULE_CORE_CHECK_SECONDS
|
||||||
|
: SCHEDULE_FETCH_NETWORK_INFO_SECONDS) * 1000
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _scheduleTurnOffCoreCheck() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this._coreCheckActive = false;
|
||||||
|
}, ASSUME_CORE_START_SECONDS * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _fetchSupervisorInfo(schedule = false) {
|
||||||
|
try {
|
||||||
|
const response = await pingSupervisor();
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("ping-failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
this._networkInfo = await getSupervisorNetworkInfo();
|
||||||
|
this._networkInfoError = false;
|
||||||
|
this._coreStatusChecked = false;
|
||||||
|
} catch (err: any) {
|
||||||
|
if (!this._coreStatusChecked) {
|
||||||
|
// wait before show errors, because we assume that core is starting
|
||||||
|
this._coreCheckActive = true;
|
||||||
|
this._scheduleTurnOffCoreCheck();
|
||||||
|
}
|
||||||
|
await this._checkCoreAvailability();
|
||||||
|
|
||||||
|
// assume supervisor update if ping fails -> don't show an error
|
||||||
|
if (!this._coreCheckActive && err.message !== "ping-failed") {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(err);
|
||||||
|
this._networkInfoError = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schedule) {
|
||||||
|
this._scheduleFetchSupervisorInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async _checkCoreAvailability() {
|
private async _checkCoreAvailability() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch("/manifest.json");
|
const response = await fetch("/manifest.json");
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
location.reload();
|
location.reload();
|
||||||
|
} else {
|
||||||
|
throw new Error("Failed to fetch manifest");
|
||||||
}
|
}
|
||||||
} finally {
|
} catch (_err) {
|
||||||
this._scheduleCoreCheck();
|
this._coreStatusChecked = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,10 +175,6 @@ class HaLandingPage extends LandingPageBaseElement {
|
|||||||
this._supervisorError = true;
|
this._supervisorError = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _networkInfoChanged(ev: CustomEvent) {
|
|
||||||
this._networkIssue = ev.detail.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _languageChanged(ev: CustomEvent) {
|
private _languageChanged(ev: CustomEvent) {
|
||||||
const language = ev.detail.value;
|
const language = ev.detail.value;
|
||||||
if (language !== this.language && language) {
|
if (language !== this.language && language) {
|
||||||
|
129
package.json
@@ -26,25 +26,25 @@
|
|||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "7.26.7",
|
"@babel/runtime": "7.26.10",
|
||||||
"@braintree/sanitize-url": "7.1.1",
|
"@braintree/sanitize-url": "7.1.1",
|
||||||
"@codemirror/autocomplete": "6.18.4",
|
"@codemirror/autocomplete": "6.18.6",
|
||||||
"@codemirror/commands": "6.8.0",
|
"@codemirror/commands": "6.8.0",
|
||||||
"@codemirror/language": "6.10.8",
|
"@codemirror/language": "6.11.0",
|
||||||
"@codemirror/legacy-modes": "6.4.2",
|
"@codemirror/legacy-modes": "6.5.0",
|
||||||
"@codemirror/search": "6.5.8",
|
"@codemirror/search": "6.5.10",
|
||||||
"@codemirror/state": "6.5.1",
|
"@codemirror/state": "6.5.2",
|
||||||
"@codemirror/view": "6.36.2",
|
"@codemirror/view": "6.36.4",
|
||||||
"@egjs/hammerjs": "2.0.17",
|
"@egjs/hammerjs": "2.0.17",
|
||||||
"@formatjs/intl-datetimeformat": "6.17.2",
|
"@formatjs/intl-datetimeformat": "6.17.4",
|
||||||
"@formatjs/intl-displaynames": "6.8.9",
|
"@formatjs/intl-displaynames": "6.8.11",
|
||||||
"@formatjs/intl-durationformat": "0.7.2",
|
"@formatjs/intl-durationformat": "0.7.4",
|
||||||
"@formatjs/intl-getcanonicallocales": "2.5.4",
|
"@formatjs/intl-getcanonicallocales": "2.5.5",
|
||||||
"@formatjs/intl-listformat": "7.7.9",
|
"@formatjs/intl-listformat": "7.7.11",
|
||||||
"@formatjs/intl-locale": "4.2.9",
|
"@formatjs/intl-locale": "4.2.11",
|
||||||
"@formatjs/intl-numberformat": "8.15.2",
|
"@formatjs/intl-numberformat": "8.15.4",
|
||||||
"@formatjs/intl-pluralrules": "5.4.2",
|
"@formatjs/intl-pluralrules": "5.4.4",
|
||||||
"@formatjs/intl-relativetimeformat": "11.4.9",
|
"@formatjs/intl-relativetimeformat": "11.4.11",
|
||||||
"@fullcalendar/core": "6.1.15",
|
"@fullcalendar/core": "6.1.15",
|
||||||
"@fullcalendar/daygrid": "6.1.15",
|
"@fullcalendar/daygrid": "6.1.15",
|
||||||
"@fullcalendar/interaction": "6.1.15",
|
"@fullcalendar/interaction": "6.1.15",
|
||||||
@@ -53,10 +53,9 @@
|
|||||||
"@fullcalendar/timegrid": "6.1.15",
|
"@fullcalendar/timegrid": "6.1.15",
|
||||||
"@lezer/highlight": "1.2.1",
|
"@lezer/highlight": "1.2.1",
|
||||||
"@lit-labs/context": "0.4.1",
|
"@lit-labs/context": "0.4.1",
|
||||||
"@lit-labs/motion": "1.0.7",
|
"@lit-labs/motion": "1.0.8",
|
||||||
"@lit-labs/observers": "2.0.4",
|
"@lit-labs/observers": "2.0.5",
|
||||||
"@lit-labs/virtualizer": "2.0.15",
|
"@lit-labs/virtualizer": "2.1.0",
|
||||||
"@lrnwebcomponents/simple-tooltip": "8.0.2",
|
|
||||||
"@material/chips": "=14.0.0-canary.53b3cad2f.0",
|
"@material/chips": "=14.0.0-canary.53b3cad2f.0",
|
||||||
"@material/data-table": "=14.0.0-canary.53b3cad2f.0",
|
"@material/data-table": "=14.0.0-canary.53b3cad2f.0",
|
||||||
"@material/mwc-base": "0.27.0",
|
"@material/mwc-base": "0.27.0",
|
||||||
@@ -90,18 +89,21 @@
|
|||||||
"@polymer/paper-tabs": "3.1.0",
|
"@polymer/paper-tabs": "3.1.0",
|
||||||
"@polymer/polymer": "3.5.2",
|
"@polymer/polymer": "3.5.2",
|
||||||
"@replit/codemirror-indentation-markers": "6.5.3",
|
"@replit/codemirror-indentation-markers": "6.5.3",
|
||||||
|
"@shoelace-style/shoelace": "2.20.1",
|
||||||
"@thomasloven/round-slider": "0.6.0",
|
"@thomasloven/round-slider": "0.6.0",
|
||||||
"@vaadin/combo-box": "24.6.2",
|
"@tsparticles/engine": "3.8.1",
|
||||||
"@vaadin/vaadin-themable-mixin": "24.6.2",
|
"@tsparticles/preset-links": "3.2.0",
|
||||||
|
"@vaadin/combo-box": "24.7.1",
|
||||||
|
"@vaadin/vaadin-themable-mixin": "24.7.1",
|
||||||
"@vibrant/color": "4.0.0",
|
"@vibrant/color": "4.0.0",
|
||||||
"@vue/web-component-wrapper": "1.3.0",
|
"@vue/web-component-wrapper": "1.3.0",
|
||||||
"@webcomponents/scoped-custom-element-registry": "0.0.9",
|
"@webcomponents/scoped-custom-element-registry": "0.0.10",
|
||||||
"@webcomponents/webcomponentsjs": "2.8.0",
|
"@webcomponents/webcomponentsjs": "2.8.0",
|
||||||
"app-datepicker": "5.1.1",
|
"app-datepicker": "5.1.1",
|
||||||
"barcode-detector": "2.3.1",
|
"barcode-detector": "3.0.1",
|
||||||
"color-name": "2.0.0",
|
"color-name": "2.0.0",
|
||||||
"comlink": "4.4.2",
|
"comlink": "4.4.2",
|
||||||
"core-js": "3.40.0",
|
"core-js": "3.41.0",
|
||||||
"cropperjs": "1.6.2",
|
"cropperjs": "1.6.2",
|
||||||
"date-fns": "4.1.0",
|
"date-fns": "4.1.0",
|
||||||
"date-fns-tz": "3.2.0",
|
"date-fns-tz": "3.2.0",
|
||||||
@@ -109,23 +111,25 @@
|
|||||||
"deep-freeze": "0.0.1",
|
"deep-freeze": "0.0.1",
|
||||||
"dialog-polyfill": "0.5.6",
|
"dialog-polyfill": "0.5.6",
|
||||||
"echarts": "5.6.0",
|
"echarts": "5.6.0",
|
||||||
"element-internals-polyfill": "1.3.13",
|
"element-internals-polyfill": "3.0.1",
|
||||||
"fuse.js": "7.0.0",
|
"fuse.js": "7.1.0",
|
||||||
"google-timezones-json": "1.2.0",
|
"google-timezones-json": "1.2.0",
|
||||||
"gulp-zopfli-green": "6.0.2",
|
"gulp-zopfli-green": "6.0.2",
|
||||||
"hls.js": "patch:hls.js@npm%3A1.5.7#~/.yarn/patches/hls.js-npm-1.5.7-f5bbd3d060.patch",
|
"hls.js": "patch:hls.js@npm%3A1.5.7#~/.yarn/patches/hls.js-npm-1.5.7-f5bbd3d060.patch",
|
||||||
"home-assistant-js-websocket": "9.4.0",
|
"home-assistant-js-websocket": "9.4.0",
|
||||||
"idb-keyval": "6.2.1",
|
"idb-keyval": "6.2.1",
|
||||||
"intl-messageformat": "10.7.14",
|
"intl-messageformat": "10.7.16",
|
||||||
"js-yaml": "4.1.0",
|
"js-yaml": "4.1.0",
|
||||||
"leaflet": "1.9.4",
|
"leaflet": "1.9.4",
|
||||||
"leaflet-draw": "patch:leaflet-draw@npm%3A1.0.4#./.yarn/patches/leaflet-draw-npm-1.0.4-0ca0ebcf65.patch",
|
"leaflet-draw": "patch:leaflet-draw@npm%3A1.0.4#./.yarn/patches/leaflet-draw-npm-1.0.4-0ca0ebcf65.patch",
|
||||||
|
"leaflet.markercluster": "1.5.3",
|
||||||
"lit": "2.8.0",
|
"lit": "2.8.0",
|
||||||
"lit-html": "2.8.0",
|
"lit-html": "2.8.0",
|
||||||
"luxon": "3.5.0",
|
"luxon": "3.5.0",
|
||||||
"marked": "15.0.6",
|
"marked": "15.0.7",
|
||||||
"memoize-one": "6.0.0",
|
"memoize-one": "6.0.0",
|
||||||
"node-vibrant": "4.0.3",
|
"node-vibrant": "4.0.3",
|
||||||
|
"object-hash": "3.0.0",
|
||||||
"punycode": "2.3.1",
|
"punycode": "2.3.1",
|
||||||
"qr-scanner": "1.4.2",
|
"qr-scanner": "1.4.2",
|
||||||
"qrcode": "1.5.4",
|
"qrcode": "1.5.4",
|
||||||
@@ -135,9 +139,7 @@
|
|||||||
"stacktrace-js": "2.0.2",
|
"stacktrace-js": "2.0.2",
|
||||||
"superstruct": "2.0.2",
|
"superstruct": "2.0.2",
|
||||||
"tinykeys": "3.0.0",
|
"tinykeys": "3.0.0",
|
||||||
"tsparticles-engine": "2.12.0",
|
"ua-parser-js": "2.0.3",
|
||||||
"tsparticles-preset-links": "2.12.0",
|
|
||||||
"ua-parser-js": "2.0.0",
|
|
||||||
"vis-data": "7.1.9",
|
"vis-data": "7.1.9",
|
||||||
"vis-network": "9.1.9",
|
"vis-network": "9.1.9",
|
||||||
"vue": "2.7.16",
|
"vue": "2.7.16",
|
||||||
@@ -152,29 +154,30 @@
|
|||||||
"xss": "1.0.15"
|
"xss": "1.0.15"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.26.7",
|
"@babel/core": "7.26.10",
|
||||||
"@babel/helper-define-polyfill-provider": "0.6.3",
|
"@babel/helper-define-polyfill-provider": "0.6.4",
|
||||||
"@babel/plugin-proposal-decorators": "7.25.9",
|
"@babel/plugin-proposal-decorators": "7.25.9",
|
||||||
"@babel/plugin-transform-runtime": "7.25.9",
|
"@babel/plugin-transform-runtime": "7.26.10",
|
||||||
"@babel/preset-env": "7.26.7",
|
"@babel/preset-env": "7.26.9",
|
||||||
"@babel/preset-typescript": "7.26.0",
|
"@babel/preset-typescript": "7.26.0",
|
||||||
"@bundle-stats/plugin-webpack-filter": "4.18.2",
|
"@bundle-stats/plugin-webpack-filter": "4.19.1",
|
||||||
"@lokalise/node-api": "13.0.0",
|
"@lokalise/node-api": "14.2.0",
|
||||||
"@octokit/auth-oauth-device": "7.1.2",
|
"@octokit/auth-oauth-device": "7.1.4",
|
||||||
"@octokit/plugin-retry": "7.1.3",
|
"@octokit/plugin-retry": "7.2.0",
|
||||||
"@octokit/rest": "21.1.0",
|
"@octokit/rest": "21.1.1",
|
||||||
"@rsdoctor/rspack-plugin": "0.4.13",
|
"@rsdoctor/rspack-plugin": "1.0.0",
|
||||||
"@rspack/cli": "1.2.2",
|
"@rspack/cli": "1.2.8",
|
||||||
"@rspack/core": "1.2.2",
|
"@rspack/core": "1.2.8",
|
||||||
"@types/babel__plugin-transform-runtime": "7.9.5",
|
"@types/babel__plugin-transform-runtime": "7.9.5",
|
||||||
"@types/chromecast-caf-receiver": "6.0.20",
|
"@types/chromecast-caf-receiver": "6.0.21",
|
||||||
"@types/chromecast-caf-sender": "1.0.11",
|
"@types/chromecast-caf-sender": "1.0.11",
|
||||||
"@types/color-name": "2.0.0",
|
"@types/color-name": "2.0.0",
|
||||||
"@types/glob": "8.1.0",
|
"@types/glob": "8.1.0",
|
||||||
"@types/html-minifier-terser": "7.0.2",
|
"@types/html-minifier-terser": "7.0.2",
|
||||||
"@types/js-yaml": "4.0.9",
|
"@types/js-yaml": "4.0.9",
|
||||||
"@types/leaflet": "1.9.16",
|
"@types/leaflet": "1.9.17",
|
||||||
"@types/leaflet-draw": "1.0.11",
|
"@types/leaflet-draw": "1.0.11",
|
||||||
|
"@types/leaflet.markercluster": "1.5.5",
|
||||||
"@types/lodash.merge": "4.6.9",
|
"@types/lodash.merge": "4.6.9",
|
||||||
"@types/luxon": "3.4.2",
|
"@types/luxon": "3.4.2",
|
||||||
"@types/mocha": "10.0.10",
|
"@types/mocha": "10.0.10",
|
||||||
@@ -183,22 +186,20 @@
|
|||||||
"@types/tar": "6.1.13",
|
"@types/tar": "6.1.13",
|
||||||
"@types/ua-parser-js": "0.7.39",
|
"@types/ua-parser-js": "0.7.39",
|
||||||
"@types/webspeechapi": "0.0.29",
|
"@types/webspeechapi": "0.0.29",
|
||||||
"@typescript-eslint/eslint-plugin": "8.21.0",
|
"@vitest/coverage-v8": "3.0.9",
|
||||||
"@typescript-eslint/parser": "8.21.0",
|
"babel-loader": "10.0.0",
|
||||||
"@vitest/coverage-v8": "3.0.4",
|
|
||||||
"babel-loader": "9.2.1",
|
|
||||||
"babel-plugin-template-html-minifier": "4.1.0",
|
"babel-plugin-template-html-minifier": "4.1.0",
|
||||||
"browserslist-useragent-regexp": "4.1.3",
|
"browserslist-useragent-regexp": "4.1.3",
|
||||||
"del": "8.0.0",
|
"del": "8.0.0",
|
||||||
"eslint": "9.19.0",
|
"eslint": "9.23.0",
|
||||||
"eslint-config-airbnb-base": "15.0.0",
|
"eslint-config-airbnb-base": "15.0.0",
|
||||||
"eslint-config-prettier": "10.0.1",
|
"eslint-config-prettier": "10.1.1",
|
||||||
"eslint-import-resolver-webpack": "0.13.10",
|
"eslint-import-resolver-webpack": "0.13.10",
|
||||||
"eslint-plugin-import": "2.31.0",
|
"eslint-plugin-import": "2.31.0",
|
||||||
"eslint-plugin-lit": "1.15.0",
|
"eslint-plugin-lit": "2.0.0",
|
||||||
"eslint-plugin-lit-a11y": "4.1.4",
|
"eslint-plugin-lit-a11y": "4.1.4",
|
||||||
"eslint-plugin-unused-imports": "4.1.4",
|
"eslint-plugin-unused-imports": "4.1.4",
|
||||||
"eslint-plugin-wc": "2.2.0",
|
"eslint-plugin-wc": "3.0.0",
|
||||||
"fancy-log": "2.0.0",
|
"fancy-log": "2.0.0",
|
||||||
"fs-extra": "11.3.0",
|
"fs-extra": "11.3.0",
|
||||||
"glob": "11.0.1",
|
"glob": "11.0.1",
|
||||||
@@ -210,21 +211,23 @@
|
|||||||
"husky": "9.1.7",
|
"husky": "9.1.7",
|
||||||
"jsdom": "26.0.0",
|
"jsdom": "26.0.0",
|
||||||
"jszip": "3.10.1",
|
"jszip": "3.10.1",
|
||||||
"lint-staged": "15.4.3",
|
"lint-staged": "15.5.0",
|
||||||
"lit-analyzer": "2.0.3",
|
"lit-analyzer": "2.0.3",
|
||||||
"lodash.merge": "4.6.2",
|
"lodash.merge": "4.6.2",
|
||||||
"lodash.template": "4.5.0",
|
"lodash.template": "4.5.0",
|
||||||
"map-stream": "0.0.7",
|
"map-stream": "0.0.7",
|
||||||
"object-hash": "3.0.0",
|
|
||||||
"pinst": "3.0.0",
|
"pinst": "3.0.0",
|
||||||
"prettier": "3.4.2",
|
"prettier": "3.5.3",
|
||||||
"rspack-manifest-plugin": "5.0.3",
|
"rspack-manifest-plugin": "5.0.3",
|
||||||
"sinon": "19.0.2",
|
"serve": "14.2.4",
|
||||||
|
"sinon": "19.0.4",
|
||||||
"tar": "7.4.3",
|
"tar": "7.4.3",
|
||||||
"terser-webpack-plugin": "5.3.11",
|
"terser-webpack-plugin": "5.3.14",
|
||||||
"ts-lit-plugin": "2.0.2",
|
"ts-lit-plugin": "2.0.2",
|
||||||
"typescript": "5.7.3",
|
"typescript": "5.8.2",
|
||||||
"vitest": "3.0.4",
|
"typescript-eslint": "8.27.0",
|
||||||
|
"vite-tsconfig-paths": "5.1.4",
|
||||||
|
"vitest": "3.0.9",
|
||||||
"webpack-stats-plugin": "1.1.3",
|
"webpack-stats-plugin": "1.1.3",
|
||||||
"webpackbar": "7.0.0",
|
"webpackbar": "7.0.0",
|
||||||
"workbox-build": "patch:workbox-build@npm%3A7.1.1#~/.yarn/patches/workbox-build-npm-7.1.1-a854f3faae.patch"
|
"workbox-build": "patch:workbox-build@npm%3A7.1.1#~/.yarn/patches/workbox-build-npm-7.1.1-a854f3faae.patch"
|
||||||
@@ -238,8 +241,8 @@
|
|||||||
"clean-css": "5.3.3",
|
"clean-css": "5.3.3",
|
||||||
"@lit/reactive-element": "1.6.3",
|
"@lit/reactive-element": "1.6.3",
|
||||||
"@fullcalendar/daygrid": "6.1.15",
|
"@fullcalendar/daygrid": "6.1.15",
|
||||||
"globals": "15.14.0",
|
"globals": "16.0.0",
|
||||||
"tslib": "2.8.1"
|
"tslib": "2.8.1"
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@4.6.0"
|
"packageManager": "yarn@4.7.0"
|
||||||
}
|
}
|
||||||
|
10
public/static/images/form/markdown_card.svg
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<svg width="94" height="64" viewBox="0 0 94 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="64" rx="8" fill="white"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="63" rx="7.5" stroke="black" stroke-opacity="0.12"/>
|
||||||
|
<path d="M8 14C8 10.6863 10.6863 8 14 8H33C36.3137 8 39 10.6863 39 14C39 17.3137 36.3137 20 33 20H14C10.6863 20 8 17.3137 8 14Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M8 27C8 25.3431 9.34315 24 11 24H31C32.6569 24 34 25.3431 34 27V29C34 30.6569 32.6569 32 31 32H11C9.34315 32 8 30.6569 8 29V27Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M38 27C38 25.3431 39.3431 24 41 24H83C84.6569 24 86 25.3431 86 27V29C86 30.6569 84.6569 32 83 32H41C39.3431 32 38 30.6569 38 29V27Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M8 39C8 37.3431 9.34315 36 11 36H53C54.6569 36 56 37.3431 56 39V41C56 42.6569 54.6569 44 53 44H11C9.34315 44 8 42.6569 8 41V39Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M60 39C60 37.3431 61.3431 36 63 36H83C84.6569 36 86 37.3431 86 39V41C86 42.6569 84.6569 44 83 44H63C61.3431 44 60 42.6569 60 41V39Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M8 51C8 49.3431 9.34315 48 11 48H31C32.6569 48 34 49.3431 34 51V53C34 54.6569 32.6569 56 31 56H11C9.34315 56 8 54.6569 8 53V51Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
10
public/static/images/form/markdown_card_dark.svg
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<svg width="94" height="64" viewBox="0 0 94 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 8C0 3.58172 3.58172 0 8 0H86C90.4183 0 94 3.58172 94 8V56C94 60.4183 90.4183 64 86 64H8C3.58172 64 0 60.4183 0 56V8Z" fill="#1C1C1C"/>
|
||||||
|
<path d="M0.5 8C0.5 3.85786 3.85786 0.5 8 0.5H86C90.1421 0.5 93.5 3.85786 93.5 8V56C93.5 60.1421 90.1421 63.5 86 63.5H8C3.85786 63.5 0.5 60.1421 0.5 56V8Z" stroke="white" stroke-opacity="0.24"/>
|
||||||
|
<path d="M8 14C8 10.6863 10.6863 8 14 8H33C36.3137 8 39 10.6863 39 14C39 17.3137 36.3137 20 33 20H14C10.6863 20 8 17.3137 8 14Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M8 27C8 25.3431 9.34315 24 11 24H31C32.6569 24 34 25.3431 34 27V29C34 30.6569 32.6569 32 31 32H11C9.34315 32 8 30.6569 8 29V27Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M38 27C38 25.3431 39.3431 24 41 24H83C84.6569 24 86 25.3431 86 27V29C86 30.6569 84.6569 32 83 32H41C39.3431 32 38 30.6569 38 29V27Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M8 39C8 37.3431 9.34315 36 11 36H53C54.6569 36 56 37.3431 56 39V41C56 42.6569 54.6569 44 53 44H11C9.34315 44 8 42.6569 8 41V39Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M60 39C60 37.3431 61.3431 36 63 36H83C84.6569 36 86 37.3431 86 39V41C86 42.6569 84.6569 44 83 44H63C61.3431 44 60 42.6569 60 41V39Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M8 51C8 49.3431 9.34315 48 11 48H31C32.6569 48 34 49.3431 34 51V53C34 54.6569 32.6569 56 31 56H11C9.34315 56 8 54.6569 8 53V51Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
7
public/static/images/form/markdown_text_only.svg
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<svg width="94" height="48" viewBox="0 0 94 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 11C0 9.34315 1.34315 8 3 8H23C24.6569 8 26 9.34315 26 11V13C26 14.6569 24.6569 16 23 16H3C1.34315 16 0 14.6569 0 13V11Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M30 11C30 9.34315 31.3431 8 33 8H91C92.6569 8 94 9.34315 94 11V13C94 14.6569 92.6569 16 91 16H33C31.3431 16 30 14.6569 30 13V11Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M0 23C0 21.3431 1.34315 20 3 20H61C62.6569 20 64 21.3431 64 23V25C64 26.6569 62.6569 28 61 28H3C1.34315 28 0 26.6569 0 25V23Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M68 23C68 21.3431 69.3431 20 71 20H91C92.6569 20 94 21.3431 94 23V25C94 26.6569 92.6569 28 91 28H71C69.3431 28 68 26.6569 68 25V23Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M0 35C0 33.3431 1.34315 32 3 32H23C24.6569 32 26 33.3431 26 35V37C26 38.6569 24.6569 40 23 40H3C1.34315 40 0 38.6569 0 37V35Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 964 B |
7
public/static/images/form/markdown_text_only_dark.svg
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<svg width="94" height="48" viewBox="0 0 94 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 11C0 9.34315 1.34315 8 3 8H23C24.6569 8 26 9.34315 26 11V13C26 14.6569 24.6569 16 23 16H3C1.34315 16 0 14.6569 0 13V11Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M30 11C30 9.34315 31.3431 8 33 8H91C92.6569 8 94 9.34315 94 11V13C94 14.6569 92.6569 16 91 16H33C31.3431 16 30 14.6569 30 13V11Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M0 23C0 21.3431 1.34315 20 3 20H61C62.6569 20 64 21.3431 64 23V25C64 26.6569 62.6569 28 61 28H3C1.34315 28 0 26.6569 0 25V23Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M68 23C68 21.3431 69.3431 20 71 20H91C92.6569 20 94 21.3431 94 23V25C94 26.6569 92.6569 28 91 28H71C69.3431 28 68 26.6569 68 25V23Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M0 35C0 33.3431 1.34315 32 3 32H23C24.6569 32 26 33.3431 26 35V37C26 38.6569 24.6569 40 23 40H3C1.34315 40 0 38.6569 0 37V35Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 964 B |
@@ -0,0 +1,7 @@
|
|||||||
|
<svg width="94" height="40" viewBox="0 0 94 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="40" rx="8" fill="white"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="39" rx="7.5" stroke="black" stroke-opacity="0.12"/>
|
||||||
|
<circle cx="20" cy="20" r="12" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M40 14C40 10.6863 42.6863 8 46 8H65C68.3137 8 71 10.6863 71 14C71 17.3137 68.3137 20 65 20H46C42.6863 20 40 17.3137 40 14Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M40 28C40 25.7909 41.7909 24 44 24H77C79.2091 24 81 25.7909 81 28C81 30.2091 79.2091 32 77 32H44C41.7909 32 40 30.2091 40 28Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 652 B |
@@ -0,0 +1,7 @@
|
|||||||
|
<svg width="94" height="40" viewBox="0 0 94 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="40" rx="8" fill="#1C1C1C"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="39" rx="7.5" stroke="white" stroke-opacity="0.24"/>
|
||||||
|
<circle cx="20" cy="20" r="12" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M40 14C40 10.6863 42.6863 8 46 8H65C68.3137 8 71 10.6863 71 14C71 17.3137 68.3137 20 65 20H46C42.6863 20 40 17.3137 40 14Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M40 28C40 25.7909 41.7909 24 44 24H77C79.2091 24 81 25.7909 81 28C81 30.2091 79.2091 32 77 32H44C41.7909 32 40 30.2091 40 28Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 654 B |
@@ -0,0 +1,7 @@
|
|||||||
|
<svg width="94" height="72" viewBox="0 0 94 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="72" rx="8" fill="white"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="71" rx="7.5" stroke="black" stroke-opacity="0.12"/>
|
||||||
|
<circle cx="47" cy="20" r="12" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M31.5 46C31.5 42.6863 34.1863 40 37.5 40H56.5C59.8137 40 62.5 42.6863 62.5 46C62.5 49.3137 59.8137 52 56.5 52H37.5C34.1863 52 31.5 49.3137 31.5 46Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M26.5 60C26.5 57.7909 28.2909 56 30.5 56H63.5C65.7091 56 67.5 57.7909 67.5 60C67.5 62.2091 65.7091 64 63.5 64H30.5C28.2909 64 26.5 62.2091 26.5 60Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 699 B |
@@ -0,0 +1,7 @@
|
|||||||
|
<svg width="94" height="72" viewBox="0 0 94 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="72" rx="8" fill="#1C1C1C"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="71" rx="7.5" stroke="white" stroke-opacity="0.24"/>
|
||||||
|
<circle cx="47" cy="20" r="12" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M31.5 46C31.5 42.6863 34.1863 40 37.5 40H56.5C59.8137 40 62.5 42.6863 62.5 46C62.5 49.3137 59.8137 52 56.5 52H37.5C34.1863 52 31.5 49.3137 31.5 46Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M26.5 60C26.5 57.7909 28.2909 56 30.5 56H63.5C65.7091 56 67.5 57.7909 67.5 60C67.5 62.2091 65.7091 64 63.5 64H30.5C28.2909 64 26.5 62.2091 26.5 60Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 701 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg width="94" height="48" viewBox="0 0 94 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="48" rx="8" fill="white"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="47" rx="7.5" stroke="black" stroke-opacity="0.12"/>
|
||||||
|
<rect x="8" y="8" width="78" height="12" rx="3" fill="black" fill-opacity="0.12"/>
|
||||||
|
<rect x="8" y="28" width="78" height="12" rx="3" fill="black" fill-opacity="0.32"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 414 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg width="94" height="48" viewBox="0 0 94 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="48" rx="8" fill="#1C1C1C"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="47" rx="7.5" stroke="white" stroke-opacity="0.24"/>
|
||||||
|
<rect x="8" y="8" width="78" height="12" rx="3" fill="white" fill-opacity="0.24"/>
|
||||||
|
<rect x="8" y="28" width="78" height="12" rx="3" fill="white" fill-opacity="0.48"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 416 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg width="94" height="28" viewBox="0 0 94 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="28" rx="8" fill="white"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="27" rx="7.5" stroke="black" stroke-opacity="0.12"/>
|
||||||
|
<rect x="8" y="8" width="35" height="12" rx="3" fill="black" fill-opacity="0.12"/>
|
||||||
|
<rect x="51" y="8" width="35" height="12" rx="3" fill="black" fill-opacity="0.32"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 414 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg width="94" height="28" viewBox="0 0 94 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="28" rx="8" fill="#1C1C1C"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="27" rx="7.5" stroke="white" stroke-opacity="0.24"/>
|
||||||
|
<rect x="8" y="8" width="35" height="12" rx="3" fill="white" fill-opacity="0.24"/>
|
||||||
|
<rect x="51" y="8" width="35" height="12" rx="3" fill="white" fill-opacity="0.48"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 416 B |
@@ -0,0 +1,11 @@
|
|||||||
|
<svg width="94" height="56" viewBox="0 0 94 56" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="56" rx="8" fill="white"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="55" rx="7.5" stroke="black" stroke-opacity="0.12" stroke-dasharray="4 4"/>
|
||||||
|
<path d="M8 14C8 10.6863 10.6863 8 14 8H33C36.3137 8 39 10.6863 39 14C39 17.3137 36.3137 20 33 20H14C10.6863 20 8 17.3137 8 14Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M8 27C8 25.3431 9.34315 24 11 24H83C84.6569 24 86 25.3431 86 27V29C86 30.6569 84.6569 32 83 32H11C9.34315 32 8 30.6569 8 29V27Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M8 44C8 46.2091 9.79086 48 12 48H16C18.2091 48 20 46.2091 20 44C20 41.7909 18.2091 40 16 40H12C9.79086 40 8 41.7909 8 44Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M24.5 44C24.5 46.2091 26.2909 48 28.5 48H32.5C34.7091 48 36.5 46.2091 36.5 44C36.5 41.7909 34.7091 40 32.5 40H28.5C26.2909 40 24.5 41.7909 24.5 44Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M41 44C41 46.2091 42.7909 48 45 48H49C51.2091 48 53 46.2091 53 44C53 41.7909 51.2091 40 49 40H45C42.7909 40 41 41.7909 41 44Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M57.5 44C57.5 46.2091 59.2909 48 61.5 48H65.5C67.7091 48 69.5 46.2091 69.5 44C69.5 41.7909 67.7091 40 65.5 40H61.5C59.2909 40 57.5 41.7909 57.5 44Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M74 44C74 46.2091 75.7909 48 78 48H82C84.2091 48 86 46.2091 86 44C86 41.7909 84.2091 40 82 40H78C75.7909 40 74 41.7909 74 44Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,11 @@
|
|||||||
|
<svg width="94" height="56" viewBox="0 0 94 56" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 8C0 3.58172 3.58172 0 8 0H86C90.4183 0 94 3.58172 94 8V48C94 52.4183 90.4183 56 86 56H8C3.58172 56 0 52.4183 0 48V8Z" fill="#1C1C1C"/>
|
||||||
|
<path d="M1.34748 52.4449C0.772837 51.5866 0.359906 50.6109 0.152272 49.5613L0.642766 49.4643C0.549158 48.9911 0.5 48.5015 0.5 48V46H0V42H0.5V38H0V34H0.5V30H0V26H0.5V22H0V18H0.5V14H0V10H0.5V8C0.5 7.49847 0.549158 7.00892 0.642766 6.53574L0.152272 6.4387C0.359906 5.38915 0.772837 4.41341 1.34748 3.55508L1.76296 3.83324C2.31067 3.01513 3.01513 2.31067 3.83323 1.76296L3.55507 1.34748C4.41341 0.772837 5.38915 0.359906 6.4387 0.152272L6.53574 0.642766C7.00892 0.549158 7.49847 0.5 8 0.5H9.94999V0H13.85V0.5H17.75V0H21.65V0.5H25.55V0H29.45V0.5H33.35V0H37.25V0.5H41.15V0H45.05V0.5H48.95V0H52.85V0.5H56.75V0H60.65V0.5H64.55V0H68.45V0.5H72.35V0H76.25V0.5H80.15V0H84.05V0.5H86C86.5015 0.5 86.9911 0.549158 87.4643 0.642766L87.5613 0.152273C88.6108 0.359907 89.5866 0.772837 90.4449 1.34747L90.1668 1.76296C90.9849 2.31067 91.6893 3.01513 92.237 3.83323L92.6525 3.55507C93.2272 4.41341 93.6401 5.38915 93.8477 6.4387L93.3572 6.53574C93.4508 7.00892 93.5 7.49847 93.5 8V10H94V14H93.5V18H94V22H93.5V26H94V30H93.5V34H94V38H93.5V42H94V46H93.5V48C93.5 48.5015 93.4508 48.9911 93.3572 49.4643L93.8477 49.5613C93.6401 50.6109 93.2272 51.5866 92.6525 52.4449L92.237 52.1668C91.6893 52.9849 90.9849 53.6893 90.1668 54.237L90.4449 54.6525C89.5866 55.2272 88.6108 55.6401 87.5613 55.8477L87.4643 55.3572C86.9911 55.4508 86.5015 55.5 86 55.5H84.05V56H80.15V55.5H76.25V56H72.35V55.5H68.45V56H64.55V55.5H60.65V56H56.75V55.5H52.85V56H48.95V55.5H45.05V56H41.15V55.5H37.25V56H33.35V55.5H29.45V56H25.55V55.5H21.65V56H17.75V55.5H13.85V56H9.95V55.5H8C7.49847 55.5 7.00892 55.4508 6.53574 55.3572L6.4387 55.8477C5.38915 55.6401 4.41341 55.2272 3.55508 54.6525L3.83323 54.237C3.01513 53.6893 2.31067 52.9849 1.76296 52.1668L1.34748 52.4449Z" stroke="white" stroke-opacity="0.24" stroke-dasharray="4 4"/>
|
||||||
|
<path d="M8 14C8 10.6863 10.6863 8 14 8H33C36.3137 8 39 10.6863 39 14C39 17.3137 36.3137 20 33 20H14C10.6863 20 8 17.3137 8 14Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M8 27C8 25.3431 9.34315 24 11 24H83C84.6569 24 86 25.3431 86 27V29C86 30.6569 84.6569 32 83 32H11C9.34315 32 8 30.6569 8 29V27Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M8 44C8 46.2091 9.79086 48 12 48H16C18.2091 48 20 46.2091 20 44C20 41.7909 18.2091 40 16 40H12C9.79086 40 8 41.7909 8 44Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M24.5 44C24.5 46.2091 26.2909 48 28.5 48H32.5C34.7091 48 36.5 46.2091 36.5 44C36.5 41.7909 34.7091 40 32.5 40H28.5C26.2909 40 24.5 41.7909 24.5 44Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M41 44C41 46.2091 42.7909 48 45 48H49C51.2091 48 53 46.2091 53 44C53 41.7909 51.2091 40 49 40H45C42.7909 40 41 41.7909 41 44Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M57.5 44C57.5 46.2091 59.2909 48 61.5 48H65.5C67.7091 48 69.5 46.2091 69.5 44C69.5 41.7909 67.7091 40 65.5 40H61.5C59.2909 40 57.5 41.7909 57.5 44Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M74 44C74 46.2091 75.7909 48 78 48H82C84.2091 48 86 46.2091 86 44C86 41.7909 84.2091 40 82 40H78C75.7909 40 74 41.7909 74 44Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.2 KiB |
@@ -0,0 +1,11 @@
|
|||||||
|
<svg width="94" height="56" viewBox="0 0 94 56" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="56" rx="8" fill="white"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="55" rx="7.5" stroke="black" stroke-opacity="0.12" stroke-dasharray="4 4"/>
|
||||||
|
<path d="M8 12C8 14.2091 9.79086 16 12 16H16C18.2091 16 20 14.2091 20 12C20 9.79086 18.2091 8 16 8H12C9.79086 8 8 9.79086 8 12Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M24.5 12C24.5 14.2091 26.2909 16 28.5 16H32.5C34.7091 16 36.5 14.2091 36.5 12C36.5 9.79086 34.7091 8 32.5 8H28.5C26.2909 8 24.5 9.79086 24.5 12Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M41 12C41 14.2091 42.7909 16 45 16H49C51.2091 16 53 14.2091 53 12C53 9.79086 51.2091 8 49 8H45C42.7909 8 41 9.79086 41 12Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M57.5 12C57.5 14.2091 59.2909 16 61.5 16H65.5C67.7091 16 69.5 14.2091 69.5 12C69.5 9.79086 67.7091 8 65.5 8H61.5C59.2909 8 57.5 9.79086 57.5 12Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M74 12C74 14.2091 75.7909 16 78 16H82C84.2091 16 86 14.2091 86 12C86 9.79086 84.2091 8 82 8H78C75.7909 8 74 9.79086 74 12Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M8 30C8 26.6863 10.6863 24 14 24H33C36.3137 24 39 26.6863 39 30C39 33.3137 36.3137 36 33 36H14C10.6863 36 8 33.3137 8 30Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M8 43C8 41.3431 9.34315 40 11 40H83C84.6569 40 86 41.3431 86 43V45C86 46.6569 84.6569 48 83 48H11C9.34315 48 8 46.6569 8 45V43Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,11 @@
|
|||||||
|
<svg width="94" height="56" viewBox="0 0 94 56" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 8C0 3.58172 3.58172 0 8 0H86C90.4183 0 94 3.58172 94 8V48C94 52.4183 90.4183 56 86 56H8C3.58172 56 0 52.4183 0 48V8Z" fill="#1C1C1C"/>
|
||||||
|
<path d="M1.34748 52.4449C0.772837 51.5866 0.359906 50.6109 0.152272 49.5613L0.642766 49.4643C0.549158 48.9911 0.5 48.5015 0.5 48V46H0V42H0.5V38H0V34H0.5V30H0V26H0.5V22H0V18H0.5V14H0V10H0.5V8C0.5 7.49847 0.549158 7.00892 0.642766 6.53574L0.152272 6.4387C0.359906 5.38915 0.772837 4.41341 1.34748 3.55508L1.76296 3.83324C2.31067 3.01513 3.01513 2.31067 3.83323 1.76296L3.55507 1.34748C4.41341 0.772837 5.38915 0.359906 6.4387 0.152272L6.53574 0.642766C7.00892 0.549158 7.49847 0.5 8 0.5H9.94999V0H13.85V0.5H17.75V0H21.65V0.5H25.55V0H29.45V0.5H33.35V0H37.25V0.5H41.15V0H45.05V0.5H48.95V0H52.85V0.5H56.75V0H60.65V0.5H64.55V0H68.45V0.5H72.35V0H76.25V0.5H80.15V0H84.05V0.5H86C86.5015 0.5 86.9911 0.549158 87.4643 0.642766L87.5613 0.152273C88.6108 0.359907 89.5866 0.772837 90.4449 1.34747L90.1668 1.76296C90.9849 2.31067 91.6893 3.01513 92.237 3.83323L92.6525 3.55507C93.2272 4.41341 93.6401 5.38915 93.8477 6.4387L93.3572 6.53574C93.4508 7.00892 93.5 7.49847 93.5 8V10H94V14H93.5V18H94V22H93.5V26H94V30H93.5V34H94V38H93.5V42H94V46H93.5V48C93.5 48.5015 93.4508 48.9911 93.3572 49.4643L93.8477 49.5613C93.6401 50.6109 93.2272 51.5866 92.6525 52.4449L92.237 52.1668C91.6893 52.9849 90.9849 53.6893 90.1668 54.237L90.4449 54.6525C89.5866 55.2272 88.6108 55.6401 87.5613 55.8477L87.4643 55.3572C86.9911 55.4508 86.5015 55.5 86 55.5H84.05V56H80.15V55.5H76.25V56H72.35V55.5H68.45V56H64.55V55.5H60.65V56H56.75V55.5H52.85V56H48.95V55.5H45.05V56H41.15V55.5H37.25V56H33.35V55.5H29.45V56H25.55V55.5H21.65V56H17.75V55.5H13.85V56H9.95V55.5H8C7.49847 55.5 7.00892 55.4508 6.53574 55.3572L6.4387 55.8477C5.38915 55.6401 4.41341 55.2272 3.55508 54.6525L3.83323 54.237C3.01513 53.6893 2.31067 52.9849 1.76296 52.1668L1.34748 52.4449Z" stroke="white" stroke-opacity="0.24" stroke-dasharray="4 4"/>
|
||||||
|
<path d="M8 12C8 14.2091 9.79086 16 12 16H16C18.2091 16 20 14.2091 20 12C20 9.79086 18.2091 8 16 8H12C9.79086 8 8 9.79086 8 12Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M24.5 12C24.5 14.2091 26.2909 16 28.5 16H32.5C34.7091 16 36.5 14.2091 36.5 12C36.5 9.79086 34.7091 8 32.5 8H28.5C26.2909 8 24.5 9.79086 24.5 12Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M41 12C41 14.2091 42.7909 16 45 16H49C51.2091 16 53 14.2091 53 12C53 9.79086 51.2091 8 49 8H45C42.7909 8 41 9.79086 41 12Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M57.5 12C57.5 14.2091 59.2909 16 61.5 16H65.5C67.7091 16 69.5 14.2091 69.5 12C69.5 9.79086 67.7091 8 65.5 8H61.5C59.2909 8 57.5 9.79086 57.5 12Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M74 12C74 14.2091 75.7909 16 78 16H82C84.2091 16 86 14.2091 86 12C86 9.79086 84.2091 8 82 8H78C75.7909 8 74 9.79086 74 12Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M8 30C8 26.6863 10.6863 24 14 24H33C36.3137 24 39 26.6863 39 30C39 33.3137 36.3137 36 33 36H14C10.6863 36 8 33.3137 8 30Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M8 43C8 41.3431 9.34315 40 11 40H83C84.6569 40 86 41.3431 86 43V45C86 46.6569 84.6569 48 83 48H11C9.34315 48 8 46.6569 8 45V43Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.2 KiB |
11
public/static/images/form/view_header_layout_center.svg
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<svg width="94" height="56" viewBox="0 0 94 56" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="56" rx="8" fill="white"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="55" rx="7.5" stroke="black" stroke-opacity="0.12" stroke-dasharray="4 4"/>
|
||||||
|
<path d="M31.5 14C31.5 10.6863 34.1863 8 37.5 8H56.5C59.8137 8 62.5 10.6863 62.5 14C62.5 17.3137 59.8137 20 56.5 20H37.5C34.1863 20 31.5 17.3137 31.5 14Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M23 27C23 25.3431 24.3431 24 26 24H68C69.6569 24 71 25.3431 71 27V29C71 30.6569 69.6569 32 68 32H26C24.3431 32 23 30.6569 23 29V27Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M9 44C9 41.7909 10.7909 40 13 40H17C19.2091 40 21 41.7909 21 44C21 46.2091 19.2091 48 17 48H13C10.7909 48 9 46.2091 9 44Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M25 44C25 41.7909 26.7909 40 29 40H33C35.2091 40 37 41.7909 37 44C37 46.2091 35.2091 48 33 48H29C26.7909 48 25 46.2091 25 44Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M41 44C41 41.7909 42.7909 40 45 40H49C51.2091 40 53 41.7909 53 44C53 46.2091 51.2091 48 49 48H45C42.7909 48 41 46.2091 41 44Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M57 44C57 41.7909 58.7909 40 61 40H65C67.2091 40 69 41.7909 69 44C69 46.2091 67.2091 48 65 48H61C58.7909 48 57 46.2091 57 44Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M73 44C73 41.7909 74.7909 40 77 40H81C83.2091 40 85 41.7909 85 44C85 46.2091 83.2091 48 81 48H77C74.7909 48 73 46.2091 73 44Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
11
public/static/images/form/view_header_layout_center_dark.svg
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<svg width="94" height="56" viewBox="0 0 94 56" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 8C0 3.58172 3.58172 0 8 0H86C90.4183 0 94 3.58172 94 8V48C94 52.4183 90.4183 56 86 56H8C3.58172 56 0 52.4183 0 48V8Z" fill="#1C1C1C"/>
|
||||||
|
<path d="M1.34748 52.4449C0.772837 51.5866 0.359906 50.6109 0.152272 49.5613L0.642766 49.4643C0.549158 48.9911 0.5 48.5015 0.5 48V46H0V42H0.5V38H0V34H0.5V30H0V26H0.5V22H0V18H0.5V14H0V10H0.5V8C0.5 7.49847 0.549158 7.00892 0.642766 6.53574L0.152272 6.4387C0.359906 5.38915 0.772837 4.41341 1.34748 3.55508L1.76296 3.83324C2.31067 3.01513 3.01513 2.31067 3.83323 1.76296L3.55507 1.34748C4.41341 0.772837 5.38915 0.359906 6.4387 0.152272L6.53574 0.642766C7.00892 0.549158 7.49847 0.5 8 0.5H9.94999V0H13.85V0.5H17.75V0H21.65V0.5H25.55V0H29.45V0.5H33.35V0H37.25V0.5H41.15V0H45.05V0.5H48.95V0H52.85V0.5H56.75V0H60.65V0.5H64.55V0H68.45V0.5H72.35V0H76.25V0.5H80.15V0H84.05V0.5H86C86.5015 0.5 86.9911 0.549158 87.4643 0.642766L87.5613 0.152273C88.6108 0.359907 89.5866 0.772837 90.4449 1.34747L90.1668 1.76296C90.9849 2.31067 91.6893 3.01513 92.237 3.83323L92.6525 3.55507C93.2272 4.41341 93.6401 5.38915 93.8477 6.4387L93.3572 6.53574C93.4508 7.00892 93.5 7.49847 93.5 8V10H94V14H93.5V18H94V22H93.5V26H94V30H93.5V34H94V38H93.5V42H94V46H93.5V48C93.5 48.5015 93.4508 48.9911 93.3572 49.4643L93.8477 49.5613C93.6401 50.6109 93.2272 51.5866 92.6525 52.4449L92.237 52.1668C91.6893 52.9849 90.9849 53.6893 90.1668 54.237L90.4449 54.6525C89.5866 55.2272 88.6108 55.6401 87.5613 55.8477L87.4643 55.3572C86.9911 55.4508 86.5015 55.5 86 55.5H84.05V56H80.15V55.5H76.25V56H72.35V55.5H68.45V56H64.55V55.5H60.65V56H56.75V55.5H52.85V56H48.95V55.5H45.05V56H41.15V55.5H37.25V56H33.35V55.5H29.45V56H25.55V55.5H21.65V56H17.75V55.5H13.85V56H9.95V55.5H8C7.49847 55.5 7.00892 55.4508 6.53574 55.3572L6.4387 55.8477C5.38915 55.6401 4.41341 55.2272 3.55508 54.6525L3.83323 54.237C3.01513 53.6893 2.31067 52.9849 1.76296 52.1668L1.34748 52.4449Z" stroke="white" stroke-opacity="0.24" stroke-dasharray="4 4"/>
|
||||||
|
<path d="M31.5 14C31.5 10.6863 34.1863 8 37.5 8H56.5C59.8137 8 62.5 10.6863 62.5 14C62.5 17.3137 59.8137 20 56.5 20H37.5C34.1863 20 31.5 17.3137 31.5 14Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M23 27C23 25.3431 24.3431 24 26 24H68C69.6569 24 71 25.3431 71 27V29C71 30.6569 69.6569 32 68 32H26C24.3431 32 23 30.6569 23 29V27Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M9 44C9 41.7909 10.7909 40 13 40H17C19.2091 40 21 41.7909 21 44C21 46.2091 19.2091 48 17 48H13C10.7909 48 9 46.2091 9 44Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<rect x="25" y="40" width="12" height="8" rx="4" fill="white" fill-opacity="0.24"/>
|
||||||
|
<rect x="41" y="40" width="12" height="8" rx="4" fill="white" fill-opacity="0.24"/>
|
||||||
|
<rect x="57" y="40" width="12" height="8" rx="4" fill="white" fill-opacity="0.24"/>
|
||||||
|
<rect x="73" y="40" width="12" height="8" rx="4" fill="white" fill-opacity="0.24"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
24
public/static/images/form/view_header_layout_responsive.svg
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<svg width="94" height="72" viewBox="0 0 94 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_887_2968)">
|
||||||
|
<path d="M0 39H55V64C55 68.4183 51.4183 72 47 72H8C3.58172 72 0 68.4183 0 64V39Z" fill="white"/>
|
||||||
|
<path d="M1.34748 68.4449C0.772837 67.5866 0.359906 66.6109 0.152272 65.5613L0.642766 65.4643C0.549158 64.9911 0.5 64.5015 0.5 64V61.9167H0V57.75H0.5V53.5833H0V49.4167H0.5V45.25H0V41.0833H0.5V39.5H1.96429V39H5.89286V39.5H9.82143V39H13.75V39.5H17.6786V39H21.6071V39.5H25.5357V39H29.4643V39.5H33.3929V39H37.3214V39.5H41.25V39H45.1786V39.5H49.1071V39H53.0357V39.5H54.5V41.0833H55V45.25H54.5V49.4167H55V53.5833H54.5V57.75H55V61.9167H54.5V64C54.5 64.5015 54.4508 64.9911 54.3572 65.4643L54.8477 65.5613C54.6401 66.6109 54.2272 67.5866 53.6525 68.4449L53.237 68.1668C52.6893 68.9849 51.9849 69.6893 51.1668 70.237L51.4449 70.6525C50.5866 71.2272 49.6109 71.6401 48.5613 71.8477L48.4643 71.3572C47.9911 71.4508 47.5015 71.5 47 71.5H45.05V72H41.15V71.5H37.25V72H33.35V71.5H29.45V72H25.55V71.5H21.65V72H17.75V71.5H13.85V72H9.95V71.5H8C7.49847 71.5 7.00892 71.4508 6.53574 71.3572L6.4387 71.8477C5.38915 71.6401 4.41341 71.2272 3.55507 70.6525L3.83323 70.237C3.01513 69.6893 2.31067 68.9849 1.76296 68.1668L1.34748 68.4449Z" stroke="black" stroke-opacity="0.12" stroke-dasharray="4 4"/>
|
||||||
|
<rect x="8" y="47" width="12" height="8" rx="4" fill="black" fill-opacity="0.32"/>
|
||||||
|
<rect x="24" y="47" width="12" height="8" rx="4" fill="black" fill-opacity="0.12"/>
|
||||||
|
<rect x="8" y="59" width="12" height="8" rx="4" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M54 0H86C90.4183 0 94 3.58172 94 8V32C94 36.4183 90.4183 40 86 40H54V0Z" fill="white"/>
|
||||||
|
<path d="M84 39.5V40H80V39.5H76V40H72V39.5H68V40H64V39.5H60V40H56V39.5H54.5V38H54V34H54.5V30H54V26H54.5V22H54V18H54.5V14H54V10H54.5V6H54V2H54.5V0.5H56V0H60V0.5H64V0H68V0.5H72V0H76V0.5H80V0H84V0.5H86C86.5015 0.5 86.9911 0.549158 87.4643 0.642766L87.5613 0.152272C88.6109 0.359906 89.5866 0.772836 90.4449 1.34748L90.1668 1.76296C90.9849 2.31067 91.6893 3.01513 92.237 3.83323L92.6525 3.55507C93.2272 4.41341 93.6401 5.38915 93.8477 6.4387L93.3572 6.53574C93.4508 7.00892 93.5 7.49847 93.5 8V10H94V14H93.5V18H94V22H93.5V26H94V30H93.5V32C93.5 32.5015 93.4508 32.9911 93.3572 33.4643L93.8477 33.5613C93.6401 34.6109 93.2272 35.5866 92.6525 36.4449L92.237 36.1668C91.6893 36.9849 90.9849 37.6893 90.1668 38.237L90.4449 38.6525C89.5866 39.2272 88.6109 39.6401 87.5613 39.8477L87.4643 39.3572C86.9911 39.4508 86.5015 39.5 86 39.5H84Z" stroke="black" stroke-opacity="0.12" stroke-dasharray="4 4"/>
|
||||||
|
<path d="M58 28C58 30.2091 59.7909 32 62 32H66C68.2091 32 70 30.2091 70 28C70 25.7909 68.2091 24 66 24H62C59.7909 24 58 25.7909 58 28Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M74 28C74 30.2091 75.7909 32 78 32H82C84.2091 32 86 30.2091 86 28C86 25.7909 84.2091 24 82 24H78C75.7909 24 74 25.7909 74 28Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M74 16C74 18.2091 75.7909 20 78 20H82C84.2091 20 86 18.2091 86 16C86 13.7909 84.2091 12 82 12H78C75.7909 12 74 13.7909 74 16Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M0 8C0 3.58172 3.58172 0 8 0H55V40H0V8Z" fill="white"/>
|
||||||
|
<path d="M3.55507 1.34748C4.41341 0.772837 5.38915 0.359906 6.4387 0.152272L6.53574 0.642766C7.00892 0.549158 7.49847 0.5 8 0.5H9.95833V0H13.875V0.5H17.7917V0H21.7083V0.5H25.625V0H29.5417V0.5H33.4583V0H37.375V0.5H41.2917V0H45.2083V0.5H49.125V0H53.0417V0.5H54.5V2H55V6H54.5V10H55V14H54.5V18H55V22H54.5V26H55V30H54.5V34H55V38H54.5V39.5H53.0357V40H49.1071V39.5H45.1786V40H41.25V39.5H37.3214V40H33.3929V39.5H29.4643V40H25.5357V39.5H21.6071V40H17.6786V39.5H13.75V40H9.82143V39.5H5.89286V40H1.96429V39.5H0.5V38H0V34H0.5V30H0V26H0.5V22H0V18H0.5V14H0V10H0.5V8C0.5 7.49847 0.549158 7.00892 0.642766 6.53574L0.152272 6.4387C0.359906 5.38915 0.772837 4.41341 1.34748 3.55508L1.76296 3.83324C2.31067 3.01513 3.01513 2.31067 3.83323 1.76296L3.55507 1.34748Z" stroke="black" stroke-opacity="0.12" stroke-dasharray="4 4"/>
|
||||||
|
<path d="M8 14C8 10.6863 10.6863 8 14 8H33C36.3137 8 39 10.6863 39 14C39 17.3137 36.3137 20 33 20H14C10.6863 20 8 17.3137 8 14Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M8 27C8 25.3431 9.34315 24 11 24H44C45.6569 24 47 25.3431 47 27V29C47 30.6569 45.6569 32 44 32H11C9.34315 32 8 30.6569 8 29V27Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M79 48V54.5C79 58.09 76.09 61 72.5 61H66.83L69.92 64.09L68.5 65.5L63 60L68.5 54.5L69.91 55.91L66.83 59H72.5C75 59 77 57 77 54.5V48H79Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_887_2968">
|
||||||
|
<rect width="94" height="72" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.5 KiB |
@@ -0,0 +1,17 @@
|
|||||||
|
<svg width="94" height="72" viewBox="0 0 94 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 39H55V64C55 68.4183 51.4183 72 47 72H8C3.58172 72 0 68.4183 0 64V39Z" fill="#1C1C1C"/>
|
||||||
|
<path d="M1.34748 68.4449C0.772837 67.5866 0.359906 66.6109 0.152272 65.5613L0.642766 65.4643C0.549158 64.9911 0.5 64.5015 0.5 64V61.9167H0V57.75H0.5V53.5833H0V49.4167H0.5V45.25H0V41.0833H0.5V39.5H1.96429V39H5.89286V39.5H9.82143V39H13.75V39.5H17.6786V39H21.6071V39.5H25.5357V39H29.4643V39.5H33.3929V39H37.3214V39.5H41.25V39H45.1786V39.5H49.1071V39H53.0357V39.5H54.5V41.0833H55V45.25H54.5V49.4167H55V53.5833H54.5V57.75H55V61.9167H54.5V64C54.5 64.5015 54.4508 64.9911 54.3572 65.4643L54.8477 65.5613C54.6401 66.6109 54.2272 67.5866 53.6525 68.4449L53.237 68.1668C52.6893 68.9849 51.9849 69.6893 51.1668 70.237L51.4449 70.6525C50.5866 71.2272 49.6109 71.6401 48.5613 71.8477L48.4643 71.3572C47.9911 71.4508 47.5015 71.5 47 71.5H45.05V72H41.15V71.5H37.25V72H33.35V71.5H29.45V72H25.55V71.5H21.65V72H17.75V71.5H13.85V72H9.95V71.5H8C7.49847 71.5 7.00892 71.4508 6.53574 71.3572L6.4387 71.8477C5.38915 71.6401 4.41341 71.2272 3.55507 70.6525L3.83323 70.237C3.01513 69.6893 2.31067 68.9849 1.76296 68.1668L1.34748 68.4449Z" stroke="white" stroke-opacity="0.24" stroke-dasharray="4 4"/>
|
||||||
|
<path d="M8 51C8 48.7909 9.79086 47 12 47H16C18.2091 47 20 48.7909 20 51C20 53.2091 18.2091 55 16 55H12C9.79086 55 8 53.2091 8 51Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M24 51C24 48.7909 25.7909 47 28 47H32C34.2091 47 36 48.7909 36 51C36 53.2091 34.2091 55 32 55H28C25.7909 55 24 53.2091 24 51Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M8 63C8 60.7909 9.79086 59 12 59H16C18.2091 59 20 60.7909 20 63C20 65.2091 18.2091 67 16 67H12C9.79086 67 8 65.2091 8 63Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M54 0H86C90.4183 0 94 3.58172 94 8V32C94 36.4183 90.4183 40 86 40H54V0Z" fill="#1C1C1C"/>
|
||||||
|
<path d="M84 39.5V40H80V39.5H76V40H72V39.5H68V40H64V39.5H60V40H56V39.5H54.5V38H54V34H54.5V30H54V26H54.5V22H54V18H54.5V14H54V10H54.5V6H54V2H54.5V0.5H56V0H60V0.5H64V0H68V0.5H72V0H76V0.5H80V0H84V0.5H86C86.5015 0.5 86.9911 0.549158 87.4643 0.642766L87.5613 0.152272C88.6109 0.359906 89.5866 0.772836 90.4449 1.34748L90.1668 1.76296C90.9849 2.31067 91.6893 3.01513 92.237 3.83323L92.6525 3.55507C93.2272 4.41341 93.6401 5.38915 93.8477 6.4387L93.3572 6.53574C93.4508 7.00892 93.5 7.49847 93.5 8V10H94V14H93.5V18H94V22H93.5V26H94V30H93.5V32C93.5 32.5015 93.4508 32.9911 93.3572 33.4643L93.8477 33.5613C93.6401 34.6109 93.2272 35.5866 92.6525 36.4449L92.237 36.1668C91.6893 36.9849 90.9849 37.6893 90.1668 38.237L90.4449 38.6525C89.5866 39.2272 88.6109 39.6401 87.5613 39.8477L87.4643 39.3572C86.9911 39.4508 86.5015 39.5 86 39.5H84Z" stroke="white" stroke-opacity="0.24" stroke-dasharray="4 4"/>
|
||||||
|
<path d="M58 28C58 30.2091 59.7909 32 62 32H66C68.2091 32 70 30.2091 70 28C70 25.7909 68.2091 24 66 24H62C59.7909 24 58 25.7909 58 28Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M74 28C74 30.2091 75.7909 32 78 32H82C84.2091 32 86 30.2091 86 28C86 25.7909 84.2091 24 82 24H78C75.7909 24 74 25.7909 74 28Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M74 16C74 18.2091 75.7909 20 78 20H82C84.2091 20 86 18.2091 86 16C86 13.7909 84.2091 12 82 12H78C75.7909 12 74 13.7909 74 16Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M0 8C0 3.58172 3.58172 0 8 0H55V40H0V8Z" fill="#1C1C1C"/>
|
||||||
|
<path d="M3.55507 1.34748C4.41341 0.772837 5.38915 0.359906 6.4387 0.152272L6.53574 0.642766C7.00892 0.549158 7.49847 0.5 8 0.5H9.95833V0H13.875V0.5H17.7917V0H21.7083V0.5H25.625V0H29.5417V0.5H33.4583V0H37.375V0.5H41.2917V0H45.2083V0.5H49.125V0H53.0417V0.5H54.5V2H55V6H54.5V10H55V14H54.5V18H55V22H54.5V26H55V30H54.5V34H55V38H54.5V39.5H53.0357V40H49.1071V39.5H45.1786V40H41.25V39.5H37.3214V40H33.3929V39.5H29.4643V40H25.5357V39.5H21.6071V40H17.6786V39.5H13.75V40H9.82143V39.5H5.89286V40H1.96429V39.5H0.5V38H0V34H0.5V30H0V26H0.5V22H0V18H0.5V14H0V10H0.5V8C0.5 7.49847 0.549158 7.00892 0.642766 6.53574L0.152272 6.4387C0.359906 5.38915 0.772837 4.41341 1.34748 3.55508L1.76296 3.83324C2.31067 3.01513 3.01513 2.31067 3.83323 1.76296L3.55507 1.34748Z" stroke="white" stroke-opacity="0.24" stroke-dasharray="4 4"/>
|
||||||
|
<path d="M8 14C8 10.6863 10.6863 8 14 8H33C36.3137 8 39 10.6863 39 14C39 17.3137 36.3137 20 33 20H14C10.6863 20 8 17.3137 8 14Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M8 27C8 25.3431 9.34315 24 11 24H44C45.6569 24 47 25.3431 47 27V29C47 30.6569 45.6569 32 44 32H11C9.34315 32 8 30.6569 8 29V27Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M79 48V54.5C79 58.09 76.09 61 72.5 61H66.83L69.92 64.09L68.5 65.5L63 60L68.5 54.5L69.91 55.91L66.83 59H72.5C75 59 77 57 77 54.5V48H79Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.6 KiB |
9
public/static/images/form/view_header_layout_start.svg
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<svg width="94" height="56" viewBox="0 0 94 56" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="56" rx="8" fill="white"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="55" rx="7.5" stroke="black" stroke-opacity="0.12" stroke-dasharray="4 4"/>
|
||||||
|
<path d="M8 14C8 10.6863 10.6863 8 14 8H33C36.3137 8 39 10.6863 39 14C39 17.3137 36.3137 20 33 20H14C10.6863 20 8 17.3137 8 14Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M8 27C8 25.3431 9.34315 24 11 24H53C54.6569 24 56 25.3431 56 27V29C56 30.6569 54.6569 32 53 32H11C9.34315 32 8 30.6569 8 29V27Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M8 44C8 41.7909 9.79086 40 12 40H16C18.2091 40 20 41.7909 20 44C20 46.2091 18.2091 48 16 48H12C9.79086 48 8 46.2091 8 44Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M24 44C24 41.7909 25.7909 40 28 40H32C34.2091 40 36 41.7909 36 44C36 46.2091 34.2091 48 32 48H28C25.7909 48 24 46.2091 24 44Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M40 44C40 41.7909 41.7909 40 44 40H48C50.2091 40 52 41.7909 52 44C52 46.2091 50.2091 48 48 48H44C41.7909 48 40 46.2091 40 44Z" fill="black" fill-opacity="0.12"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
11
public/static/images/form/view_header_layout_start_dark.svg
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<svg width="94" height="56" viewBox="0 0 94 56" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 8C0 3.58172 3.58172 0 8 0H86C90.4183 0 94 3.58172 94 8V48C94 52.4183 90.4183 56 86 56H8C3.58172 56 0 52.4183 0 48V8Z" fill="#1C1C1C"/>
|
||||||
|
<path d="M1.34748 52.4449C0.772837 51.5866 0.359906 50.6109 0.152272 49.5613L0.642766 49.4643C0.549158 48.9911 0.5 48.5015 0.5 48V46H0V42H0.5V38H0V34H0.5V30H0V26H0.5V22H0V18H0.5V14H0V10H0.5V8C0.5 7.49847 0.549158 7.00892 0.642766 6.53574L0.152272 6.4387C0.359906 5.38915 0.772837 4.41341 1.34748 3.55508L1.76296 3.83324C2.31067 3.01513 3.01513 2.31067 3.83323 1.76296L3.55507 1.34748C4.41341 0.772837 5.38915 0.359906 6.4387 0.152272L6.53574 0.642766C7.00892 0.549158 7.49847 0.5 8 0.5H9.94999V0H13.85V0.5H17.75V0H21.65V0.5H25.55V0H29.45V0.5H33.35V0H37.25V0.5H41.15V0H45.05V0.5H48.95V0H52.85V0.5H56.75V0H60.65V0.5H64.55V0H68.45V0.5H72.35V0H76.25V0.5H80.15V0H84.05V0.5H86C86.5015 0.5 86.9911 0.549158 87.4643 0.642766L87.5613 0.152273C88.6108 0.359907 89.5866 0.772837 90.4449 1.34747L90.1668 1.76296C90.9849 2.31067 91.6893 3.01513 92.237 3.83323L92.6525 3.55507C93.2272 4.41341 93.6401 5.38915 93.8477 6.4387L93.3572 6.53574C93.4508 7.00892 93.5 7.49847 93.5 8V10H94V14H93.5V18H94V22H93.5V26H94V30H93.5V34H94V38H93.5V42H94V46H93.5V48C93.5 48.5015 93.4508 48.9911 93.3572 49.4643L93.8477 49.5613C93.6401 50.6109 93.2272 51.5866 92.6525 52.4449L92.237 52.1668C91.6893 52.9849 90.9849 53.6893 90.1668 54.237L90.4449 54.6525C89.5866 55.2272 88.6108 55.6401 87.5613 55.8477L87.4643 55.3572C86.9911 55.4508 86.5015 55.5 86 55.5H84.05V56H80.15V55.5H76.25V56H72.35V55.5H68.45V56H64.55V55.5H60.65V56H56.75V55.5H52.85V56H48.95V55.5H45.05V56H41.15V55.5H37.25V56H33.35V55.5H29.45V56H25.55V55.5H21.65V56H17.75V55.5H13.85V56H9.95V55.5H8C7.49847 55.5 7.00892 55.4508 6.53574 55.3572L6.4387 55.8477C5.38915 55.6401 4.41341 55.2272 3.55508 54.6525L3.83323 54.237C3.01513 53.6893 2.31067 52.9849 1.76296 52.1668L1.34748 52.4449Z" stroke="white" stroke-opacity="0.24" stroke-dasharray="4 4"/>
|
||||||
|
<path d="M8 14C8 10.6863 10.6863 8 14 8H33C36.3137 8 39 10.6863 39 14C39 17.3137 36.3137 20 33 20H14C10.6863 20 8 17.3137 8 14Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M8 27C8 25.3431 9.34315 24 11 24H53C54.6569 24 56 25.3431 56 27V29C56 30.6569 54.6569 32 53 32H11C9.34315 32 8 30.6569 8 29V27Z" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M8 44C8 41.7909 9.79086 40 12 40H16C18.2091 40 20 41.7909 20 44C20 46.2091 18.2091 48 16 48H12C9.79086 48 8 46.2091 8 44Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<rect x="24" y="40" width="12" height="8" rx="4" fill="white" fill-opacity="0.24"/>
|
||||||
|
<rect x="40" y="40" width="12" height="8" rx="4" fill="white" fill-opacity="0.24"/>
|
||||||
|
<rect x="56" y="40" width="12" height="8" rx="4" fill="white" fill-opacity="0.24"/>
|
||||||
|
<rect x="72" y="40" width="12" height="8" rx="4" fill="white" fill-opacity="0.24"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
@@ -1,11 +1,12 @@
|
|||||||
[build-system]
|
[build-system]
|
||||||
requires = ["setuptools~=75.1"]
|
requires = ["setuptools~=77.0"]
|
||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "home-assistant-frontend"
|
name = "home-assistant-frontend"
|
||||||
version = "20250129.0"
|
version = "20250326.0"
|
||||||
license = {text = "Apache-2.0"}
|
license = "Apache-2.0"
|
||||||
|
license-files = ["LICENSE*"]
|
||||||
description = "The Home Assistant frontend"
|
description = "The Home Assistant frontend"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
authors = [
|
authors = [
|
||||||
@@ -17,8 +18,6 @@ requires-python = ">=3.13.0"
|
|||||||
"Homepage" = "https://github.com/home-assistant/frontend"
|
"Homepage" = "https://github.com/home-assistant/frontend"
|
||||||
|
|
||||||
[tool.setuptools]
|
[tool.setuptools]
|
||||||
platforms = ["any"]
|
|
||||||
zip-safe = false
|
|
||||||
include-package-data = true
|
include-package-data = true
|
||||||
|
|
||||||
[tool.setuptools.packages.find]
|
[tool.setuptools.packages.find]
|
||||||
|
@@ -37,7 +37,7 @@
|
|||||||
{
|
{
|
||||||
"description": "Group tsparticles engine and presets",
|
"description": "Group tsparticles engine and presets",
|
||||||
"groupName": "tsparticles",
|
"groupName": "tsparticles",
|
||||||
"matchPackageNames": ["tsparticles-engine", "tsparticles-preset-{/,}**"]
|
"matchPackageNames": ["@tsparticles/engine", "@tsparticles/preset-{/,}**"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Group date-fns with dependent timezone package",
|
"description": "Group date-fns with dependent timezone package",
|
||||||
|
@@ -64,7 +64,7 @@ echo Core is used from ${coreUrl}
|
|||||||
HASS_URL="$coreUrl" ./script/develop &
|
HASS_URL="$coreUrl" ./script/develop &
|
||||||
|
|
||||||
# serve the frontend
|
# serve the frontend
|
||||||
yarn dlx serve -l $frontendPort ./hass_frontend -s &
|
./node_modules/.bin/serve -p $frontendPort --single --no-port-switching --config ../script/serve-config.json ./hass_frontend &
|
||||||
|
|
||||||
# keep the script running while serving
|
# keep the script running while serving
|
||||||
wait
|
wait
|
||||||
|
3
script/serve-config.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"cleanUrls": false
|
||||||
|
}
|
@@ -1,3 +1,4 @@
|
|||||||
|
import memoizeOne from "memoize-one";
|
||||||
import { theme2hex } from "./convert-color";
|
import { theme2hex } from "./convert-color";
|
||||||
|
|
||||||
export const COLORS = [
|
export const COLORS = [
|
||||||
@@ -74,3 +75,12 @@ export function getGraphColorByIndex(
|
|||||||
getColorByIndex(index);
|
getColorByIndex(index);
|
||||||
return theme2hex(themeColor);
|
return theme2hex(themeColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getAllGraphColors = memoizeOne(
|
||||||
|
(style: CSSStyleDeclaration) =>
|
||||||
|
COLORS.map((_color, index) => getGraphColorByIndex(index, style)),
|
||||||
|
(newArgs: [CSSStyleDeclaration], lastArgs: [CSSStyleDeclaration]) =>
|
||||||
|
// this is not ideal, but we need to memoize the colors
|
||||||
|
newArgs[0].getPropertyValue("--graph-color-1") ===
|
||||||
|
lastArgs[0].getPropertyValue("--graph-color-1")
|
||||||
|
);
|
||||||
|
@@ -132,15 +132,31 @@ export const hs2rgb = (hs: [number, number]): [number, number, number] =>
|
|||||||
|
|
||||||
export function theme2hex(themeColor: string): string {
|
export function theme2hex(themeColor: string): string {
|
||||||
if (themeColor.startsWith("#")) {
|
if (themeColor.startsWith("#")) {
|
||||||
|
if (themeColor.length === 4 || themeColor.length === 5) {
|
||||||
|
const c = themeColor;
|
||||||
|
// Convert short-form hex (#abc) to 6 digit (#aabbcc). Ignore alpha channel.
|
||||||
|
return `#${c[1]}${c[1]}${c[2]}${c[2]}${c[3]}${c[3]}`;
|
||||||
|
}
|
||||||
|
if (themeColor.length === 9) {
|
||||||
|
// Ignore alpha channel.
|
||||||
|
return themeColor.substring(0, 7);
|
||||||
|
}
|
||||||
return themeColor;
|
return themeColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rgbFromColorName = colors[themeColor];
|
const rgbFromColorName = colors[themeColor];
|
||||||
if (!rgbFromColorName) {
|
if (rgbFromColorName) {
|
||||||
|
return rgb2hex(rgbFromColorName);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rgbMatch = themeColor.match(/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/);
|
||||||
|
if (rgbMatch) {
|
||||||
|
const [, r, g, b] = rgbMatch.map(Number);
|
||||||
|
return rgb2hex([r, g, b]);
|
||||||
|
}
|
||||||
|
|
||||||
// We have a named color, and there's nothing in the table,
|
// We have a named color, and there's nothing in the table,
|
||||||
// so nothing further we can do with it.
|
// so nothing further we can do with it.
|
||||||
// Compare/border/background color will all be the same.
|
// Compare/border/background color will all be the same.
|
||||||
return themeColor;
|
return themeColor;
|
||||||
}
|
|
||||||
return rgb2hex(rgbFromColorName);
|
|
||||||
}
|
}
|
||||||
|
116
src/common/datetime/calc_date_range.ts
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
import {
|
||||||
|
addDays,
|
||||||
|
subHours,
|
||||||
|
endOfDay,
|
||||||
|
endOfMonth,
|
||||||
|
endOfWeek,
|
||||||
|
endOfYear,
|
||||||
|
startOfDay,
|
||||||
|
startOfMonth,
|
||||||
|
startOfWeek,
|
||||||
|
startOfYear,
|
||||||
|
startOfQuarter,
|
||||||
|
endOfQuarter,
|
||||||
|
subDays,
|
||||||
|
subMonths,
|
||||||
|
} from "date-fns";
|
||||||
|
import type { HomeAssistant } from "../../types";
|
||||||
|
import { calcDate } from "./calc_date";
|
||||||
|
import { firstWeekdayIndex } from "./first_weekday";
|
||||||
|
|
||||||
|
export type DateRange =
|
||||||
|
| "today"
|
||||||
|
| "yesterday"
|
||||||
|
| "this_week"
|
||||||
|
| "this_month"
|
||||||
|
| "this_quarter"
|
||||||
|
| "this_year"
|
||||||
|
| "now-7d"
|
||||||
|
| "now-30d"
|
||||||
|
| "now-12m"
|
||||||
|
| "now-1h"
|
||||||
|
| "now-12h"
|
||||||
|
| "now-24h";
|
||||||
|
|
||||||
|
export const calcDateRange = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
range: DateRange
|
||||||
|
): [Date, Date] => {
|
||||||
|
const today = new Date();
|
||||||
|
const weekStartsOn = firstWeekdayIndex(hass.locale);
|
||||||
|
switch (range) {
|
||||||
|
case "today":
|
||||||
|
return [
|
||||||
|
calcDate(today, startOfDay, hass.locale, hass.config, {
|
||||||
|
weekStartsOn,
|
||||||
|
}),
|
||||||
|
calcDate(today, endOfDay, hass.locale, hass.config, {
|
||||||
|
weekStartsOn,
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
case "yesterday":
|
||||||
|
return [
|
||||||
|
calcDate(addDays(today, -1), startOfDay, hass.locale, hass.config, {
|
||||||
|
weekStartsOn,
|
||||||
|
}),
|
||||||
|
calcDate(addDays(today, -1), endOfDay, hass.locale, hass.config, {
|
||||||
|
weekStartsOn,
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
case "this_week":
|
||||||
|
return [
|
||||||
|
calcDate(today, startOfWeek, hass.locale, hass.config, {
|
||||||
|
weekStartsOn,
|
||||||
|
}),
|
||||||
|
calcDate(today, endOfWeek, hass.locale, hass.config, {
|
||||||
|
weekStartsOn,
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
case "this_month":
|
||||||
|
return [
|
||||||
|
calcDate(today, startOfMonth, hass.locale, hass.config),
|
||||||
|
calcDate(today, endOfMonth, hass.locale, hass.config),
|
||||||
|
];
|
||||||
|
case "this_quarter":
|
||||||
|
return [
|
||||||
|
calcDate(today, startOfQuarter, hass.locale, hass.config),
|
||||||
|
calcDate(today, endOfQuarter, hass.locale, hass.config),
|
||||||
|
];
|
||||||
|
case "this_year":
|
||||||
|
return [
|
||||||
|
calcDate(today, startOfYear, hass.locale, hass.config),
|
||||||
|
calcDate(today, endOfYear, hass.locale, hass.config),
|
||||||
|
];
|
||||||
|
case "now-7d":
|
||||||
|
return [
|
||||||
|
calcDate(today, subDays, hass.locale, hass.config, 7),
|
||||||
|
calcDate(today, subDays, hass.locale, hass.config, 1),
|
||||||
|
];
|
||||||
|
case "now-30d":
|
||||||
|
return [
|
||||||
|
calcDate(today, subDays, hass.locale, hass.config, 30),
|
||||||
|
calcDate(today, subDays, hass.locale, hass.config, 1),
|
||||||
|
];
|
||||||
|
case "now-12m":
|
||||||
|
return [
|
||||||
|
calcDate(subMonths(today, 12), startOfMonth, hass.locale, hass.config),
|
||||||
|
calcDate(subMonths(today, 1), endOfMonth, hass.locale, hass.config),
|
||||||
|
];
|
||||||
|
case "now-1h":
|
||||||
|
return [
|
||||||
|
calcDate(today, subHours, hass.locale, hass.config, 1),
|
||||||
|
calcDate(today, subHours, hass.locale, hass.config, 0),
|
||||||
|
];
|
||||||
|
case "now-12h":
|
||||||
|
return [
|
||||||
|
calcDate(today, subHours, hass.locale, hass.config, 12),
|
||||||
|
calcDate(today, subHours, hass.locale, hass.config, 0),
|
||||||
|
];
|
||||||
|
case "now-24h":
|
||||||
|
return [
|
||||||
|
calcDate(today, subHours, hass.locale, hass.config, 24),
|
||||||
|
calcDate(today, subHours, hass.locale, hass.config, 0),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return [today, today];
|
||||||
|
};
|
@@ -26,6 +26,20 @@ const formatDateTimeMem = memoizeOne(
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const formatDateTimeWithBrowserDefaults = (dateObj: Date) =>
|
||||||
|
formatDateTimeWithBrowserDefaultsMem().format(dateObj);
|
||||||
|
|
||||||
|
const formatDateTimeWithBrowserDefaultsMem = memoizeOne(
|
||||||
|
() =>
|
||||||
|
new Intl.DateTimeFormat(undefined, {
|
||||||
|
year: "numeric",
|
||||||
|
month: "long",
|
||||||
|
day: "numeric",
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
// Aug 9, 2021, 8:23 AM
|
// Aug 9, 2021, 8:23 AM
|
||||||
export const formatShortDateTimeWithYear = (
|
export const formatShortDateTimeWithYear = (
|
||||||
dateObj: Date,
|
dateObj: Date,
|
||||||
|
@@ -16,11 +16,22 @@ export const setupLeafletMap = async (
|
|||||||
const Leaflet = (await import("leaflet")).default as LeafletModuleType;
|
const Leaflet = (await import("leaflet")).default as LeafletModuleType;
|
||||||
Leaflet.Icon.Default.imagePath = "/static/images/leaflet/images/";
|
Leaflet.Icon.Default.imagePath = "/static/images/leaflet/images/";
|
||||||
|
|
||||||
|
await import("leaflet.markercluster");
|
||||||
|
|
||||||
const map = Leaflet.map(mapElement);
|
const map = Leaflet.map(mapElement);
|
||||||
const style = document.createElement("link");
|
const style = document.createElement("link");
|
||||||
style.setAttribute("href", "/static/images/leaflet/leaflet.css");
|
style.setAttribute("href", "/static/images/leaflet/leaflet.css");
|
||||||
style.setAttribute("rel", "stylesheet");
|
style.setAttribute("rel", "stylesheet");
|
||||||
mapElement.parentNode.appendChild(style);
|
mapElement.parentNode.appendChild(style);
|
||||||
|
|
||||||
|
const markerClusterStyle = document.createElement("link");
|
||||||
|
markerClusterStyle.setAttribute(
|
||||||
|
"href",
|
||||||
|
"/static/images/leaflet/MarkerCluster.css"
|
||||||
|
);
|
||||||
|
markerClusterStyle.setAttribute("rel", "stylesheet");
|
||||||
|
mapElement.parentNode.appendChild(markerClusterStyle);
|
||||||
|
|
||||||
map.setView([52.3731339, 4.8903147], 13);
|
map.setView([52.3731339, 4.8903147], 13);
|
||||||
|
|
||||||
const tileLayer = createTileLayer(Leaflet).addTo(map);
|
const tileLayer = createTileLayer(Leaflet).addTo(map);
|
||||||
|
4
src/common/entity/compute_area_name.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import type { AreaRegistryEntry } from "../../data/area_registry";
|
||||||
|
|
||||||
|
export const computeAreaName = (area: AreaRegistryEntry): string | undefined =>
|
||||||
|
area.name?.trim();
|
@@ -34,7 +34,7 @@ export const computeAttributeValueDisplay = (
|
|||||||
value !== undefined ? value : stateObj.attributes[attribute];
|
value !== undefined ? value : stateObj.attributes[attribute];
|
||||||
|
|
||||||
// Null value, the state is unknown
|
// Null value, the state is unknown
|
||||||
if (attributeValue === null) {
|
if (attributeValue === null || attributeValue === undefined) {
|
||||||
return localize("state.default.unknown");
|
return localize("state.default.unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
38
src/common/entity/compute_device_name.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import type { DeviceRegistryEntry } from "../../data/device_registry";
|
||||||
|
import type {
|
||||||
|
EntityRegistryDisplayEntry,
|
||||||
|
EntityRegistryEntry,
|
||||||
|
} from "../../data/entity_registry";
|
||||||
|
import type { HomeAssistant } from "../../types";
|
||||||
|
import { computeStateName } from "./compute_state_name";
|
||||||
|
|
||||||
|
export const computeDeviceName = (
|
||||||
|
device: DeviceRegistryEntry
|
||||||
|
): string | undefined => (device.name_by_user || device.name)?.trim();
|
||||||
|
|
||||||
|
export const computeDeviceNameDisplay = (
|
||||||
|
device: DeviceRegistryEntry,
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entities?: EntityRegistryEntry[] | EntityRegistryDisplayEntry[] | string[]
|
||||||
|
) =>
|
||||||
|
computeDeviceName(device) ||
|
||||||
|
(entities && fallbackDeviceName(hass, entities)) ||
|
||||||
|
hass.localize("ui.panel.config.devices.unnamed_device", {
|
||||||
|
type: hass.localize(
|
||||||
|
`ui.panel.config.devices.type.${device.entry_type || "device"}`
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const fallbackDeviceName = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entities: EntityRegistryEntry[] | EntityRegistryDisplayEntry[] | string[]
|
||||||
|
) => {
|
||||||
|
for (const entity of entities || []) {
|
||||||
|
const entityId = typeof entity === "string" ? entity : entity.entity_id;
|
||||||
|
const stateObj = hass.states[entityId];
|
||||||
|
if (stateObj) {
|
||||||
|
return computeStateName(stateObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
@@ -1,2 +1,2 @@
|
|||||||
export const computeDomain = (entityId: string): string =>
|
export const computeDomain = (entityId: string): string =>
|
||||||
entityId.substr(0, entityId.indexOf("."));
|
entityId.substring(0, entityId.indexOf("."));
|
||||||
|
52
src/common/entity/compute_entity_name.ts
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import type { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
import type {
|
||||||
|
EntityRegistryDisplayEntry,
|
||||||
|
EntityRegistryEntry,
|
||||||
|
} from "../../data/entity_registry";
|
||||||
|
import type { HomeAssistant } from "../../types";
|
||||||
|
import { computeDeviceName } from "./compute_device_name";
|
||||||
|
import { computeStateName } from "./compute_state_name";
|
||||||
|
import { stripPrefixFromEntityName } from "./strip_prefix_from_entity_name";
|
||||||
|
|
||||||
|
export const computeEntityName = (
|
||||||
|
stateObj: HassEntity,
|
||||||
|
hass: HomeAssistant
|
||||||
|
): string | undefined => {
|
||||||
|
const entry = hass.entities[stateObj.entity_id] as
|
||||||
|
| EntityRegistryDisplayEntry
|
||||||
|
| undefined;
|
||||||
|
|
||||||
|
if (!entry) {
|
||||||
|
// Fall back to state name if not in the entity registry (friendly name)
|
||||||
|
return computeStateName(stateObj);
|
||||||
|
}
|
||||||
|
return computeEntityEntryName(entry, hass);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const computeEntityEntryName = (
|
||||||
|
entry: EntityRegistryDisplayEntry | EntityRegistryEntry,
|
||||||
|
hass: HomeAssistant
|
||||||
|
): string | undefined => {
|
||||||
|
const name =
|
||||||
|
entry.name || ("original_name" in entry ? entry.original_name : undefined);
|
||||||
|
|
||||||
|
const device = entry.device_id ? hass.devices[entry.device_id] : undefined;
|
||||||
|
|
||||||
|
if (!device) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const deviceName = computeDeviceName(device);
|
||||||
|
|
||||||
|
// If the device name is the same as the entity name, consider empty entity name
|
||||||
|
if (deviceName === name) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the device name from the entity name if it starts with it
|
||||||
|
if (deviceName && name) {
|
||||||
|
return stripPrefixFromEntityName(name, deviceName) || name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
};
|