Compare commits

...

344 Commits

Author SHA1 Message Date
Paul Bottein
1b44c7ce64 Add strategy editor
rename clean function

Fix types
2023-11-15 14:46:31 +01:00
Paul Bottein
de370d6384 Add todo entity_id in URL (#18653) 2023-11-15 11:26:03 +01:00
Paul Bottein
1cf928b425 Improve Lovelace types (#18652) 2023-11-15 11:13:49 +01:00
renovate[bot]
b9c62c34a0 Update dependency lint-staged to v15.1.0 (#18660)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-15 10:49:33 +01:00
renovate[bot]
37554213dc Update dependency @bundle-stats/plugin-webpack-filter to v4.8.0 (#18654) 2023-11-14 20:37:44 -05:00
renovate[bot]
3845fd2ef9 Update dependency @types/tar to v6.1.9 (#18650) 2023-11-14 20:35:55 -05:00
renovate[bot]
837b36a430 Update dependency marked to v9.1.6 (#18644)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-13 19:46:13 +01:00
karwosts
bff09a7a36 Fix login password form (#18619) 2023-11-13 19:45:34 +01:00
renovate[bot]
a5e5efa526 Update dependency @codemirror/autocomplete to v6.11.0 (#18633)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-12 22:29:54 -05:00
renovate[bot]
1cd5b9ff37 Update babel monorepo to v7.23.3 (#18632)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-12 21:16:45 -05:00
renovate[bot]
6a11155dd7 Update dependency vis-data to v7.1.8 (#18625) 2023-11-11 21:09:28 -05:00
renovate[bot]
1acb76d2f0 Update dependency @types/leaflet to v1.9.8 (#18622) 2023-11-12 02:07:18 +00:00
renovate[bot]
2e8a40efd5 Update dependency @types/ua-parser-js to v0.7.39 (#18616) 2023-11-11 20:58:50 -05:00
renovate[bot]
845a0e4e39 Update dependency @types/js-yaml to v4.0.9 (#18621) 2023-11-11 20:56:30 -05:00
Paul Bottein
9417f13cc9 Add unit for number tile feature (#18602) 2023-11-10 19:30:07 +01:00
renovate[bot]
d3f52f3bc0 Update dependency @types/tar to v6.1.8 (#18614)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-10 18:17:57 +00:00
renovate[bot]
7d0ec00fde Update dependency @types/sortablejs to v1.15.5 (#18613)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-10 13:06:13 -05:00
renovate[bot]
6dbb5dd4be Update dependency @types/qrcode to v1.5.5 (#18610)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-10 13:05:36 -05:00
renovate[bot]
f30e7948cb Update dependency @types/luxon to v3.3.4 (#18605)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-10 13:04:49 -05:00
renovate[bot]
41472d8160 Update dependency @types/serve-handler to v6.1.4 (#18612)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-10 12:43:05 -05:00
renovate[bot]
e596d32426 Update dependency @types/mocha to v10.0.4 (#18606)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-10 12:41:33 -05:00
renovate[bot]
89de62812f Update dependency @types/leaflet-draw to v1.0.10 (#18603)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-10 12:39:56 -05:00
renovate[bot]
3e391fcbe6 Update dependency @types/html-minifier-terser to v7.0.2 (#18601)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-10 12:37:31 -05:00
karwosts
708ab2ed69 Localize hide/show password (#18607) 2023-11-10 18:12:36 +01:00
Paul Bottein
1d45cb78fe Rename tooltipUnit to unit for slider (#18599) 2023-11-10 18:08:12 +01:00
Philip Allgaier
d3f6ebd1d0 Add unit to temperature tile number button group (#17841)
* Add unit to temperature tile number button group

* Update gallery

* Use blank before unit

* Hide unit if no space

* Fix build

---------

Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
2023-11-10 14:22:10 +01:00
Joseph Abbey
21644c70b3 Add number tile feature (#18562)
* hui-number-tile-feature

* Added support for number domain

* Apply suggestions from code review (thanks @piitaya)

Co-authored-by: Paul Bottein <paul.bottein@gmail.com>

* Fixed the callback to use the correct service

* fix formatting

---------

Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
2023-11-10 08:34:29 +00:00
karwosts
eb75389cac Localize clear in entity filter (#18598)
Localize  in entity filter
2023-11-10 08:27:36 +01:00
Bram Kragten
cd4f3a091b Fix add device dialog (#18591) 2023-11-10 08:27:02 +01:00
renovate[bot]
19c1973ec1 Update dependency @types/chromecast-caf-sender to v1.0.8 (#18597)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-10 03:35:04 +00:00
renovate[bot]
a8efbe5b06 Update dependency @types/chromecast-caf-receiver to v6.0.12 (#18595)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-10 03:22:14 +00:00
renovate[bot]
44b5c66c19 Update dependency @types/babel__plugin-transform-runtime to v7.9.5 (#18594)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-09 22:08:58 -05:00
renovate[bot]
3fa3bba4d8 Update formatjs monorepo (#18592)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-09 22:07:01 -05:00
renovate[bot]
ab09c821a2 Update typescript-eslint monorepo to v6.10.0 (#18586)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-09 22:05:26 -05:00
Paul Bottein
37b7395986 Migrate chips to Material 3 chips. (#18513) 2023-11-09 17:57:37 +01:00
Bram Kragten
4933413140 Fix virtualizer with v2.0.10 (#18584) 2023-11-09 11:53:35 -05:00
Bram Kragten
1c16bd5ab2 rollback lit-labs/virtualizer to 2.0.8 (#18580) 2023-11-09 16:26:09 +01:00
Paul Bottein
3a926c6f83 Add pointer-events none to slider tooltip (#18577) 2023-11-09 14:57:23 +01:00
Paul Bottein
7a619ad55a Only update dev tools yaml editor on entity change or submit (#18575)
Co-authored-by: Simon Lamon <32477463+silamon@users.noreply.github.com>
2023-11-09 10:00:24 +01:00
Paul Bottein
bc21425981 Add tooltip to tile sliders and more info sliders (#18567) 2023-11-08 12:47:55 +01:00
renovate[bot]
f2505c0798 Update dependency eslint to v8.53.0 (#18558)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-08 11:48:22 +01:00
Steve Repsher
cee8c756fc Remove dependency esprima (#18564) 2023-11-08 11:24:03 +01:00
renovate[bot]
396b3aace9 Update dependency @codemirror/view to v6.22.0 (#18553)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-07 18:02:11 -05:00
renovate[bot]
28dc1e4da9 Update vaadinWebComponents monorepo to v24.2.2 (#18552)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-07 17:59:54 -05:00
Kendell R
aa0419e783 Minify logos (#18542) 2023-11-07 13:39:38 +01:00
Jan Bouwhuis
fd9c24d05e Add localization to service call exceptions (#18447) 2023-11-07 12:04:53 +01:00
Paul Bottein
8bdbe8c6a6 Use strict comparison for above condition in conditional card (#18560) 2023-11-07 12:04:04 +01:00
Steve Repsher
39550cefa0 Add some Renovate groups and enable NVM updates (#18559) 2023-11-07 11:53:47 +01:00
David Bell
589e3b63c7 Don't display hidden/non-visible calendars on the Calendar panel (#18541) 2023-11-06 15:09:54 +00:00
renovate[bot]
0cc38278b9 Update dependency @lit-labs/virtualizer to v2.0.10 (#18547)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-06 15:56:45 +01:00
renovate[bot]
aafdf7bed7 Update dependency vis-network to v9.1.9 (#18548)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-06 15:55:24 +01:00
Simon Lamon
a7f6ce3079 Fix refresh in developer state tools (#18532) 2023-11-06 15:53:23 +01:00
karwosts
3d03f74d66 Improve template trigger/condition descriptions (#18504) 2023-11-06 10:04:58 +01:00
tzagim
e09a6a23fc Fix for RTL (#18509) 2023-11-06 10:02:44 +01:00
Kendell R
9e4bb6ed0c Fix "ttme" typo on the demo page (#18543) 2023-11-06 10:02:00 +01:00
renovate[bot]
c45c8ab5c0 Update dependency sinon to v17.0.1 (#18535)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-05 14:16:21 -05:00
renovate[bot]
5ef6973933 Update dependency marked to v9.1.5 (#18523)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-05 14:14:50 -05:00
renovate[bot]
1df344580a Update dependency eslint-plugin-lit-a11y to v4.1.1 (#18534)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-05 14:13:25 -05:00
renovate[bot]
25acc479b9 Update dependency core-js to v3.33.2 (#18515) 2023-11-02 20:54:59 -04:00
renovate[bot]
c9f051374b Update dependency punycode to v2.3.1 (#18516) 2023-11-02 20:50:03 -04:00
renovate[bot]
bf5116fc0b Update typescript-eslint monorepo to v6.9.1 (#18518) 2023-11-02 20:47:03 -04:00
renovate[bot]
edc8cb1d2e Update dependency @rollup/plugin-replace to v5.0.5 (#18505) 2023-11-02 20:42:05 -04:00
Bram Kragten
a60bb3ae0a Clean up auth flow translation placeholders (#18502) 2023-11-02 21:02:42 +01:00
Paul Bottein
784f753f07 Display default action label in action selector (#18398) 2023-11-02 16:10:15 +01:00
Paul Bottein
e63c7e3763 Add trigger selector for blueprint (#18469) 2023-11-02 16:01:59 +01:00
karwosts
cfa522068c Localize trigger condition and add list formatting (#18488) 2023-11-01 15:42:43 +01:00
schelv
5f2375fe84 feat: Dynamically adjust gradient percentages based on min/max values (#18479) 2023-11-01 15:41:26 +01:00
Kendell R
a9e34d7590 Stop using ha-markdown on the auth page (#18480) 2023-11-01 15:36:17 +01:00
Paul Bottein
463cfb869f Add and and or condition to conditional card (#18409) 2023-11-01 15:28:37 +01:00
Paul Bottein
acb5a2b283 Add test button to conditional card (#18411) 2023-11-01 15:25:56 +01:00
Bram Kragten
08597d6e91 Bump node to v20 (#18497) 2023-11-01 15:22:23 +01:00
renovate[bot]
9478485268 Update Yarn to v4 (#18414)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-11-01 10:16:46 +00:00
renovate[bot]
0af9ec2fff Pin dependencies (#18498)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-01 09:51:15 +00:00
Kendell R
f6e74de05e Properly set direction styles (#18483) 2023-11-01 10:38:02 +01:00
Bram Kragten
8b0373d5c0 Revert bump to @lit/context@1.0.1 (#18496) 2023-11-01 10:35:50 +01:00
karwosts
d4218250af Fix choose add option (#18493) 2023-11-01 09:37:26 +01:00
renovate[bot]
78783942be Update dependency @lit-labs/observers to v2.0.2 (#18484)
* Update dependency @lit-labs/observers to v2.0.2

* Resolve @lit/reactive-element to v1

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>
2023-10-31 14:42:28 -04:00
renovate[bot]
17ad8013ca Update dependency @lit-labs/context to v0.5.1 (#18208)
* Update dependency @lit-labs/context to v0.5.1

* Switch to @lit/context and resolve reactive-element to v1

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>
2023-10-31 13:53:53 -04:00
renovate[bot]
f70767f084 Update dependency @lit-labs/motion to v1.0.6 (#18205)
* Update dependency @lit-labs/motion to v1.0.6

* Resolve to lit v2

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>
2023-10-31 14:31:42 +00:00
renovate[bot]
3972394d82 Update dependency @lit-labs/virtualizer to v2.0.9 (#18206)
* Update dependency @lit-labs/virtualizer to v2.0.9

* Resolve to lit v2

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>
2023-10-31 13:22:54 +00:00
renovate[bot]
5331fb4f5f Update dependency marked to v9.1.3 (#18485)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-31 08:44:18 -04:00
Matthias de Baat
16df352ba8 Update ha-dialogs.markdown (#18487) 2023-10-31 12:27:46 +00:00
Bram Kragten
8e1e75dee1 Bumped version to 20231030.0 2023-10-30 21:44:17 +01:00
Bram Kragten
d27b4e04a9 Adapt to new todo services (#18477) 2023-10-30 20:32:32 +00:00
Simon Lamon
36f7b34ac5 Use trigger and condition type translation labels (#18413)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-10-30 20:54:30 +01:00
renovate[bot]
c0ff24bf1b Update dependency ua-parser-js to v1.0.37 (#18473)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-30 12:29:17 -04:00
Duco Sebel
abb5aa348f Allow individual item deletion in To-do list (#18464)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-10-30 14:21:29 +00:00
renovate[bot]
37ab5cbdc3 Update dependency fuse.js to v7 (#18462)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-10-30 15:09:12 +01:00
Bram Kragten
42be3b331c Fix buttons (#18472) 2023-10-30 13:56:48 +01:00
Paul Bottein
71e05f79c2 Update ts-lit-plugin to 2.0.1 (#18471) 2023-10-30 13:40:07 +01:00
karwosts
c5a0a5bbbf Fix statistics bar chart time axis (#18450) 2023-10-30 13:39:15 +01:00
dependabot[bot]
c3d809fcf3 Bump actions/setup-node from 3.8.1 to 4.0.0 (#18468)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 11:18:14 +01:00
renovate[bot]
cbd0c39091 Update formatjs monorepo (#18423) 2023-10-29 22:05:19 -04:00
renovate[bot]
113eb5be24 Update dependency eslint-plugin-lit to v1.10.1 (#18460) 2023-10-28 21:45:57 -04:00
renovate[bot]
c497669fd3 Update dependency ts-lit-plugin to v2.0.0 (#18459) 2023-10-29 01:39:04 +00:00
renovate[bot]
c32ca5885b Update dependency lit-analyzer to v2.0.1 (#18458) 2023-10-28 21:28:01 -04:00
renovate[bot]
3c792c4019 Update dependency @bundle-stats/plugin-webpack-filter to v4.7.8 (#18457) 2023-10-28 21:23:43 -04:00
renovate[bot]
9762e61ee2 Update vaadinWebComponents monorepo to v24.2.1 (#18454)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-28 20:36:52 +00:00
renovate[bot]
c09c39998b Update dependency vue to v2.7.15 (#18424)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-28 16:22:32 -04:00
renovate[bot]
d37e29c247 Update CodeMirror (#18453)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-28 16:20:45 -04:00
renovate[bot]
51f22cd74a Update dependency eslint-import-resolver-webpack to v0.13.8 (#18422)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-28 16:12:52 -04:00
renovate[bot]
b57dc968bd Update dependency eslint-plugin-import to v2.29.0 (#18425)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-28 16:07:23 -04:00
renovate[bot]
e2e8cb785a Update typescript-eslint monorepo to v6.9.0 (#18433)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-28 16:06:02 -04:00
Bram Kragten
9961a4ae3f Bumped version to 20231027.0 2023-10-27 16:33:32 +02:00
Bram Kragten
c25755bfcd Translate todo panel title, update assist title/icon (#18442) 2023-10-27 16:33:02 +02:00
Bram Kragten
40983619d6 Reload when entering safe mode (#18443) 2023-10-27 15:48:01 +02:00
Bram Kragten
54758b5962 Don't override ranges provided by parent (#18444) 2023-10-27 15:47:47 +02:00
Bram Kragten
4f09485b20 Update todo list items when entity changes, only refresh on shopping … (#18445) 2023-10-27 15:47:37 +02:00
Paul Bottein
9207f6c407 Fix unit of measurement not displayed in entity settings (#18440) 2023-10-27 13:29:41 +02:00
Paul Bottein
1a2312460a Disable resource panel in safe mode (#18437) 2023-10-27 13:29:00 +02:00
Simon Lamon
951b88ab4c Fix change entity in dev tools state (#18441) 2023-10-27 13:27:01 +02:00
Bram Kragten
d3cc57d8b4 Don't use lookbehind assertion in slugify (#18438) 2023-10-27 12:53:17 +02:00
karwosts
4e9b118728 Ensure energy card titles always displayed (#18432) 2023-10-27 10:42:01 +02:00
Paul Bottein
f1748e4dd5 Bumped version to 20231026.0 2023-10-26 15:39:36 +02:00
Paul Bottein
d491d8f5ac Quick fix for lovelace resources not loaded (#18430) 2023-10-26 15:37:31 +02:00
Bram Kragten
cf0fde0f3c Change move item todo API (#18410)
* Change move item todo API

* Handle entity unavailable, add link to more info, allow to delete local todo
2023-10-26 15:37:13 +02:00
Paul Bottein
a7dc2cfaa6 Reduce slider handle size (#18427) 2023-10-26 15:25:47 +02:00
Paul Bottein
d8c7db6ebf Add translations to tile state content options (#18428) 2023-10-26 10:32:09 +00:00
J. Nick Koston
c3743b57ea Speed up first load by preloading recorder info (#18412) 2023-10-25 19:29:44 +00:00
Steve Repsher
e16a101de8 Compress service worker (#18407) 2023-10-25 17:17:11 +02:00
Paul Bottein
94ad47c60e Hide reveal icon on edge for text-field (#18408) 2023-10-25 17:15:43 +02:00
Bram Kragten
184ef7b7ff Bar media player fixes (#18402) 2023-10-25 16:04:05 +02:00
karwosts
81053f2e07 Fix an undefined exception in more-info popup for history graph (#18404) 2023-10-25 15:48:05 +02:00
Paul Bottein
e8b4eeec67 Allow any number in above and below numeric condition (#18403) 2023-10-25 13:38:39 +00:00
karwosts
b0b7e77e28 Fix schedule form rendering after disconnect (#18401) 2023-10-25 13:21:05 +00:00
Bram Kragten
763f80b46a Bumped version to 20231025.1 2023-10-25 13:59:11 +02:00
Bram Kragten
0c2531a7ee Update todo list card (#18396) 2023-10-25 13:57:50 +02:00
Paul Bottein
8d2ec8098c Fix state not condition for condition card (#18397) 2023-10-25 11:09:28 +00:00
Bram Kragten
d2caed2b68 Merge branch 'master' into dev 2023-10-25 11:51:01 +02:00
Jan-Philipp Benecke
402d443843 Add mac and bluetooth address to the device info card (#18392)
Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
2023-10-25 11:47:54 +02:00
Bram Kragten
399f12194a Bumped version to 20231025.0 2023-10-25 11:47:02 +02:00
Bram Kragten
a745539c33 fix height issue calendar, make default on mobile list (#18394) 2023-10-25 11:46:28 +02:00
Bram Kragten
f6fddbc6ec Add create todo list button (#18387) 2023-10-25 11:38:45 +02:00
Steve Repsher
01f51f3247 Cache brand images (#17840) 2023-10-25 09:28:28 +02:00
karwosts
80112bb662 Add Fields to Script UI (#18250) 2023-10-25 09:23:15 +02:00
Jan-Philipp Benecke
7ce7cbb755 Add serial number to the device info card (#18386)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2023-10-25 06:32:24 +02:00
karwosts
464ecffda7 Fix a crash in trace graph generation for if/else (#18390) 2023-10-24 23:18:21 +00:00
Paul Bottein
33e0c691c7 Use expansion panel for dashboard conditions (#18380) 2023-10-25 00:45:55 +02:00
c0ffeeca7
d94f7c90c0 Restart dialog description: consistently use indicative form (#18385)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2023-10-24 23:39:23 +02:00
Raman Gupta
d8d16c4d5f Add Z-Wave controller hard reset device action (certification req) (#18216)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-10-24 23:16:21 +02:00
Bram Kragten
1cb238ec2a Fixes for todo card (#18388) 2023-10-24 22:53:54 +02:00
karwosts
3e6ab8b179 Chart updates to improve stability, possible fix for infinite loop (#18329)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-10-24 20:41:34 +00:00
Bram Kragten
10bcaadcdb center icons in restart dialog 2023-10-24 21:21:02 +02:00
Bram Kragten
67517643ef Add safe mode theme and alert dialog 2023-10-24 21:08:23 +02:00
Paul Bottein
eb35eb3de5 Disable dashboard resources in safe mode (#18382) 2023-10-24 20:15:11 +02:00
Paul Bottein
8350d71f6e Add restart in safe mode in restart dialog (#18375) 2023-10-24 20:09:54 +02:00
Paul Bottein
c840f1cbb1 Redesign about page (#18383) 2023-10-24 20:07:12 +02:00
Bram Kragten
8efc0816bb Rename shopping-list-card to todo-list-card (#18378) 2023-10-24 20:06:03 +02:00
J. Nick Koston
b12e4989db Subscribe to the issue registry as early as possible (#18384) 2023-10-24 19:34:47 +02:00
Bram Kragten
2b67731906 Add resize observer to full calendar, fix missing styles (#18381) 2023-10-24 19:33:15 +02:00
Bram Kragten
ccba7a7623 Add button to create local calendar in calendar panel (#18377) 2023-10-24 19:33:03 +02:00
Bram Kragten
c0dfc9f73e Performance tweaks in energy dashboard (#18379)
* Remove unneeded refresh from energy panel

* Optimize energy-period-selector
2023-10-24 18:18:29 +02:00
Bram Kragten
be1624f66f Convert shopping list card editor to ha-form (#18376)
* Convert shopping list card editor to ha-form

* hide todo from generated dashboard
2023-10-24 18:14:14 +02:00
Steve Repsher
32edbd7b33 Remove js-yaml resource proxy (#18369) 2023-10-24 14:17:25 +02:00
Josh McCarty
18827db9ba Add bottom padding to code editor (#18368) 2023-10-24 12:59:14 +02:00
karwosts
191250a66a Fix complex attribute display in devtools (#18371) 2023-10-24 12:57:36 +02:00
Erik Montnemery
1fdf609606 Rename safe mode to recovery mode (#18374)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-10-24 12:56:27 +02:00
Paul Bottein
6ffc0625d3 Add support for state content customization in tile card (#18180)
* Add support for state content customization

* Add reorder option

* Do not display null attributes

* Always return a value

* Add hide state option

* Add missing attribute unit

* Fix sortable create and destroy
2023-10-24 12:08:11 +02:00
Allen Porter
c9f5d16745 Rename status code string for To-do List NEEDS-ACTION status (#18373) 2023-10-24 12:07:36 +02:00
renovate[bot]
eb4afedf2e Update dependency eslint to v8.52.0 (#18370) 2023-10-23 20:46:04 -04:00
Bram Kragten
2b9540fe03 Add support for todo component (#18289) 2023-10-23 22:53:09 +02:00
renovate[bot]
53b8d1bb0a Update dependency sinon to v17 (#18346)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-23 15:18:23 +00:00
Simon Lamon
0ff5bffd0c Make time condition translatable (#18298) 2023-10-23 17:02:51 +02:00
Paul Bottein
82a464f50f Add translation to numeric condition card 2023-10-23 16:37:27 +02:00
Paul Bottein
fdddc18291 Add numeric state condition for conditional card (#18288)
* Add numeric state condition for conditional card

* Add validate ui

* Clean entity data

* Check for numeric state
2023-10-23 14:17:23 +00:00
Bram Kragten
463a3244cf Add two pane view to calendar panel (#18286)
Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
2023-10-23 14:13:38 +00:00
karwosts
6cae11f0a6 Update statistics chart to respect entity display precision, fix precision bug in history chart (#18334) 2023-10-23 16:03:42 +02:00
renovate[bot]
65112b36ce Update dependency @material/web to v1.0.1 (#18335)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-23 15:53:18 +02:00
renovate[bot]
58625d2a9d Update dependency core-js to v3.33.1 (#18339)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-23 15:50:55 +02:00
Paul Bottein
9bafbdd989 Allow multiple states in conditional card (#18273)
* Allow multiple states in conditional card

* Update src/panels/lovelace/editor/conditions/types/ha-card-condition-state.ts

Co-authored-by: Bram Kragten <mail@bramkragten.nl>

---------

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-10-23 13:49:43 +00:00
Paul Bottein
eedb42b2f3 Add user condition to conditional card (#18265)
* Add user condition to conditional card

* Refactor user fetch

* Add validate ui

* Use ha-check-list-item
2023-10-23 13:49:27 +00:00
Paul Bottein
4354ad3807 Move condition editor into its own file (#18340) 2023-10-23 15:31:49 +02:00
Paul Bottein
aeaf091b50 Use sensor device class for graph and precision (#18099)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-10-23 15:01:24 +02:00
Paul Bottein
c6be4d6f4d Improve warning messages in conditional card (#18272)
* Improve warning messages in conditional card

* Update src/panels/lovelace/editor/conditions/ha-card-condition-editor.ts

Co-authored-by: Bram Kragten <mail@bramkragten.nl>

---------

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-10-23 14:50:45 +02:00
Caius-Bonus
c48b620e03 Fix inconsistencies in slugify between frontend and core implementation (#18297) 2023-10-23 08:37:56 +00:00
Steve Repsher
77e05decdf Remove ondemand methods for CodeMirror and SortableJS (#18336) 2023-10-23 10:29:49 +02:00
Necroneco
b24e99c56c Fix oscillating handler in more info fan card (#18305) (#18306) 2023-10-23 10:26:31 +02:00
J. Nick Koston
768344c3f7 Fix double load of lovelace resources (#18332) 2023-10-23 10:05:26 +02:00
Bram Kragten
03a21d5519 Only calculate opening direction when we are opening the datepicker (#18313) 2023-10-23 09:58:20 +02:00
dependabot[bot]
1247a5c8d3 Bump home-assistant/wheels from 2023.10.4 to 2023.10.5 (#18338)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-23 09:54:53 +02:00
dependabot[bot]
db8287df89 Bump actions/checkout from 4.1.0 to 4.1.1 (#18337)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-23 09:03:17 +02:00
renovate[bot]
71edbd6352 Update dependency sinon to v16.1.3 (#18325)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-22 13:05:20 -04:00
renovate[bot]
9d87a66908 Update dependency lint-staged to v15.0.2 (#18326)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-22 13:03:45 -04:00
renovate[bot]
11d62cece2 Lock file maintenance (#18284)
* Lock file maintenance

* Add resolution to keep lit at v2

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>
2023-10-22 03:34:14 +00:00
renovate[bot]
f15a65f5a6 Update dependency sinon to v16.1.1 (#18322)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-21 22:41:15 -04:00
renovate[bot]
a03d3f796b Update dependency @types/ua-parser-js to v0.7.38 (#18321) 2023-10-21 22:26:22 -04:00
renovate[bot]
d0f5b0e864 Update dependency @types/tar to v6.1.7 (#18320) 2023-10-21 23:43:59 +00:00
renovate[bot]
e4a67dd555 Update dependency @types/sortablejs to v1.15.4 (#18319) 2023-10-21 19:33:02 -04:00
renovate[bot]
f72ab94742 Update dependency @types/qrcode to v1.5.4 (#18317)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-21 23:22:48 +00:00
renovate[bot]
b521be6d3b Update dependency @types/serve-handler to v6.1.3 (#18318)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-21 19:11:27 -04:00
renovate[bot]
3fa7001be6 Update dependency @types/mocha to v10.0.3 (#18316)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-21 20:37:21 +00:00
renovate[bot]
b45226509b Update dependency @types/js-yaml to v4.0.8 (#18309)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-21 20:31:43 +00:00
renovate[bot]
2a5f8097bc Update dependency @types/luxon to v3.3.3 (#18315)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-21 16:24:47 -04:00
renovate[bot]
0ffe0f38e1 Update dependency @types/leaflet to v1.9.7 (#18310)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-21 20:19:23 +00:00
renovate[bot]
c48491088e Update dependency @codemirror/state to v6.3.1 (#18307)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-21 16:15:23 -04:00
renovate[bot]
f115e4025d Update dependency @types/html-minifier-terser to v7.0.1 (#18308)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-21 16:06:07 -04:00
renovate[bot]
7be8a799aa Update dependency @types/leaflet-draw to v1.0.9 (#18311)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-21 16:04:54 -04:00
karwosts
d992b2d40b Fix missing range labels in date-range-picker (#18274)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-10-21 15:40:38 +00:00
karwosts
96fbd8aefb Don't round statistic values before plotting (#18312) 2023-10-21 17:19:03 +02:00
renovate[bot]
17df761a1b Update dependency @types/esprima to v4.0.5 (#18304) 2023-10-20 23:44:38 -04:00
renovate[bot]
79b2fa96ed Update dependency @types/chromecast-caf-receiver to v6.0.11 (#18302) 2023-10-21 03:08:33 +00:00
renovate[bot]
c14e3333cf Update dependency @types/chromecast-caf-sender to v1.0.7 (#18303) 2023-10-20 22:56:56 -04:00
renovate[bot]
4af0ecbaa8 Update dependency @types/babel__plugin-transform-runtime to v7.9.4 (#18301) 2023-10-20 22:50:11 -04:00
Bram Kragten
ce11301516 Fix initial theming (#18296) 2023-10-20 20:44:53 +02:00
Josh McCarty
16766f8878 Wrap dict attributes (#18290) 2023-10-20 17:07:14 +02:00
renovate[bot]
5e933e8e15 Update typescript-eslint monorepo to v6.8.0 (#18292)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-19 23:28:11 -04:00
renovate[bot]
7eb92be84a Update formatjs monorepo (#18285)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-19 23:26:56 -04:00
Kendell R
60ec4d31db Fix some minor inconsistencies/duplications (#18071) 2023-10-19 17:29:05 +02:00
Steve Repsher
3526ba308f Remove unused imports from ZHA card and alias editor (#18282) 2023-10-19 17:17:27 +02:00
Steve Repsher
02a212a47d Load and set Polymer settings asynchronously (#18278) 2023-10-19 17:09:35 +02:00
Simon Vallières
49f88a98a5 Add multi-path icon support and path attributes (#18189) 2023-10-19 15:35:50 +02:00
Steve Repsher
feb371839c Fix yarn lock file (#18283) 2023-10-19 01:27:57 +02:00
renovate[bot]
24c37f5293 Update dependency @rollup/plugin-replace to v5.0.4 (#18280)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 18:25:15 -04:00
renovate[bot]
8f3fea5a33 Update dependency vis-network to v9.1.8 (#18281)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 18:24:28 -04:00
renovate[bot]
b2bc529d7b Update dependency @rollup/plugin-commonjs to v25.0.7 (#18279)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 18:23:24 -04:00
Jonas Lang
ad68782b79 Typo automation (#18266) 2023-10-18 13:42:30 +00:00
renovate[bot]
f432528388 Update dependency lint-staged to v15 (#18267)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 15:29:38 +02:00
Kendell R
f98c0769b0 Fix "No visual editor support for action: " (#18271) 2023-10-18 15:24:36 +02:00
Josh McCarty
b2cb0d8e0f Fixes alarm dialog inputmode for code input (#18263) 2023-10-17 12:23:40 +02:00
renovate[bot]
4c7c04bdc0 Update dependency marked to v9.1.2 (#18259) 2023-10-16 21:46:43 -04:00
renovate[bot]
ffb7469a7e Update dependency webpack to v5.89.0 (#18260) 2023-10-16 21:44:07 -04:00
Steve Repsher
d88831b719 Enable CORS for legacy bundle loading (#18248) 2023-10-16 20:40:15 +02:00
Steve Repsher
3b2f6d71f5 Minify ha-style/Roboto and load asynchronously (#18226) 2023-10-16 20:37:50 +02:00
Simon Lamon
a08185a1a5 Migrate developer state tools to LitElement (#18134)
Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>
2023-10-16 20:37:04 +02:00
renovate[bot]
7ee91ca8fc Update vaadinWebComponents monorepo to v24.2.0 (#18255)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-16 15:54:20 +02:00
Simon Lamon
b6fe0cfa1b Replace internal material/web usages (#18219)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-10-16 15:42:59 +02:00
karwosts
c3a9682861 An alias editor and overflow menu for choose options (#18183) 2023-10-16 14:02:34 +02:00
Simon Lamon
62d21bea4f Replace polymer paper-slider (#18168)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-10-16 13:35:13 +02:00
Steve Repsher
434b9595c0 Remove SystemJS loader from Webpack builds (#18249) 2023-10-16 12:42:46 +02:00
renovate[bot]
a0f1b7f365 Update dependency @codemirror/autocomplete to v6.10.2 (#18253)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-16 12:40:37 +02:00
dependabot[bot]
628c2c39cf Bump relative-ci/agent-action from 2.1.8 to 2.1.10 (#18252)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-16 09:04:34 +02:00
Bram Kragten
4b885cbd93 Remove narrow from strategies (#18201) 2023-10-16 00:20:36 -04:00
Simon Lamon
02d9786f8c Fix lokalise translation upload (#18221)
Fix translation upload
2023-10-15 23:52:12 -04:00
renovate[bot]
88d14cd7b5 Update dependency magic-string to v0.30.5 (#18238)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-15 16:53:32 -04:00
renovate[bot]
4ea8f599cf Update dependency @codemirror/state to v6.3.0 (#18228)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-15 16:52:50 -04:00
renovate[bot]
37ef444180 Update babel monorepo to v7.23.2 (#18223)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-15 01:10:47 +00:00
renovate[bot]
4253feb8a2 Update dependency marked to v9.1.1 (#18224)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-14 21:00:11 -04:00
renovate[bot]
ce33cf7ff3 Update dependency @codemirror/autocomplete to v6.10.1 (#18218)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-14 20:59:07 -04:00
renovate[bot]
faa4455951 Update dependency @bundle-stats/plugin-webpack-filter to v4.7.7 (#18220)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-14 15:57:36 -04:00
renovate[bot]
08d8b43f44 Update dependency @types/js-yaml to v4.0.7 (#18212) 2023-10-13 20:59:48 -04:00
Paul Bottein
15c67fe299 Improve state and name display on state-card-display (#18207) 2023-10-13 10:38:19 +02:00
renovate[bot]
a10ec1f53c Update typescript-eslint monorepo to v6.7.5 (#18203)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-12 15:47:12 -04:00
Bram Kragten
1b220abf70 run on all branches 2023-10-12 19:09:33 +02:00
Till
607175706b Add date range picker to energy period selector (#14337) 2023-10-12 18:29:04 +02:00
Bram Kragten
f8966a2114 Slug not needed for reactive ci (#18200) 2023-10-12 17:00:29 +02:00
G Johansson
4c94ac5dda CountrySelector (#18035) 2023-10-12 16:47:28 +02:00
Bram Kragten
6d1e923b83 Voice assistant dev: fix wake word continue (#18181)
Start wake word when continue when wake word was used the previous run
2023-10-12 16:10:14 +02:00
Bram Kragten
2c743b7b56 Update relative-ci.yaml (#18197) 2023-10-12 15:26:33 +02:00
tzagim
6686da1f24 Fix for RTL languages - Profile panel + weather forecast card (#18191) 2023-10-12 14:27:01 +02:00
renovate[bot]
6bdeb45f6b Update vaadinWebComponents monorepo to v24.1.11 (#18195)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-12 14:25:06 +02:00
Simon Lamon
9f05a9679b Fix RelativeCI input issues (#18196) 2023-10-12 14:17:13 +02:00
Simon Lamon
51a6376991 Fix RelativeCI format issues (#18194) 2023-10-12 12:35:11 +02:00
Simon Lamon
c5056eb4d2 Allow Multiple Entities for Numeric State Trigger (#18064) 2023-10-12 09:37:19 +02:00
Steve Repsher
79f3759756 Create webpack bundle stats for Relative CI (#18178) 2023-10-12 09:28:34 +02:00
renovate[bot]
6c3b748279 Update dependency @rollup/plugin-node-resolve to v15.2.3 (#18193) 2023-10-11 16:52:28 -04:00
Bram Kragten
4293192e74 Use progress button when adding/updating mount (#18182) 2023-10-11 13:22:56 +02:00
Bram Kragten
ceaceaf47b Move select clearing to ha-select (#18190) 2023-10-11 13:22:17 +02:00
Piero
479a625662 Update url on tab reorder (#18169)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-10-11 12:49:08 +02:00
fustom
095d171a61 Tile card current temperature for climate entity (#18143) 2023-10-11 09:01:34 +02:00
renovate[bot]
8c3a7de6d9 Update dependency @mdi/js to v7.3.67 (#18185)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-10 23:42:48 -04:00
renovate[bot]
84e743c4c0 Update dependency @mdi/svg to v7.3.67 (#18186)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-10 23:26:46 -04:00
Paul Bottein
51f8d91ddf Fix user name in config page (#18187) 2023-10-10 23:25:21 -04:00
Kendell R
8f1a6ef1b1 Improve password show/hide buttons (#18176) 2023-10-10 13:26:54 +00:00
Kendell R
b3f1783269 Say "log in" instead of "login" on the authorize page (#18175) 2023-10-10 12:47:31 +02:00
renovate[bot]
7e630d0fc5 Update dependency eslint to v8.51.0 (#18172) 2023-10-09 21:38:05 -04:00
renovate[bot]
a4533251a1 Update dependency vis-network to v9.1.7 (#18167)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-09 15:32:45 -04:00
renovate[bot]
659db109aa Update CodeMirror (#18166)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-09 15:31:34 -04:00
Kendell R
d3fd27910a Separate outline color (#18109) 2023-10-09 18:29:25 +02:00
Simon Lamon
eae3c1309f Localize durations using Intl.NumberFormat (#18067) 2023-10-09 18:28:08 +02:00
Thomas Konrad
4a5b67e320 Add 'max devices' config to Energy Devices Graph (#17553) 2023-10-09 17:27:22 +02:00
Paul Bottein
86c014b677 Add screen condition to conditional card. (#18041) 2023-10-09 15:06:58 +02:00
karwosts
5a6d6dc7d3 Fix period selector in statistic card (#18131) 2023-10-09 14:41:27 +02:00
Steve Repsher
294df396f4 Remove test language from production (really) (#18137) 2023-10-09 14:40:06 +02:00
renovate[bot]
cc01e8d6a8 Update dependency core-js to v3.33.0 (#18119)
* Update dependency core-js to v3.33.0

* Update babel setting

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>
2023-10-09 12:38:31 +00:00
Michael
a3532a41da Add before offset to sun condition description (#18152) 2023-10-09 14:36:16 +02:00
karwosts
ae35fd1eb8 Fix handling of negative zero in number selectors (#17127) 2023-10-09 14:34:16 +02:00
Simon Lamon
63095f1501 Replace paper-items in Scene Editor (#18101) 2023-10-09 14:29:58 +02:00
Steve Repsher
bf9e2cd404 Move polyfill time zone data out of bundles (#18142) 2023-10-09 14:28:16 +02:00
Bram Kragten
5b7ef941e4 Make it possible to clear an optional select (#18047) 2023-10-09 14:24:18 +02:00
ildar170975
352e721d0c Update state-badge.ts: change border-radius for media_player (#18066) 2023-10-09 14:11:29 +02:00
ildar170975
220b4794c5 Update developer-tools-state.js: fix alignment for ha-tips (#17608) 2023-10-09 13:59:09 +02:00
karwosts
811ebde42a Add per-set theme coloring to remainder of energy dashboard (#17826) 2023-10-09 13:55:21 +02:00
ildar170975
bfeee618f4 more-info: make long states "multilined" (#17649)
* align info when a state is multiline

* Enable multiline for long states

* Update state-info.ts

* Update state-card-display.ts
2023-10-09 13:52:03 +02:00
karwosts
db9b16e9f5 Change help link in statistics pickers in energy dashboard (#18138) 2023-10-09 13:47:46 +02:00
Philip Allgaier
7861d813b1 Add translations for voice assistant debug page (#17843)
* Add translations for voice assistant debug page

* Apply suggestions from code review

---------

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-10-09 11:46:59 +00:00
breakthestatic
d7760c4b7a Expose history replace in action editor (#17740)
* Expose existing navigation history replace to the UI

* Remove navigation_replace from GUI editor

* Restore default value
2023-10-09 12:02:30 +02:00
dependabot[bot]
a60a721ea5 Bump home-assistant/wheels from 2023.10.1 to 2023.10.4 (#18162)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-09 08:40:14 +02:00
renovate[bot]
36219e1cb4 Update dependency marked to v9.1.0 (#18148)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-08 13:33:17 -04:00
renovate[bot]
7fdbc9dd32 Update dependency sinon to v16.1.0 (#18158)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-08 13:31:05 -04:00
renovate[bot]
334be93254 Update dependency @rollup/plugin-commonjs to v25.0.5 (#18154)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-08 17:28:14 +00:00
renovate[bot]
c14a6d59e2 Update dependency @rollup/plugin-replace to v5.0.3 (#18157)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-08 13:19:25 -04:00
renovate[bot]
7a8139b650 Update dependency @rollup/plugin-json to v6.0.1 (#18155)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-08 17:16:16 +00:00
renovate[bot]
9d2a443217 Update dependency @rollup/plugin-babel to v6.0.4 (#18153)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-08 13:07:16 -04:00
renovate[bot]
484b166233 Update dependency @rollup/plugin-node-resolve to v15.2.2 (#18156)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-08 13:04:52 -04:00
renovate[bot]
530208cb6a Update Yarn to v3.6.4 (#18139)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-07 00:01:49 -04:00
renovate[bot]
b534ff8ca3 Update dependency @codemirror/view to v6.21.2 (#18132) 2023-10-05 20:17:36 -04:00
renovate[bot]
02bd50c434 Update typescript-eslint monorepo to v6.7.4 (#18128) 2023-10-05 20:14:53 -04:00
Paul Bottein
9a84ce7b81 20231005.0 (#18126)
* Update dependency @material/web to v1.0.0 (#18070)

* Update dependency @material/web to v1.0.0

* Fix icon button size

* Remove unused ios override

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Paul Bottein <paul.bottein@gmail.com>

* Update dependency magic-string to v0.30.4 (#18089)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Bump postcss from 8.4.30 to 8.4.31 (#18110)

Bumps [postcss](https://github.com/postcss/postcss) from 8.4.30 to 8.4.31.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.30...8.4.31)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Update CodeMirror (#18096)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update vaadinWebComponents monorepo to v24.1.10 (#18092)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Make the "icon next/prev" series load faster (#18087)

* Preserve ancillary fields in a repeat action when modifying the form (#18068)

* Do not clear alias when editing automation action, condition or trigger (#18114)

* Use restart dialog confirmation for quick command (#18113)

* Add translations for restore backup dialogs (#18112)

Co-authored-by: c0ffeeca7 <38767475+c0ffeeca7@users.noreply.github.com>

* Hide tooltip after clicking on a chart to display more info (cosmetic change) (#18103)

* fix setting wake word to first option everytime (#18121)

* Fix class field for ha-icon-next/prev (#18118)

* Set border-radius to 0 for img in thread panel (#18124)

* Load Intl locale data in parallel (#18120)

* Load Intl locale data in parallel

* Switch to check result.ok

* Update dependency @codemirror/view to v6.21.1 (#18125)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Bumped version to 20231005.0

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Kendell R <KTibow@users.noreply.github.com>
Co-authored-by: karwosts <32912880+karwosts@users.noreply.github.com>
Co-authored-by: c0ffeeca7 <38767475+c0ffeeca7@users.noreply.github.com>
Co-authored-by: K3A <966992+k3a@users.noreply.github.com>
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>
2023-10-05 18:29:15 +02:00
Paul Bottein
6e00be6684 Bumped version to 20231005.0 2023-10-05 18:28:19 +02:00
renovate[bot]
91ec43b9bc Update dependency @codemirror/view to v6.21.1 (#18125)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-05 18:19:22 +02:00
Steve Repsher
4a4d9a08d5 Load Intl locale data in parallel (#18120)
* Load Intl locale data in parallel

* Switch to check result.ok
2023-10-05 10:26:15 -04:00
Paul Bottein
0c32d1eb4e Set border-radius to 0 for img in thread panel (#18124) 2023-10-05 15:48:18 +02:00
Steve Repsher
f43171f91c Fix class field for ha-icon-next/prev (#18118) 2023-10-05 12:52:31 +00:00
Bram Kragten
48593eee0d fix setting wake word to first option everytime (#18121) 2023-10-05 11:30:05 +02:00
K3A
c106a0ac85 Hide tooltip after clicking on a chart to display more info (cosmetic change) (#18103) 2023-10-05 11:28:07 +02:00
Paul Bottein
e1a71fbfaa Add translations for restore backup dialogs (#18112)
Co-authored-by: c0ffeeca7 <38767475+c0ffeeca7@users.noreply.github.com>
2023-10-05 11:26:50 +02:00
Paul Bottein
0489d8922e Use restart dialog confirmation for quick command (#18113) 2023-10-05 11:24:43 +02:00
Paul Bottein
d7f1e9d091 Do not clear alias when editing automation action, condition or trigger (#18114) 2023-10-05 11:23:44 +02:00
karwosts
32bc8bd01d Preserve ancillary fields in a repeat action when modifying the form (#18068) 2023-10-04 14:36:58 +02:00
Kendell R
242b018ece Make the "icon next/prev" series load faster (#18087) 2023-10-04 13:59:51 +02:00
renovate[bot]
c25447d001 Update vaadinWebComponents monorepo to v24.1.10 (#18092)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-04 13:57:42 +02:00
renovate[bot]
d2d718475f Update CodeMirror (#18096)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-04 13:56:13 +02:00
dependabot[bot]
8e1e42cd50 Bump postcss from 8.4.30 to 8.4.31 (#18110)
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.30 to 8.4.31.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.30...8.4.31)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-04 03:29:36 +00:00
renovate[bot]
014f9b8b73 Update dependency magic-string to v0.30.4 (#18089)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-03 23:15:36 -04:00
renovate[bot]
774c7e275c Update dependency @material/web to v1.0.0 (#18070)
* Update dependency @material/web to v1.0.0

* Fix icon button size

* Remove unused ios override

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
2023-10-03 09:48:27 +00:00
Bram Kragten
75c43d15e1 20231002.0 (#18102) 2023-10-02 21:43:12 +02:00
Bram Kragten
e288b003d8 Bumped version to 20231002.0 2023-10-02 21:41:37 +02:00
yousaf465
4aa8518ed6 Change Urdu language to RTL (#18063)
Co-authored-by: karwosts <32912880+karwosts@users.noreply.github.com>
2023-10-02 21:26:07 +02:00
Bram Kragten
6acbf6395c Ignore prettier styling for tooltip of disk life time (#18097) 2023-10-02 21:23:13 +02:00
Bram Kragten
2030feabf7 Only set wakeword when not in new wakewords (#18095) 2023-10-02 21:23:02 +02:00
Bram Kragten
46d1dbcb47 Dont continue debug assist run when disconnected (#18098) 2023-10-02 21:22:50 +02:00
Bram Kragten
2f6297ec17 Always deduplicate found integrations in onboarding (#18091)
always deduplicate found integrations in onboarding
2023-10-02 14:30:28 +02:00
Paul Bottein
a3400a2f9c Prevent ha-form data lost if quick data updates (#18094) 2023-10-02 11:44:43 +02:00
Kendell R
c345f41416 Factor out style data to reduce bundle size (#18077) 2023-10-02 11:18:44 +02:00
Kendell R
292cdc7621 Fix clicking on radio buttons (and improve code) (#18078) 2023-10-02 10:58:10 +02:00
dependabot[bot]
c5ba74e0b4 Bump home-assistant/wheels from 2023.09.1 to 2023.10.1 (#18088)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-02 08:54:53 +02:00
renovate[bot]
41b24de559 Update dependency chai to v4.3.10 (#18082) 2023-10-01 20:24:14 -04:00
renovate[bot]
4fe7b18161 Update dependency chai to v4.3.9 (#18074)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-30 16:17:27 -04:00
renovate[bot]
399a979c33 Update dependency glob to v10.3.10 (#18072)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-30 16:16:20 -04:00
renovate[bot]
03c5482860 Update dependency @types/mocha to v10.0.2 (#18075)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-30 16:15:30 -04:00
Franck Nijhof
a116a50604 Hide shopping list from discovered onboarding integrations (#18069) 2023-09-29 22:39:57 +02:00
renovate[bot]
0dfa292c40 Update dependency glob to v10.3.9 (#18060)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-29 13:30:08 -04:00
Bram Kragten
5914a6c1a4 Clear wake word when new engine is picked, select first wake word. by… (#18058)
* Clear wake word when new engine is picked, select first wake word. by default

* Update assist-pipeline-detail-wakeword.ts
2023-09-29 12:38:11 +02:00
Paul Bottein
47022d3a04 20230928.0 (#18052) 2023-09-28 20:15:04 +02:00
Bram Kragten
60345f3fe8 20230926.0 (#18037) 2023-09-26 23:56:14 +02:00
Bram Kragten
40bb6566b8 20230911.0 (#17901) 2023-09-11 18:30:42 +02:00
Bram Kragten
db272e3e18 20230908.0 (#17866) 2023-09-08 15:56:12 +02:00
Bram Kragten
35496ead23 20230906.1 (#17838) 2023-09-06 13:47:02 +02:00
Bram Kragten
41403a5d35 20230906.0 (#17834) 2023-09-06 09:54:26 +02:00
Bram Kragten
8acf557137 20230905.0 (#17828) 2023-09-05 18:11:08 +02:00
Bram Kragten
4e62370d18 20230904.0 (#17819) 2023-09-04 19:18:58 +02:00
Bram Kragten
f90ab60354 20230901.0 (#17782) 2023-09-01 17:02:38 +02:00
Bram Kragten
d187aa0ac6 20230831.0 (#17756) 2023-08-31 14:38:24 +02:00
Bram Kragten
96597b3963 20230830.0 (#17737) 2023-08-30 15:48:10 +02:00
485 changed files with 18821 additions and 13212 deletions

View File

@@ -21,12 +21,12 @@ jobs:
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
steps:
- name: Check out files from GitHub
uses: actions/checkout@v4.1.0
uses: actions/checkout@v4.1.1
with:
ref: dev
- name: Setup Node
uses: actions/setup-node@v3.8.1
uses: actions/setup-node@v4.0.0
with:
node-version-file: ".nvmrc"
cache: yarn
@@ -57,12 +57,12 @@ jobs:
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
steps:
- name: Check out files from GitHub
uses: actions/checkout@v4.1.0
uses: actions/checkout@v4.1.1
with:
ref: master
- name: Setup Node
uses: actions/setup-node@v3.8.1
uses: actions/setup-node@v4.0.0
with:
node-version-file: ".nvmrc"
cache: yarn

View File

@@ -24,9 +24,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out files from GitHub
uses: actions/checkout@v4.1.0
uses: actions/checkout@v4.1.1
- name: Setup Node
uses: actions/setup-node@v3.8.1
uses: actions/setup-node@v4.0.0
with:
node-version-file: ".nvmrc"
cache: yarn
@@ -55,9 +55,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out files from GitHub
uses: actions/checkout@v4.1.0
uses: actions/checkout@v4.1.1
- name: Setup Node
uses: actions/setup-node@v3.8.1
uses: actions/setup-node@v4.0.0
with:
node-version-file: ".nvmrc"
cache: yarn
@@ -73,9 +73,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out files from GitHub
uses: actions/checkout@v4.1.0
uses: actions/checkout@v4.1.1
- name: Setup Node
uses: actions/setup-node@v3.8.1
uses: actions/setup-node@v4.0.0
with:
node-version-file: ".nvmrc"
cache: yarn
@@ -85,15 +85,21 @@ jobs:
run: ./node_modules/.bin/gulp build-app
env:
IS_TEST: "true"
- name: Upload bundle stats
uses: actions/upload-artifact@v3.1.3
with:
name: frontend-bundle-stats
path: build/stats/*.json
if-no-files-found: error
supervisor:
name: Build supervisor
needs: [lint, test]
runs-on: ubuntu-latest
steps:
- name: Check out files from GitHub
uses: actions/checkout@v4.1.0
uses: actions/checkout@v4.1.1
- name: Setup Node
uses: actions/setup-node@v3.8.1
uses: actions/setup-node@v4.0.0
with:
node-version-file: ".nvmrc"
cache: yarn
@@ -103,3 +109,9 @@ jobs:
run: ./node_modules/.bin/gulp build-hassio
env:
IS_TEST: "true"
- name: Upload bundle stats
uses: actions/upload-artifact@v3.1.3
with:
name: supervisor-bundle-stats
path: build/stats/*.json
if-no-files-found: error

View File

@@ -23,7 +23,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4.1.0
uses: actions/checkout@v4.1.1
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.

View File

@@ -22,12 +22,12 @@ jobs:
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
steps:
- name: Check out files from GitHub
uses: actions/checkout@v4.1.0
uses: actions/checkout@v4.1.1
with:
ref: dev
- name: Setup Node
uses: actions/setup-node@v3.8.1
uses: actions/setup-node@v4.0.0
with:
node-version-file: ".nvmrc"
cache: yarn
@@ -58,12 +58,12 @@ jobs:
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
steps:
- name: Check out files from GitHub
uses: actions/checkout@v4.1.0
uses: actions/checkout@v4.1.1
with:
ref: master
- name: Setup Node
uses: actions/setup-node@v3.8.1
uses: actions/setup-node@v4.0.0
with:
node-version-file: ".nvmrc"
cache: yarn

View File

@@ -16,10 +16,10 @@ jobs:
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
steps:
- name: Check out files from GitHub
uses: actions/checkout@v4.1.0
uses: actions/checkout@v4.1.1
- name: Setup Node
uses: actions/setup-node@v3.8.1
uses: actions/setup-node@v4.0.0
with:
node-version-file: ".nvmrc"
cache: yarn

View File

@@ -21,10 +21,10 @@ jobs:
if: github.repository == 'home-assistant/frontend' && contains(github.event.pull_request.labels.*.name, 'needs design preview')
steps:
- name: Check out files from GitHub
uses: actions/checkout@v4.1.0
uses: actions/checkout@v4.1.1
- name: Setup Node
uses: actions/setup-node@v3.8.1
uses: actions/setup-node@v4.0.0
with:
node-version-file: ".nvmrc"
cache: yarn

View File

@@ -20,7 +20,7 @@ jobs:
contents: write
steps:
- name: Checkout the repository
uses: actions/checkout@v4.1.0
uses: actions/checkout@v4.1.1
- name: Set up Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v4
@@ -28,7 +28,7 @@ jobs:
python-version: ${{ env.PYTHON_VERSION }}
- name: Setup Node
uses: actions/setup-node@v3.8.1
uses: actions/setup-node@v4.0.0
with:
node-version-file: ".nvmrc"
cache: yarn
@@ -57,14 +57,14 @@ jobs:
run: tar -czvf translations.tar.gz translations
- name: Upload build artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v3.1.3
with:
name: wheels
path: dist/home_assistant_frontend*.whl
if-no-files-found: error
- name: Upload translations
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v3.1.3
with:
name: translations
path: translations.tar.gz

25
.github/workflows/relative-ci.yaml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: RelativeCI
on:
workflow_run:
workflows: [CI]
types:
- completed
jobs:
upload:
name: Upload stats
if: ${{ github.event.workflow_run.conclusion == 'success' }}
strategy:
matrix:
bundle: [frontend, supervisor]
build: [modern, legacy]
runs-on: ubuntu-latest
steps:
- name: Send bundle stats and build information to RelativeCI
uses: relative-ci/agent-action@v2.1.10
with:
key: ${{ secrets[format('RELATIVE_CI_KEY_{0}_{1}', matrix.bundle, matrix.build)] }}
token: ${{ github.token }}
artifactName: ${{ format('{0}-bundle-stats', matrix.bundle) }}
webpackStatsFile: ${{ format('{0}-{1}.json', matrix.bundle, matrix.build) }}

View File

@@ -23,7 +23,7 @@ jobs:
contents: write # Required to upload release assets
steps:
- name: Checkout the repository
uses: actions/checkout@v4.1.0
uses: actions/checkout@v4.1.1
- name: Verify version
uses: home-assistant/actions/helpers/verify-version@master
@@ -34,7 +34,7 @@ jobs:
python-version: ${{ env.PYTHON_VERSION }}
- name: Setup Node
uses: actions/setup-node@v3.8.1
uses: actions/setup-node@v4.0.0
with:
node-version-file: ".nvmrc"
cache: yarn
@@ -74,7 +74,7 @@ jobs:
echo "home-assistant-frontend==$version" > ./requirements.txt
- name: Build wheels
uses: home-assistant/wheels@2023.09.1
uses: home-assistant/wheels@2023.10.5
with:
abi: cp311
tag: musllinux_1_2

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v4.1.0
uses: actions/checkout@v4.1.1
- name: Upload Translations
run: |

3
.gitignore vendored
View File

@@ -47,3 +47,6 @@ src/cast/dev_const.ts
# Home Assistant config
/config/
# Jetbrains
/.idea/

2
.nvmrc
View File

@@ -1 +1 @@
18
lts/iron

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

893
.yarn/releases/yarn-4.0.1.cjs vendored Executable file

File diff suppressed because one or more lines are too long

View File

@@ -1,11 +1,9 @@
compressionLevel: mixed
defaultSemverRangePrefix: ""
enableGlobalCache: false
nodeLinker: node-modules
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-typescript.cjs
spec: "@yarnpkg/plugin-typescript"
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"
yarnPath: .yarn/releases/yarn-3.6.3.cjs
yarnPath: .yarn/releases/yarn-4.0.1.cjs

View File

@@ -12,11 +12,7 @@ module.exports.sourceMapURL = () => {
};
// Files from NPM Packages that should not be imported
// eslint-disable-next-line unused-imports/no-unused-vars
module.exports.ignorePackages = ({ latestBuild }) => [
// Part of yaml.js and only used for !!js functions that we don't use
require.resolve("esprima"),
];
module.exports.ignorePackages = () => [];
// Files from NPM packages that we should replace with empty file
module.exports.emptyPackages = ({ latestBuild, isHassioBuild }) =>
@@ -98,7 +94,7 @@ module.exports.babelOptions = ({ latestBuild, isProdBuild, isTestBuild }) => ({
"@babel/preset-env",
{
useBuiltIns: latestBuild ? false : "entry",
corejs: latestBuild ? false : { version: "3.32", proposals: true },
corejs: latestBuild ? false : { version: "3.33", proposals: true },
bugfixes: true,
shippedProposals: true,
},
@@ -149,7 +145,7 @@ module.exports.babelOptions = ({ latestBuild, isProdBuild, isTestBuild }) => ({
sourceMaps: !isTestBuild,
});
const nameSuffix = (latestBuild) => (latestBuild ? "-latest" : "-es5");
const nameSuffix = (latestBuild) => (latestBuild ? "-modern" : "-legacy");
const outputPath = (outputRoot, latestBuild) =>
path.resolve(outputRoot, latestBuild ? "frontend_latest" : "frontend_es5");
@@ -183,7 +179,7 @@ const publicPath = (latestBuild, root = "") =>
module.exports.config = {
app({ isProdBuild, latestBuild, isStatsBuild, isTestBuild, isWDS }) {
return {
name: "app" + nameSuffix(latestBuild),
name: "frontend" + nameSuffix(latestBuild),
entry: {
service_worker: "./src/entrypoints/service_worker.ts",
app: "./src/entrypoints/app.ts",

View File

@@ -45,8 +45,8 @@ gulp.task(
gulp.parallel("gen-icons-json", "build-translations", "build-locale-data"),
"copy-static-app",
env.useRollup() ? "rollup-prod-app" : "webpack-prod-app",
gulp.parallel("gen-pages-app-prod", "gen-service-worker-app-prod"),
// Don't compress running tests
...(env.isTestBuild() ? [] : ["compress-app"]),
gulp.parallel("gen-pages-app-prod", "gen-service-worker-app-prod")
...(env.isTestBuild() ? [] : ["compress-app"])
)
);

View File

@@ -4,6 +4,7 @@ import fs from "fs-extra";
import gulp from "gulp";
import path from "path";
import paths from "../paths.cjs";
import env from "../env.cjs";
const npmPath = (...parts) =>
path.resolve(paths.polymer_dir, "node_modules", ...parts);
@@ -62,6 +63,9 @@ function copyPolyfills(staticDir) {
}
function copyLoaderJS(staticDir) {
if (!env.useRollup()) {
return;
}
const staticPath = genStaticPath(staticDir);
copyFileDir(npmPath("systemjs/dist/s.min.js"), staticPath("js"));
copyFileDir(npmPath("systemjs/dist/s.min.js.map"), staticPath("js"));

View File

@@ -1,51 +1,54 @@
import { deleteSync } from "del";
import { mkdir, readFile, writeFile } from "fs/promises";
import gulp from "gulp";
import path from "path";
import { join, resolve } from "node:path";
import paths from "../paths.cjs";
const outDir = path.join(paths.build_dir, "locale-data");
const formatjsDir = join(paths.polymer_dir, "node_modules", "@formatjs");
const outDir = join(paths.build_dir, "locale-data");
const INTL_PACKAGES = {
"intl-relativetimeformat": "RelativeTimeFormat",
const INTL_POLYFILLS = {
"intl-datetimeformat": "DateTimeFormat",
"intl-numberformat": "NumberFormat",
"intl-displaynames": "DisplayNames",
"intl-listformat": "ListFormat",
"intl-numberformat": "NumberFormat",
"intl-relativetimeformat": "RelativeTimeFormat",
};
const convertToJSON = async (pkg, lang) => {
const convertToJSON = async (
pkg,
lang,
subDir = "locale-data",
addFunc = "__addLocaleData",
skipMissing = true
) => {
let localeData;
try {
localeData = await readFile(
path.resolve(
paths.polymer_dir,
`node_modules/@formatjs/${pkg}/locale-data/${lang}.js`
),
join(formatjsDir, pkg, subDir, `${lang}.js`),
"utf-8"
);
} catch (e) {
// Ignore if language is missing (i.e. not supported by @formatjs)
if (e.code === "ENOENT") {
if (e.code === "ENOENT" && skipMissing) {
console.warn(`Skipped missing data for language ${lang} from ${pkg}`);
return;
} else {
throw e;
}
throw e;
}
// Convert to JSON
const className = INTL_PACKAGES[pkg];
localeData = localeData
.replace(
new RegExp(
`\\/\\*\\s*@generated\\s*\\*\\/\\s*\\/\\/\\s*prettier-ignore\\s*if\\s*\\(Intl\\.${className}\\s*&&\\s*typeof\\s*Intl\\.${className}\\.__addLocaleData\\s*===\\s*'function'\\)\\s*{\\s*Intl\\.${className}\\.__addLocaleData\\(`,
"im"
),
""
)
.replace(/\)\s*}/im, "");
const obj = INTL_POLYFILLS[pkg];
const dataRegex = new RegExp(
`Intl\\.${obj}\\.${addFunc}\\((?<data>.*)\\)`,
"s"
);
localeData = localeData.match(dataRegex)?.groups?.data;
if (!localeData) {
throw Error(`Failed to extract data for language ${lang} from ${pkg}`);
}
// Parse to validate JSON, then stringify to minify
localeData = JSON.stringify(JSON.parse(localeData));
await writeFile(path.join(outDir, `${pkg}/${lang}.json`), localeData);
await writeFile(join(outDir, `${pkg}/${lang}.json`), localeData);
};
gulp.task("clean-locale-data", async () => deleteSync([outDir]));
@@ -53,17 +56,27 @@ gulp.task("clean-locale-data", async () => deleteSync([outDir]));
gulp.task("create-locale-data", async () => {
const translationMeta = JSON.parse(
await readFile(
path.resolve(paths.translations_src, "translationMetadata.json"),
resolve(paths.translations_src, "translationMetadata.json"),
"utf-8"
)
);
const conversions = [];
for (const pkg of Object.keys(INTL_PACKAGES)) {
await mkdir(path.join(outDir, pkg), { recursive: true });
for (const pkg of Object.keys(INTL_POLYFILLS)) {
// eslint-disable-next-line no-await-in-loop
await mkdir(join(outDir, pkg), { recursive: true });
for (const lang of Object.keys(translationMeta)) {
conversions.push(convertToJSON(pkg, lang));
}
}
conversions.push(
convertToJSON(
"intl-datetimeformat",
"add-all-tz",
".",
"__addTZData",
false
)
);
await Promise.all(conversions);
});

View File

@@ -1,12 +1,7 @@
import { createHash } from "crypto";
import { deleteSync } from "del";
import {
mkdirSync,
readdirSync,
readFileSync,
renameSync,
writeFile,
} from "fs";
import { mkdirSync, readdirSync, readFileSync, renameSync } from "fs";
import { writeFile } from "node:fs/promises";
import gulp from "gulp";
import flatmap from "gulp-flatmap";
import transform from "gulp-json-transform";
@@ -136,27 +131,23 @@ gulp.task("ensure-translations-build-dir", async () => {
mkdirSync(workDir, { recursive: true });
});
gulp.task("create-test-metadata", (cb) => {
writeFile(
workDir + "/testMetadata.json",
JSON.stringify({
test: {
nativeName: "Test",
},
}),
cb
);
});
gulp.task("create-test-metadata", () =>
env.isProdBuild()
? Promise.resolve()
: writeFile(
workDir + "/testMetadata.json",
JSON.stringify({ test: { nativeName: "Test" } })
)
);
gulp.task(
"create-test-translation",
gulp.series("create-test-metadata", () =>
gulp
.src(path.join(paths.translations_src, "en.json"))
.pipe(transform((data, _file) => recursiveEmpty(data)))
.pipe(rename("test.json"))
.pipe(gulp.dest(workDir))
)
gulp.task("create-test-translation", () =>
env.isProdBuild()
? Promise.resolve()
: gulp
.src(path.join(paths.translations_src, "en.json"))
.pipe(transform((data, _file) => recursiveEmpty(data)))
.pipe(rename("test.json"))
.pipe(gulp.dest(workDir))
);
/**
@@ -188,16 +179,11 @@ gulp.task("build-master-translation", () => {
gulp.task("build-merged-translations", () =>
gulp
.src(
[
inFrontendDir + "/*.json",
"!" + inFrontendDir + "/en.json",
workDir + "/test.json",
],
{
allowEmpty: true,
}
)
.src([
inFrontendDir + "/*.json",
"!" + inFrontendDir + "/en.json",
...(env.isProdBuild() ? [] : [workDir + "/test.json"]),
])
.pipe(transform((data, file) => lokaliseTransform(data, data, file)))
.pipe(
flatmap((stream, file) => {
@@ -377,14 +363,11 @@ gulp.task("build-translation-flatten-supervisor", () =>
gulp.task("build-translation-write-metadata", () =>
gulp
.src(
[
path.join(paths.translations_src, "translationMetadata.json"),
workDir + "/testMetadata.json",
workDir + "/translationFingerprints.json",
],
{ allowEmpty: true }
)
.src([
path.join(paths.translations_src, "translationMetadata.json"),
...(env.isProdBuild() ? [] : [workDir + "/testMetadata.json"]),
workDir + "/translationFingerprints.json",
])
.pipe(merge({}))
.pipe(
transform((data) => {
@@ -415,7 +398,7 @@ gulp.task("build-translation-write-metadata", () =>
gulp.task(
"create-translations",
gulp.series(
...(env.isProdBuild() ? [] : ["create-test-translation"]),
gulp.parallel("create-test-metadata", "create-test-translation"),
"build-master-translation",
"build-merged-translations",
gulp.parallel(...splitTasks),

View File

@@ -1,6 +1,8 @@
const { existsSync } = require("fs");
const path = require("path");
const webpack = require("webpack");
const { StatsWriterPlugin } = require("webpack-stats-plugin");
const filterStats = require("@bundle-stats/plugin-webpack-filter").default;
const TerserPlugin = require("terser-webpack-plugin");
const { WebpackManifestPlugin } = require("webpack-manifest-plugin");
const log = require("fancy-log");
@@ -152,6 +154,15 @@ const createWebpackConfig = ({
)
),
!isProdBuild && new LogStartCompilePlugin(),
isProdBuild &&
new StatsWriterPlugin({
filename: path.relative(
outputPath,
path.join(paths.build_dir, "stats", `${name}.json`)
),
stats: { assets: true, chunks: true, modules: true },
transform: (stats) => JSON.stringify(filterStats(stats)),
}),
].filter(Boolean),
resolve: {
extensions: [".ts", ".js", ".json"],
@@ -171,6 +182,8 @@ const createWebpackConfig = ({
"@lit-labs/virtualizer/layouts/grid.js",
"@lit-labs/virtualizer/polyfills/resize-observer-polyfill/ResizeObserver":
"@lit-labs/virtualizer/polyfills/resize-observer-polyfill/ResizeObserver.js",
"@lit-labs/observers/resize-controller":
"@lit-labs/observers/resize-controller.js",
},
},
output: {
@@ -183,6 +196,7 @@ const createWebpackConfig = ({
isProdBuild && !isStatsBuild ? "[id]-[contenthash].js" : "[name].js",
assetModuleFilename:
isProdBuild && !isStatsBuild ? "[id]-[contenthash][ext]" : "[id][ext]",
crossOriginLoading: "use-credentials",
hashFunction: "xxhash64",
hashDigest: "base64url",
hashDigestLength: 11, // full length of 64 bit base64url

View File

@@ -1,4 +1,4 @@
import "../../../src/resources/safari-14-attachshadow-patch";
import "../../../src/resources/ha-style";
import "../../../src/resources/roboto";
import "./layout/hc-connect";
import("../../../src/resources/ha-style");

View File

@@ -3,7 +3,7 @@ import { mdiCast, mdiCastConnected } from "@mdi/js";
import "@polymer/paper-item/paper-icon-item";
import "@polymer/paper-listbox/paper-listbox";
import { Auth, Connection } from "home-assistant-js-websocket";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { CSSResultGroup, LitElement, TemplateResult, css, html } from "lit";
import { customElement, property, state } from "lit/decorators";
import { CastManager } from "../../../../src/cast/cast_manager";
import {
@@ -22,8 +22,9 @@ import "../../../../src/components/ha-svg-icon";
import {
getLegacyLovelaceCollection,
getLovelaceCollection,
LovelaceConfig,
} from "../../../../src/data/lovelace";
import { isStrategyDashboard } from "../../../../src/data/lovelace/config/types";
import { LovelaceViewConfig } from "../../../../src/data/lovelace/config/view";
import "../../../../src/layouts/hass-loading-screen";
import { generateDefaultViewConfig } from "../../../../src/panels/lovelace/common/generate-lovelace-config";
import "./hc-layout";
@@ -38,10 +39,10 @@ class HcCast extends LitElement {
@state() private askWrite = false;
@state() private lovelaceConfig?: LovelaceConfig | null;
@state() private lovelaceViews?: LovelaceViewConfig[] | null;
protected render(): TemplateResult {
if (this.lovelaceConfig === undefined) {
if (this.lovelaceViews === undefined) {
return html`<hass-loading-screen no-toolbar></hass-loading-screen>`;
}
@@ -86,9 +87,10 @@ class HcCast extends LitElement {
attr-for-selected="data-path"
.selected=${this.castManager.status.lovelacePath || ""}
>
${(this.lovelaceConfig
? this.lovelaceConfig.views
: [generateDefaultViewConfig({}, {}, {}, {}, () => "")]
${(
this.lovelaceViews ?? [
generateDefaultViewConfig({}, {}, {}, {}, () => ""),
]
).map(
(view, idx) => html`
<paper-icon-item
@@ -136,11 +138,15 @@ class HcCast extends LitElement {
llColl.refresh().then(
() => {
llColl.subscribe((config) => {
this.lovelaceConfig = config;
if (isStrategyDashboard(config)) {
this.lovelaceViews = null;
} else {
this.lovelaceViews = config.views;
}
});
},
async () => {
this.lovelaceConfig = null;
this.lovelaceViews = null;
}
);
@@ -159,9 +165,7 @@ class HcCast extends LitElement {
toggleAttribute(
this,
"hide-icons",
this.lovelaceConfig
? !this.lovelaceConfig.views.some((view) => view.icon)
: true
this.lovelaceViews ? !this.lovelaceViews.some((view) => view.icon) : true
);
}

View File

@@ -1,7 +1,5 @@
import {
LovelaceCardConfig,
LovelaceConfig,
} from "../../../../src/data/lovelace";
import { LovelaceCardConfig } from "../../../../src/data/lovelace/config/card";
import { LovelaceConfig } from "../../../../src/data/lovelace/config/types";
import { castContext } from "../cast_context";
export const castDemoLovelace: () => LovelaceConfig = () => {

View File

@@ -1,7 +1,7 @@
import { html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { mockHistory } from "../../../../demo/src/stubs/history";
import { LovelaceConfig } from "../../../../src/data/lovelace";
import { LovelaceConfig } from "../../../../src/data/lovelace/config/types";
import {
MockHomeAssistant,
provideHass,

View File

@@ -1,7 +1,7 @@
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, query } from "lit/decorators";
import { fireEvent } from "../../../../src/common/dom/fire_event";
import { LovelaceConfig } from "../../../../src/data/lovelace";
import { LovelaceConfig } from "../../../../src/data/lovelace/config/types";
import { Lovelace } from "../../../../src/panels/lovelace/types";
import "../../../../src/panels/lovelace/views/hui-view";
import { HomeAssistant } from "../../../../src/types";
@@ -14,7 +14,8 @@ import "./hc-launch-screen";
class HcLovelace extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public lovelaceConfig!: LovelaceConfig;
@property({ attribute: false })
public lovelaceConfig!: LovelaceConfig;
@property() public viewPath?: string | number;

View File

@@ -21,18 +21,26 @@ import {
import { atLeastVersion } from "../../../../src/common/config/version";
import { isNavigationClick } from "../../../../src/common/dom/is-navigation-click";
import {
fetchResources,
getLegacyLovelaceCollection,
getLovelaceCollection,
} from "../../../../src/data/lovelace";
import {
isStrategyDashboard,
LegacyLovelaceConfig,
LovelaceConfig,
} from "../../../../src/data/lovelace";
LovelaceDashboardStrategyConfig,
} from "../../../../src/data/lovelace/config/types";
import { fetchResources } from "../../../../src/data/lovelace/resource";
import { loadLovelaceResources } from "../../../../src/panels/lovelace/common/load-resources";
import { HassElement } from "../../../../src/state/hass-element";
import { castContext } from "../cast_context";
import "./hc-launch-screen";
const DEFAULT_STRATEGY = "original-states";
const DEFAULT_CONFIG: LovelaceDashboardStrategyConfig = {
strategy: {
type: "original-states",
},
};
let resourcesLoaded = false;
@customElement("hc-main")
@@ -93,14 +101,16 @@ export class HcMain extends HassElement {
.lovelaceConfig=${this._lovelaceConfig}
.viewPath=${this._lovelacePath}
.urlPath=${this._urlPath}
@config-refresh=${this._generateLovelaceConfig}
@config-refresh=${this._generateDefaultLovelaceConfig}
></hc-lovelace>
`;
}
protected firstUpdated(changedProps) {
super.firstUpdated(changedProps);
import("../second-load");
import("./hc-lovelace");
import("../../../../src/resources/ha-style");
window.addEventListener("location-changed", () => {
const panelPath = `/${this._urlPath || "lovelace"}/`;
if (location.pathname.startsWith(panelPath)) {
@@ -260,7 +270,6 @@ export class HcMain extends HassElement {
{
strategy: {
type: "energy",
show_date_selection: true,
},
},
],
@@ -283,9 +292,20 @@ export class HcMain extends HassElement {
// configuration.
try {
await llColl.refresh();
this._unsubLovelace = llColl.subscribe((lovelaceConfig) =>
this._handleNewLovelaceConfig(lovelaceConfig)
);
this._unsubLovelace = llColl.subscribe(async (rawConfig) => {
if (isStrategyDashboard(rawConfig)) {
const { generateLovelaceDashboardStrategy } = await import(
"../../../../src/panels/lovelace/strategies/get-strategy"
);
const config = await generateLovelaceDashboardStrategy(
rawConfig.strategy,
this.hass!
);
this._handleNewLovelaceConfig(config);
} else {
this._handleNewLovelaceConfig(rawConfig);
}
});
} catch (err: any) {
if (
atLeastVersion(this.hass.connection.haVersion, 0, 107) &&
@@ -299,7 +319,7 @@ export class HcMain extends HassElement {
}
// Generate a Lovelace config.
this._unsubLovelace = () => undefined;
await this._generateLovelaceConfig();
await this._generateDefaultLovelaceConfig();
}
}
if (!resourcesLoaded) {
@@ -308,24 +328,21 @@ export class HcMain extends HassElement {
? await fetchResources(this.hass!.connection)
: (this._lovelaceConfig as LegacyLovelaceConfig).resources;
if (resources) {
loadLovelaceResources(resources, this.hass!.auth.data.hassUrl);
loadLovelaceResources(resources, this.hass!);
}
}
this._sendStatus();
}
private async _generateLovelaceConfig() {
private async _generateDefaultLovelaceConfig() {
const { generateLovelaceDashboardStrategy } = await import(
"../../../../src/panels/lovelace/strategies/get-strategy"
);
this._handleNewLovelaceConfig(
await generateLovelaceDashboardStrategy(
{
type: DEFAULT_STRATEGY,
},
this.hass!,
{ narrow: false }
DEFAULT_CONFIG.strategy,
this.hass!
)
);
}

View File

@@ -1,3 +0,0 @@
import "../../../src/resources/ha-style";
import "../../../src/resources/roboto";
import "./layout/hc-lovelace";

View File

@@ -3,6 +3,15 @@ import { DemoConfig } from "../types";
export const demoEntitiesArsaboo: DemoConfig["entities"] = (localize) =>
convertEntities({
"todo.shopping_list": {
entity_id: "todo.shopping_list",
state: "2",
attributes: {
supported_features: 15,
friendly_name: "Shopping List",
icon: "mdi:cart",
},
},
"zone.home": {
entity_id: "zone.home",
state: "zoning",

View File

@@ -3,6 +3,15 @@ import { DemoConfig } from "../types";
export const demoEntitiesJimpower: DemoConfig["entities"] = () =>
convertEntities({
"todo.shopping_list": {
entity_id: "todo.shopping_list",
state: "2",
attributes: {
supported_features: 15,
friendly_name: "Shopping List",
icon: "mdi:cart",
},
},
"zone.powertec": {
entity_id: "zone.powertec",
state: "zoning",

View File

@@ -4,16 +4,11 @@ export const demoThemeJimpower = () => ({
"primary-color": "#5294E2",
"label-badge-red": "var(--accent-color)",
"paper-tabs-selection-bar-color": "green",
"paper-slider-knob-color": "var(--accent-color)",
"light-primary-color": "var(--accent-color)",
"primary-background-color": "#383C45",
"primary-text-color": "#FFFFFF",
"paper-item-selected_-_background-color": "#434954",
"paper-slider-active-color": "var(--accent-color)",
"secondary-background-color": "#383C45",
"paper-slider-container-color":
"linear-gradient(var(--primary-background-color), var(--secondary-background-color)) no-repeat",
"paper-slider-disabled-active-color": "var(--disabled-text-color)",
"disabled-text-color": "#7F848E",
"paper-item-icon_-_color": "green",
"paper-grey-200": "#414A59",
@@ -32,14 +27,10 @@ export const demoThemeJimpower = () => ({
"switch-unchecked-button-color": "var(--disabled-text-color)",
"label-badge-border-color": "green",
"paper-listbox-color": "var(--primary-color)",
"paper-slider-disabled-secondary-color": "var(--disabled-text-color)",
"card-background-color": "#434954",
"label-badge-text-color": "var(--primary-text-color)",
"paper-slider-knob-start-color": "var(--accent-color)",
"switch-unchecked-track-color": "var(--disabled-text-color)",
"dark-primary-color": "var(--accent-color)",
"paper-slider-secondary-color": "var(--secondary-background-color)",
"paper-slider-pin-color": "var(--accent-color)",
"paper-item-icon-active-color": "#F9C536",
"accent-color": "#E45E65",
"table-row-alternative-background-color": "#3E424B",

View File

@@ -3,6 +3,15 @@ import { DemoConfig } from "../types";
export const demoEntitiesKernehed: DemoConfig["entities"] = () =>
convertEntities({
"todo.shopping_list": {
entity_id: "todo.shopping_list",
state: "2",
attributes: {
supported_features: 15,
friendly_name: "Shopping List",
icon: "mdi:cart",
},
},
"zone.anna": {
entity_id: "zone.anna",
state: "zoning",

View File

@@ -5,17 +5,12 @@ export const demoThemeKernehed = () => ({
"primary-color": "#2980b9",
"label-badge-red": "var(--accent-color)",
"paper-tabs-selection-bar-color": "green",
"paper-slider-knob-color": "var(--accent-color)",
"primary-text-color": "#FFFFFF",
"light-primary-color": "var(--accent-color)",
"primary-background-color": "#222222",
"sidebar-icon-color": "#777777",
"paper-item-selected_-_background-color": "#292929",
"paper-slider-active-color": "var(--accent-color)",
"secondary-background-color": "#222222",
"paper-slider-container-color":
"linear-gradient(var(--primary-background-color), var(--secondary-background-color)) no-repeat",
"paper-slider-disabled-active-color": "var(--disabled-text-color)",
"disabled-text-color": "#777777",
"paper-item-icon_-_color": "green",
"paper-grey-200": "#222222",
@@ -33,14 +28,10 @@ export const demoThemeKernehed = () => ({
"switch-unchecked-button-color": "var(--disabled-text-color)",
"label-badge-border-color": "green",
"paper-listbox-color": "#777777",
"paper-slider-disabled-secondary-color": "var(--disabled-text-color)",
"card-background-color": "#292929",
"label-badge-text-color": "var(--primary-text-color)",
"paper-slider-knob-start-color": "var(--accent-color)",
"switch-unchecked-track-color": "var(--disabled-text-color)",
"dark-primary-color": "var(--accent-color)",
"paper-slider-secondary-color": "var(--secondary-background-color)",
"paper-slider-pin-color": "var(--accent-color)",
"paper-item-icon-active-color": "#b58e31",
"accent-color": "#2980b9",
"table-row-alternative-background-color": "#292929",

View File

@@ -3,6 +3,15 @@ import { DemoConfig } from "../types";
export const demoEntitiesTeachingbirds: DemoConfig["entities"] = () =>
convertEntities({
"todo.shopping_list": {
entity_id: "todo.shopping_list",
state: "2",
attributes: {
supported_features: 15,
friendly_name: "Shopping List",
icon: "mdi:cart",
},
},
"sensor.pollen_grabo": {
entity_id: "sensor.pollen_grabo",
state: "",

View File

@@ -220,7 +220,8 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
state_filter: ["on"],
},
{
type: "shopping-list",
type: "todo-list",
entity: "todo.shopping_list",
},
{
entities: [

View File

@@ -1,6 +1,5 @@
export const demoThemeTeachingbirds = () => ({
"paper-card-header-color": "var(--paper-item-icon-color)",
"paper-slider-pin-color": "var(--primary-color)",
"paper-listbox-background-color": "#202020",
"paper-grey-50": "var(--primary-text-color)",
"paper-item-icon-color": "#d3d3d3",
@@ -8,8 +7,6 @@ export const demoThemeTeachingbirds = () => ({
"primary-color": "#389638",
"light-primary-color": "#6f956f",
"label-badge-red": "var(--primary-color)",
"paper-slider-secondary-color": "var(--light-primary-color)",
"paper-slider-knob-color": "var(--primary-color)",
"paper-listbox-color": "#FFFFFF",
"paper-toggle-button-checked-bar-color": "var(--light-primary-color)",
"switch-unchecked-track-color": "var(--primary-text-color)",
@@ -17,9 +14,7 @@ export const demoThemeTeachingbirds = () => ({
"label-badge-text-color": "var(--text-primary-color)",
"primary-background-color": "#303030",
"sidebar-icon-color": "var(--paper-item-icon-color)",
"paper-slider-active-color": "#d8bf50",
"secondary-background-color": "#2b2b2b",
"paper-slider-knob-start-color": "var(--primary-color)",
"paper-item-icon-active-color": "#d8bf50",
"switch-checked-color": "var(--primary-color)",
"secondary-text-color": "#389638",

View File

@@ -1,5 +1,5 @@
import { LocalizeFunc } from "../../../src/common/translations/localize";
import { LovelaceConfig } from "../../../src/data/lovelace";
import { LovelaceConfig } from "../../../src/data/lovelace/config/types";
import { Entity } from "../../../src/fake_data/entity";
export interface DemoConfig {

View File

@@ -4,7 +4,7 @@ import { customElement, property, state } from "lit/decorators";
import { until } from "lit/directives/until";
import "../../../src/components/ha-card";
import "../../../src/components/ha-circular-progress";
import { LovelaceCardConfig } from "../../../src/data/lovelace";
import { LovelaceCardConfig } from "../../../src/data/lovelace/config/card";
import { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
import { Lovelace, LovelaceCard } from "../../../src/panels/lovelace/types";
import {

View File

@@ -1,4 +1,4 @@
import "../../src/resources/ha-style";
import "../../src/resources/roboto";
import "../../src/resources/safari-14-attachshadow-patch";
import "./ha-demo";
import("../../src/resources/ha-style");

View File

@@ -22,7 +22,7 @@ import { mockLovelace } from "./stubs/lovelace";
import { mockMediaPlayer } from "./stubs/media_player";
import { mockPersistentNotification } from "./stubs/persistent_notification";
import { mockRecorder } from "./stubs/recorder";
import { mockShoppingList } from "./stubs/shopping_list";
import { mockTodo } from "./stubs/todo";
import { mockSystemLog } from "./stubs/system_log";
import { mockTemplate } from "./stubs/template";
import { mockTranslations } from "./stubs/translations";
@@ -49,7 +49,7 @@ export class HaDemo extends HomeAssistantAppEl {
mockTranslations(hass);
mockHistory(hass);
mockRecorder(hass);
mockShoppingList(hass);
mockTodo(hass);
mockSystemLog(hass);
mockTemplate(hass);
mockEvents(hass);

View File

@@ -74,19 +74,9 @@
<body>
<div id="ha-launch-screen">
<div class="ha-launch-screen-spacer"></div>
<svg
viewBox="0 0 240 240"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M240 224.762C240 233.012 233.25 239.762 225 239.762H15C6.75 239.762 0 233.012 0 224.762V134.762C0 126.512 4.77 114.993 10.61 109.153L109.39 10.3725C115.22 4.5425 124.77 4.5425 130.6 10.3725L229.39 109.162C235.22 114.992 240 126.522 240 134.772V224.772V224.762Z"
fill="#F2F4F9"
/>
<path
d="M229.39 109.153L130.61 10.3725C124.78 4.5425 115.23 4.5425 109.4 10.3725L10.61 109.153C4.78 114.983 0 126.512 0 134.762V224.762C0 233.012 6.75 239.762 15 239.762H107.27L66.64 199.132C64.55 199.852 62.32 200.262 60 200.262C48.7 200.262 39.5 191.062 39.5 179.762C39.5 168.462 48.7 159.262 60 159.262C71.3 159.262 80.5 168.462 80.5 179.762C80.5 182.092 80.09 184.322 79.37 186.412L111 218.042V102.162C104.2 98.8225 99.5 91.8425 99.5 83.7725C99.5 72.4725 108.7 63.2725 120 63.2725C131.3 63.2725 140.5 72.4725 140.5 83.7725C140.5 91.8425 135.8 98.8225 129 102.162V183.432L160.46 151.972C159.84 150.012 159.5 147.932 159.5 145.772C159.5 134.472 168.7 125.272 180 125.272C191.3 125.272 200.5 134.472 200.5 145.772C200.5 157.072 191.3 166.272 180 166.272C177.5 166.272 175.12 165.802 172.91 164.982L129 208.892V239.772H225C233.25 239.772 240 233.022 240 224.772V134.772C240 126.522 235.23 115.002 229.39 109.162V109.153Z"
fill="#18BCF2"
/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240">
<path fill="#18BCF2" d="M240 224.762a15 15 0 0 1-15 15H15a15 15 0 0 1-15-15v-90c0-8.25 4.77-19.769 10.61-25.609l98.78-98.7805c5.83-5.83 15.38-5.83 21.21 0l98.79 98.7895c5.83 5.83 10.61 17.36 10.61 25.61v90-.01Z"/>
<path fill="#F2F4F9" d="m107.27 239.762-40.63-40.63c-2.09.72-4.32 1.13-6.64 1.13-11.3 0-20.5-9.2-20.5-20.5s9.2-20.5 20.5-20.5 20.5 9.2 20.5 20.5c0 2.33-.41 4.56-1.13 6.65l31.63 31.63v-115.88c-6.8-3.3395-11.5-10.3195-11.5-18.3895 0-11.3 9.2-20.5 20.5-20.5s20.5 9.2 20.5 20.5c0 8.07-4.7 15.05-11.5 18.3895v81.27l31.46-31.46c-.62-1.96-.96-4.04-.96-6.2 0-11.3 9.2-20.5 20.5-20.5s20.5 9.2 20.5 20.5-9.2 20.5-20.5 20.5c-2.5 0-4.88-.47-7.09-1.29L129 208.892v30.88z"/>
</svg>
<div id="ha-launch-screen-info-box" class="ha-launch-screen-spacer"></div>
</div>

View File

@@ -1,44 +0,0 @@
import { ShoppingListItem } from "../../../src/data/shopping-list";
import { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
let items: ShoppingListItem[] = [
{
id: 12,
name: "Milk",
complete: false,
},
{
id: 13,
name: "Eggs",
complete: false,
},
{
id: 14,
name: "Oranges",
complete: true,
},
];
export const mockShoppingList = (hass: MockHomeAssistant) => {
hass.mockWS("shopping_list/items", () => items);
hass.mockWS("shopping_list/items/add", (msg) => {
const item: ShoppingListItem = {
id: new Date().getTime(),
complete: false,
name: msg.name,
};
items.push(item);
hass.mockEvent("shopping_list_updated");
return item;
});
hass.mockWS("shopping_list/items/update", ({ type, item_id, ...updates }) => {
items = items.map((item) =>
item.id === item_id ? { ...item, ...updates } : item
);
hass.mockEvent("shopping_list_updated");
});
hass.mockWS("shopping_list/items/clear", () => {
items = items.filter((item) => !item.complete);
hass.mockEvent("shopping_list_updated");
});
};

24
demo/src/stubs/todo.ts Normal file
View File

@@ -0,0 +1,24 @@
import { TodoItem, TodoItemStatus } from "../../../src/data/todo";
import { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
export const mockTodo = (hass: MockHomeAssistant) => {
hass.mockWS("todo/item/list", () => ({
items: [
{
uid: "12",
summary: "Milk",
status: TodoItemStatus.NeedsAction,
},
{
uid: "13",
summary: "Eggs",
status: TodoItemStatus.NeedsAction,
},
{
uid: "14",
summary: "Oranges",
status: TodoItemStatus.Completed,
},
] as TodoItem[],
}));
};

View File

@@ -1,5 +1,5 @@
import "../../src/resources/ha-style";
import "../../src/resources/roboto";
import "./ha-gallery";
import("../../src/resources/ha-style");
document.body.appendChild(document.createElement("ha-gallery"));

View File

@@ -1,8 +1,10 @@
import { css, html, LitElement, TemplateResult } from "lit";
import { css, html, LitElement, TemplateResult, nothing } from "lit";
import { customElement } from "lit/decorators";
import "../../../../src/components/ha-card";
import "../../../../src/components/ha-chip";
import "../../../../src/components/ha-chip-set";
import "../../../../src/components/chips/ha-chip-set";
import "../../../../src/components/chips/ha-assist-chip";
import "../../../../src/components/chips/ha-input-chip";
import "../../../../src/components/chips/ha-filter-chip";
import "../../../../src/components/ha-svg-icon";
import { mdiHomeAssistant } from "../../../../src/resources/home-assistant-logo-svg";
@@ -10,10 +12,6 @@ const chips: {
icon?: string;
content?: string;
}[] = [
{},
{
icon: mdiHomeAssistant,
},
{
content: "Content",
},
@@ -29,31 +27,73 @@ export class DemoHaChips extends LitElement {
return html`
<ha-card header="ha-chip demo">
<div class="card-content">
${chips.map(
(chip) => html`
<ha-chip .hasIcon=${chip.icon !== undefined}>
${chip.icon
? html`<ha-svg-icon slot="icon" .path=${chip.icon}>
</ha-svg-icon>`
: ""}
${chip.content}
</ha-chip>
`
)}
</div>
</ha-card>
<ha-card header="ha-chip-set demo">
<div class="card-content">
<p>Action chip</p>
<ha-chip-set>
${chips.map(
(chip) => html`
<ha-chip .hasIcon=${chip.icon !== undefined}>
<ha-assist-chip .label=${chip.content}>
${chip.icon
? html`<ha-svg-icon slot="icon" .path=${chip.icon}>
</ha-svg-icon>`
: nothing}
</ha-assist-chip>
`
)}
${chips.map(
(chip) => html`
<ha-assist-chip .label=${chip.content} selected>
${chip.icon
? html`<ha-svg-icon slot="icon" .path=${chip.icon}>
</ha-svg-icon>`
: nothing}
</ha-assist-chip>
`
)}
</ha-chip-set>
<p>Filter chip</p>
<ha-chip-set>
${chips.map(
(chip) => html`
<ha-filter-chip .label=${chip.content}>
${chip.icon
? html`<ha-svg-icon slot="icon" .path=${chip.icon}>
</ha-svg-icon>`
: nothing}
</ha-filter-chip>
`
)}
${chips.map(
(chip) => html`
<ha-filter-chip .label=${chip.content} selected>
${chip.icon
? html`<ha-svg-icon slot="icon" .path=${chip.icon}>
</ha-svg-icon>`
: nothing}
</ha-filter-chip>
`
)}
</ha-chip-set>
<p>Input chip</p>
<ha-chip-set>
${chips.map(
(chip) => html`
<ha-input-chip .label=${chip.content}>
${chip.icon
? html`<ha-svg-icon slot="icon" .path=${chip.icon}>
</ha-svg-icon>`
: ""}
${chip.content}
</ha-chip>
</ha-input-chip>
`
)}
${chips.map(
(chip) => html`
<ha-input-chip .label=${chip.content} selected>
${chip.icon
? html`<ha-svg-icon slot="icon" .path=${chip.icon}>
</ha-svg-icon>`
: nothing}
</ha-input-chip>
`
)}
</ha-chip-set>
@@ -68,12 +108,10 @@ export class DemoHaChips extends LitElement {
max-width: 600px;
margin: 24px auto;
}
ha-chip {
margin-bottom: 4px;
}
.card-content {
display: flex;
flex-direction: column;
align-items: flex-start;
}
`;
}

View File

@@ -49,11 +49,11 @@ export class DemoHaCircularSlider extends LitElement {
<div class="field">
<p>Current</p>
<ha-slider
labeled
min="10"
max="30"
.value=${this.current}
@change=${this._currentChanged}
pin
></ha-slider>
<p>${this.current} °C</p>
</div>

View File

@@ -11,6 +11,7 @@ const buttons: {
min?: number;
max?: number;
step?: number;
unit?: string;
class?: string;
}[] = [
{
@@ -29,6 +30,11 @@ const buttons: {
label: "Custom",
class: "custom",
},
{
id: "unit",
label: "With unit",
unit: "m",
},
];
@customElement("demo-components-ha-control-number-buttons")
@@ -50,6 +56,7 @@ export class DemoHarControlNumberButtons extends LitElement {
<pre>Config: ${JSON.stringify(config)}</pre>
<ha-control-number-buttons
.value=${this.value}
.unit=${config.unit}
.min=${config.min}
.max=${config.max}
.step=${config.step}

View File

@@ -9,6 +9,7 @@ const sliders: {
id: string;
label: string;
mode?: "start" | "end" | "cursor";
unit?: string;
class?: string;
}[] = [
{
@@ -31,18 +32,21 @@ const sliders: {
label: "Slider (start mode) and custom style",
mode: "start",
class: "custom",
unit: "mm",
},
{
id: "slider-end-custom",
label: "Slider (end mode) and custom style",
mode: "end",
class: "custom",
unit: "mm",
},
{
id: "slider-cursor-custom",
label: "Slider (cursor mode) and custom style",
mode: "cursor",
class: "custom",
unit: "mm",
},
];
@@ -93,6 +97,7 @@ export class DemoHaBarSlider extends LitElement {
@value-changed=${this.handleValueChanged}
@slider-moved=${this.handleSliderMoved}
aria-labelledby=${id}
.unit=${config.unit}
>
</ha-control-slider>
</div>
@@ -114,6 +119,7 @@ export class DemoHaBarSlider extends LitElement {
@value-changed=${this.handleValueChanged}
@slider-moved=${this.handleSliderMoved}
aria-label=${label}
.unit=${config.unit}
>
</ha-control-slider>
`;

View File

@@ -5,9 +5,22 @@ subtitle: Dialogs provide important prompts in a user flow.
# Material Design 3
Our dialogs are based on the latest version of Material Design. Specs and guidelines can be found on its [website](https://m3.material.io/components/dialogs/overview).
Our dialogs are based on the latest version of Material Design. Please note that we have made some well-considered adjustments to these guideliness. Specs and guidelines can be found on its [website](https://m3.material.io/components/dialogs/overview).
# Highlighted guidelines
# Guidelines
## Design
- Dialogs have a max width of 560px. Alert and confirmation dialogs got a fixed width of 320px. If you need more width, consider a dedicated page instead.
- The close X-icon is on the top left, on all screen sizes. Except for alert and confirmation dialogs, they only have buttons and no X-icon. This is different compared to the Material guideliness.
- Dialogs can't be closed with ESC or clicked outside of the dialog when there is a form that the user needs to fill out. Instead it will animate "no" by a little shake.
- Extra icon buttons are on the top right, for example help, settings and expand dialog. More than 2 icon buttons, they will be in an overflow menu.
- The submit button is grouped with a cancel button at the bottom right, on all screen sizes. Fullscreen mobile dialogs have them sticky at the bottom.
- Keep the labels short, for example `Save`, `Delete`, `Enable`.
- Dialog with actions must always have a discard button. On desktop a `Cancel` button and X-icon, on mobile only the X-icon.
- Destructive actions should be a red warning button.
- Alert or confirmation dialogs only have buttons and no X-icon.
- Try to avoid three buttons in one dialog. Especially when you leave the dialog task unfinished.
## Content
@@ -17,14 +30,6 @@ Our dialogs are based on the latest version of Material Design. Specs and guidel
- If users become unsure, they read the description. Make sure this explains what will happen.
- Strive for minimalism.
## Buttons and X-icon
- Keep the labels short, for example `Save`, `Delete`, `Enable`.
- Dialog with actions must always have a discard button. On desktop a `Cancel` button and X-icon, on mobile only the X-icon.
- Destructive actions should be a red warning button.
- Alert or confirmation dialogs only have buttons and no X-icon.
- Try to avoid three buttons in one dialog. Especially when you leave the dialog task unfinished.
## Example
### Confirmation dialog

View File

@@ -57,6 +57,7 @@ const DEVICES = [
sw_version: null,
hw_version: null,
via_device_id: null,
serial_number: null,
},
{
area_id: "backyard",
@@ -74,6 +75,7 @@ const DEVICES = [
sw_version: null,
hw_version: null,
via_device_id: null,
serial_number: null,
},
{
area_id: null,
@@ -91,6 +93,7 @@ const DEVICES = [
sw_version: null,
hw_version: null,
via_device_id: null,
serial_number: null,
},
];

View File

@@ -57,8 +57,8 @@ export class DemoHaHsColorPicker extends LitElement {
></ha-hs-color-picker>
<p>Hue : ${this.value[0]}</p>
<ha-slider
labeled
step="1"
pin
min="0"
max="360"
.value=${this.value[0]}
@@ -67,8 +67,8 @@ export class DemoHaHsColorPicker extends LitElement {
</ha-slider>
<p>Saturation : ${this.value[1]}</p>
<ha-slider
labeled
step="0.01"
pin
min="0"
max="1"
.value=${this.value[1]}
@@ -77,8 +77,8 @@ export class DemoHaHsColorPicker extends LitElement {
</ha-slider>
<p>Color Brighness : ${this.brightness}</p>
<ha-slider
labeled
step="1"
pin
min="0"
max="255"
.value=${this.brightness}

View File

@@ -53,6 +53,7 @@ const DEVICES = [
sw_version: null,
hw_version: null,
via_device_id: null,
serial_number: null,
},
{
area_id: "backyard",
@@ -70,6 +71,7 @@ const DEVICES = [
sw_version: null,
hw_version: null,
via_device_id: null,
serial_number: null,
},
{
area_id: null,
@@ -87,6 +89,7 @@ const DEVICES = [
sw_version: null,
hw_version: null,
via_device_id: null,
serial_number: null,
},
];

View File

@@ -1,3 +0,0 @@
---
title: Shopping List Card
---

View File

@@ -0,0 +1,3 @@
---
title: Todo List Card
---

View File

@@ -2,25 +2,39 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit";
import { customElement, query } from "lit/decorators";
import { provideHass } from "../../../../src/fake_data/provide_hass";
import "../../components/demo-cards";
import { getEntity } from "../../../../src/fake_data/entity";
import { mockTodo } from "../../../../demo/src/stubs/todo";
const ENTITIES = [
getEntity("todo", "shopping_list", "2", {
friendly_name: "Shopping List",
supported_features: 15,
}),
getEntity("todo", "read_only", "2", {
friendly_name: "Read only",
}),
];
const CONFIGS = [
{
heading: "List example",
config: `
- type: shopping-list
- type: todo-list
entity: todo.shopping_list
`,
},
{
heading: "List with title example",
config: `
- type: shopping-list
- type: todo-list
title: Shopping List
entity: todo.read_only
`,
},
];
@customElement("demo-lovelace-shopping-list-card")
class DemoShoppingListEntity extends LitElement {
@customElement("demo-lovelace-todo-list-card")
class DemoTodoListEntity extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
@@ -32,18 +46,14 @@ class DemoShoppingListEntity extends LitElement {
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
hass.mockAPI("shopping_list", () => [
{ name: "list", id: 1, complete: false },
{ name: "all", id: 2, complete: false },
{ name: "the", id: 3, complete: false },
{ name: "things", id: 4, complete: true },
]);
mockTodo(hass);
}
}
declare global {
interface HTMLElementTagNameMap {
"demo-lovelace-shopping-list-card": DemoShoppingListEntity;
"demo-lovelace-todo-list-card": DemoTodoListEntity;
}
}

View File

@@ -10,7 +10,6 @@ import { computeStateDisplay } from "../../../../src/common/entity/compute_state
import "../../../../src/components/data-table/ha-data-table";
import type { DataTableColumnContainer } from "../../../../src/components/data-table/ha-data-table";
import "../../../../src/components/entity/state-badge";
import "../../../../src/components/ha-chip";
import { provideHass } from "../../../../src/fake_data/provide_hass";
import { HomeAssistant } from "../../../../src/types";

View File

@@ -213,6 +213,7 @@ const createDeviceRegistryEntries = (
name: "Tag Reader",
sw_version: null,
hw_version: "1.0.0",
serial_number: "00_12_4B_00_22_98_88_7F",
id: "mock-device-id",
identifiers: [],
via_device_id: null,

View File

@@ -2,7 +2,7 @@ import "@material/mwc-button";
import { css, html, LitElement, TemplateResult } from "lit";
import { customElement } from "lit/decorators";
import "../../../../src/components/ha-card";
import { ActionHandlerEvent } from "../../../../src/data/lovelace";
import { ActionHandlerEvent } from "../../../../src/data/lovelace/action_handler";
import { actionHandler } from "../../../../src/panels/lovelace/common/directives/action-handler-directive";
@customElement("demo-misc-util-long-press")

View File

@@ -31,8 +31,8 @@ import { navigate } from "../../../../src/common/navigate";
import "../../../../src/components/buttons/ha-progress-button";
import "../../../../src/components/ha-alert";
import "../../../../src/components/ha-card";
import "../../../../src/components/ha-chip";
import "../../../../src/components/ha-chip-set";
import "../../../../src/components/chips/ha-chip-set";
import "../../../../src/components/chips/ha-assist-chip";
import "../../../../src/components/ha-markdown";
import "../../../../src/components/ha-settings-row";
import "../../../../src/components/ha-svg-icon";
@@ -78,6 +78,7 @@ import { showHassioMarkdownDialog } from "../../dialogs/markdown/show-dialog-has
import { hassioStyle } from "../../resources/hassio-style";
import "../../update-available/update-available-card";
import { addonArchIsSupported, extractChangelog } from "../../util/addon";
import { capitalizeFirstLetter } from "../../../../src/common/string/capitalize-first-letter";
const STAGE_ICON = {
stable: mdiCheckCircle,
@@ -234,28 +235,32 @@ class HassioAddonInfo extends LitElement {
<ha-chip-set class="capabilities">
${this.addon.stage !== "stable"
? html` <ha-chip
hasIcon
class=${classMap({
yellow: this.addon.stage === "experimental",
red: this.addon.stage === "deprecated",
})}
@click=${this._showMoreInfo}
id="stage"
>
<ha-svg-icon
slot="icon"
.path=${STAGE_ICON[this.addon.stage]}
? html`
<ha-assist-chip
filled
class=${classMap({
yellow: this.addon.stage === "experimental",
red: this.addon.stage === "deprecated",
})}
@click=${this._showMoreInfo}
id="stage"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
`addon.dashboard.capability.stages.${this.addon.stage}`
)
)}
>
</ha-svg-icon>
${this.supervisor.localize(
`addon.dashboard.capability.stages.${this.addon.stage}`
)}
</ha-chip>`
<ha-svg-icon
slot="icon"
.path=${STAGE_ICON[this.addon.stage]}
>
</ha-svg-icon>
</ha-assist-chip>
`
: ""}
<ha-chip
hasIcon
<ha-assist-chip
filled
class=${classMap({
green: Number(this.addon.rating) >= 6,
yellow: [3, 4, 5].includes(Number(this.addon.rating)),
@@ -263,138 +268,183 @@ class HassioAddonInfo extends LitElement {
})}
@click=${this._showMoreInfo}
id="rating"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.rating"
)
)}
>
<ha-svg-icon slot="icon" .path=${RATING_ICON[this.addon.rating]}>
</ha-svg-icon>
${this.supervisor.localize(
"addon.dashboard.capability.label.rating"
)}
</ha-chip>
</ha-assist-chip>
${this.addon.host_network
? html`
<ha-chip
hasIcon
<ha-assist-chip
filled
@click=${this._showMoreInfo}
id="host_network"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.host"
)
)}
>
<ha-svg-icon slot="icon" .path=${mdiNetwork}> </ha-svg-icon>
${this.supervisor.localize(
"addon.dashboard.capability.label.host"
)}
</ha-chip>
</ha-assist-chip>
`
: ""}
${this.addon.full_access
? html`
<ha-chip
hasIcon
<ha-assist-chip
filled
@click=${this._showMoreInfo}
id="full_access"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.hardware"
)
)}
>
<ha-svg-icon slot="icon" .path=${mdiChip}></ha-svg-icon>
${this.supervisor.localize(
"addon.dashboard.capability.label.hardware"
)}
</ha-chip>
</ha-assist-chip>
`
: ""}
${this.addon.homeassistant_api
? html`
<ha-chip
hasIcon
<ha-assist-chip
filled
@click=${this._showMoreInfo}
id="homeassistant_api"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.core"
)
)}
>
<ha-svg-icon
slot="icon"
.path=${mdiHomeAssistant}
></ha-svg-icon>
${this.supervisor.localize(
"addon.dashboard.capability.label.core"
)}
</ha-chip>
</ha-assist-chip>
`
: ""}
${this._computeHassioApi
? html`
<ha-chip hasIcon @click=${this._showMoreInfo} id="hassio_api">
<ha-assist-chip
filled
@click=${this._showMoreInfo}
id="hassio_api"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
`addon.dashboard.capability.role.${this.addon.hassio_role}`
) || this.addon.hassio_role
)}
>
<ha-svg-icon
slot="icon"
.path=${mdiHomeAssistant}
></ha-svg-icon>
${this.supervisor.localize(
`addon.dashboard.capability.role.${this.addon.hassio_role}`
) || this.addon.hassio_role}
</ha-chip>
</ha-assist-chip>
`
: ""}
${this.addon.docker_api
? html`
<ha-chip hasIcon @click=${this._showMoreInfo} id="docker_api">
<ha-svg-icon slot="icon" .path=${mdiDocker}></ha-svg-icon>
${this.supervisor.localize(
"addon.dashboard.capability.label.docker"
<ha-assist-chip
filled
@click=${this._showMoreInfo}
id="docker_api"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.docker"
)
)}
</ha-chip>
>
<ha-svg-icon slot="icon" .path=${mdiDocker}></ha-svg-icon>
</ha-assist-chip>
`
: ""}
${this.addon.host_pid
? html`
<ha-chip hasIcon @click=${this._showMoreInfo} id="host_pid">
<ha-svg-icon slot="icon" .path=${mdiPound}></ha-svg-icon>
${this.supervisor.localize(
"addon.dashboard.capability.label.host_pid"
<ha-assist-chip
filled
@click=${this._showMoreInfo}
id="host_pid"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.host_pid"
)
)}
</ha-chip>
>
<ha-svg-icon slot="icon" .path=${mdiPound}></ha-svg-icon>
</ha-assist-chip>
`
: ""}
${this.addon.apparmor !== "default"
? html`
<ha-chip
hasIcon
<ha-assist-chip
filled
@click=${this._showMoreInfo}
class=${this._computeApparmorClassName}
id="apparmor"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.apparmor"
)
)}
>
<ha-svg-icon slot="icon" .path=${mdiShield}></ha-svg-icon>
${this.supervisor.localize(
"addon.dashboard.capability.label.apparmor"
)}
</ha-chip>
</ha-assist-chip>
`
: ""}
${this.addon.auth_api
? html`
<ha-chip hasIcon @click=${this._showMoreInfo} id="auth_api">
<ha-svg-icon slot="icon" .path=${mdiKey}></ha-svg-icon>
${this.supervisor.localize(
"addon.dashboard.capability.label.auth"
<ha-assist-chip
filled
@click=${this._showMoreInfo}
id="auth_api"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.auth"
)
)}
</ha-chip>
>
<ha-svg-icon slot="icon" .path=${mdiKey}></ha-svg-icon>
</ha-assist-chip>
`
: ""}
${this.addon.ingress
? html`
<ha-chip hasIcon @click=${this._showMoreInfo} id="ingress">
<ha-assist-chip
filled
@click=${this._showMoreInfo}
id="ingress"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.ingress"
)
)}
>
<ha-svg-icon
slot="icon"
.path=${mdiCursorDefaultClickOutline}
></ha-svg-icon>
${this.supervisor.localize(
"addon.dashboard.capability.label.ingress"
)}
</ha-chip>
</ha-assist-chip>
`
: ""}
${this.addon.signed
? html`
<ha-chip hasIcon @click=${this._showMoreInfo} id="signed">
<ha-svg-icon slot="icon" .path=${mdiLinkLock}></ha-svg-icon>
${this.supervisor.localize(
"addon.dashboard.capability.label.signed"
<ha-assist-chip
filled
@click=${this._showMoreInfo}
id="signed"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.signed"
)
)}
</ha-chip>
>
<ha-svg-icon slot="icon" .path=${mdiLinkLock}></ha-svg-icon>
</ha-assist-chip>
`
: ""}
</ha-chip-set>
@@ -1185,23 +1235,35 @@ class HassioAddonInfo extends LitElement {
.description a {
color: var(--primary-color);
}
ha-chip {
text-transform: capitalize;
--ha-chip-text-color: var(--text-primary-color);
--ha-chip-background-color: var(--primary-color);
ha-assist-chip {
--md-sys-color-primary: var(--text-primary-color);
--md-sys-color-on-surface: var(--text-primary-color);
--ha-assist-chip-filled-container-color: var(--primary-color);
}
.red {
--ha-chip-background-color: var(--label-badge-red, #df4c1e);
--ha-assist-chip-filled-container-color: var(
--label-badge-red,
#df4c1e
);
}
.blue {
--ha-chip-background-color: var(--label-badge-blue, #039be5);
--ha-assist-chip-filled-container-color: var(
--label-badge-blue,
#039be5
);
}
.green {
--ha-chip-background-color: var(--label-badge-green, #0da035);
--ha-assist-chip-filled-container-color: var(
--label-badge-green,
#0da035
);
}
.yellow {
--ha-chip-background-color: var(--label-badge-yellow, #f4b400);
--ha-assist-chip-filled-container-color: var(
--label-badge-yellow,
#f4b400
);
}
.capabilities {
margin-bottom: 16px;
@@ -1260,9 +1322,6 @@ class HassioAddonInfo extends LitElement {
}
@media (max-width: 720px) {
ha-chip {
line-height: 36px;
}
.addon-options {
max-width: 100%;
}

View File

@@ -360,11 +360,9 @@ export class HassioBackups extends LitElement {
if (this.supervisor!.info.state !== "running") {
showAlertDialog(this, {
title: this.supervisor!.localize("backup.could_not_create"),
text: this.supervisor!.localize(
"backup.create_blocked_not_running",
"state",
this.supervisor!.info.state
),
text: this.supervisor!.localize("backup.create_blocked_not_running", {
state: this.supervisor!.info.state,
}),
});
return;
}

View File

@@ -1,8 +1,9 @@
import Fuse from "fuse.js";
import type { IFuseOptions } from "fuse.js";
import { StoreAddon } from "../../../src/data/supervisor/store";
export function filterAndSort(addons: StoreAddon[], filter: string) {
const options: Fuse.IFuseOptions<StoreAddon> = {
const options: IFuseOptions<StoreAddon> = {
keys: ["name", "description", "slug"],
isCaseSensitive: false,
minMatchCharLength: 2,

View File

@@ -31,6 +31,7 @@ import { fileDownload } from "../../../../src/util/file_download";
import "../../components/supervisor-backup-content";
import type { SupervisorBackupContent } from "../../components/supervisor-backup-content";
import { HassioBackupDialogParams } from "./show-dialog-hassio-backup";
import { BackupOrRestoreKey } from "../../util/translations";
@customElement("dialog-hassio-backup")
class HassioBackupDialog
@@ -64,6 +65,13 @@ class HassioBackupDialog
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
private _localize(key: BackupOrRestoreKey) {
return (
this._dialogParams!.supervisor?.localize(`backup.${key}`) ||
this._dialogParams!.localize!(`ui.panel.page-onboarding.restore.${key}`)
);
}
protected render() {
if (!this._dialogParams || !this._backup) {
return nothing;
@@ -79,7 +87,7 @@ class HassioBackupDialog
<ha-header-bar>
<span slot="title">${this._backup.name}</span>
<ha-icon-button
.label=${this.hass?.localize("ui.common.close") || "Close"}
.label=${this._localize("close")}
.path=${mdiClose}
slot="actionItems"
dialogAction="cancel"
@@ -87,29 +95,31 @@ class HassioBackupDialog
</ha-header-bar>
</div>
${this._restoringBackup
? html` <ha-circular-progress active></ha-circular-progress>`
: html`<supervisor-backup-content
.hass=${this.hass}
.supervisor=${this._dialogParams.supervisor}
.backup=${this._backup}
.onboarding=${this._dialogParams.onboarding || false}
.localize=${this._dialogParams.localize}
dialogInitialFocus
>
</supervisor-backup-content>`}
? html`<ha-circular-progress active></ha-circular-progress>`
: html`
<supervisor-backup-content
.hass=${this.hass}
.supervisor=${this._dialogParams.supervisor}
.backup=${this._backup}
.onboarding=${this._dialogParams.onboarding || false}
.localize=${this._dialogParams.localize}
dialogInitialFocus
>
</supervisor-backup-content>
`}
${this._error
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
: ""}
: nothing}
<mwc-button
.disabled=${this._restoringBackup}
slot="secondaryAction"
@click=${this._restoreClicked}
>
Restore
${this._localize("restore")}
</mwc-button>
${!this._dialogParams.onboarding
${!this._dialogParams.onboarding && this._dialogParams.supervisor
? html`<ha-button-menu
fixed
slot="primaryAction"
@@ -117,22 +127,24 @@ class HassioBackupDialog
@closed=${stopPropagation}
>
<ha-icon-button
.label=${this.hass!.localize("ui.common.menu") || "Menu"}
.label=${this._dialogParams.supervisor.localize(
"backup.more_actions"
)}
.path=${mdiDotsVertical}
slot="trigger"
></ha-icon-button>
<mwc-list-item
>${this._dialogParams.supervisor?.localize(
>${this._dialogParams.supervisor.localize(
"backup.download_backup"
)}</mwc-list-item
>
<mwc-list-item class="error"
>${this._dialogParams.supervisor?.localize(
>${this._dialogParams.supervisor.localize(
"backup.delete_backup_title"
)}</mwc-list-item
>
</ha-button-menu>`
: ""}
: nothing}
</ha-dialog>
`;
}
@@ -183,21 +195,22 @@ class HassioBackupDialog
}
private async _partialRestoreClicked(backupDetails) {
if (
this._dialogParams?.supervisor !== undefined &&
this._dialogParams?.supervisor.info.state !== "running"
) {
const supervisor = this._dialogParams?.supervisor;
if (supervisor !== undefined && supervisor.info.state !== "running") {
await showAlertDialog(this, {
title: "Could not restore backup",
text: `Restoring a backup is not possible right now because the system is in ${this._dialogParams?.supervisor.info.state} state.`,
title: supervisor.localize("backup.could_not_restore"),
text: supervisor.localize("backup.restore_blocked_not_running", {
state: supervisor.info.state,
}),
});
return;
}
if (
!(await showConfirmationDialog(this, {
title: "Are you sure you want to restore this partial backup?",
confirmText: "restore",
dismissText: "cancel",
title: this._localize("confirm_restore_partial_backup_title"),
text: this._localize("confirm_restore_partial_backup_text"),
confirmText: this._localize("restore"),
dismissText: this._localize("cancel"),
}))
) {
return;
@@ -230,22 +243,22 @@ class HassioBackupDialog
}
private async _fullRestoreClicked(backupDetails) {
if (
this._dialogParams?.supervisor !== undefined &&
this._dialogParams?.supervisor.info.state !== "running"
) {
const supervisor = this._dialogParams?.supervisor;
if (supervisor !== undefined && supervisor.info.state !== "running") {
await showAlertDialog(this, {
title: "Could not restore backup",
text: `Restoring a backup is not possible right now because the system is in ${this._dialogParams?.supervisor.info.state} state.`,
title: supervisor.localize("backup.could_not_restore"),
text: supervisor.localize("backup.restore_blocked_not_running", {
state: supervisor.info.state,
}),
});
return;
}
if (
!(await showConfirmationDialog(this, {
title:
"Are you sure you want to wipe your system and restore this backup?",
confirmText: "restore",
dismissText: "cancel",
title: this._localize("confirm_restore_full_backup_title"),
text: this._localize("confirm_restore_full_backup_text"),
confirmText: this._localize("restore"),
dismissText: this._localize("cancel"),
}))
) {
return;
@@ -279,11 +292,15 @@ class HassioBackupDialog
}
private async _deleteClicked() {
const supervisor = this._dialogParams?.supervisor;
if (!supervisor) return;
if (
!(await showConfirmationDialog(this, {
title: "Are you sure you want to delete this backup?",
confirmText: "delete",
dismissText: "cancel",
title: supervisor!.localize("backup.confirm_delete_title"),
text: supervisor!.localize("backup.confirm_delete_text"),
confirmText: supervisor!.localize("backup.delete"),
dismissText: supervisor!.localize("backup.cancel"),
}))
) {
return;
@@ -301,6 +318,9 @@ class HassioBackupDialog
}
private async _downloadClicked() {
const supervisor = this._dialogParams?.supervisor;
if (!supervisor) return;
let signedPath: { path: string };
try {
signedPath = await getSignedPath(
@@ -320,10 +340,10 @@ class HassioBackupDialog
if (window.location.href.includes("ui.nabu.casa")) {
const confirm = await showConfirmationDialog(this, {
title: "Potential slow download",
text: "Downloading backups over the Nabu Casa URL will take some time, it is recomended to use your local URL instead, do you want to continue?",
confirmText: "continue",
dismissText: "cancel",
title: supervisor.localize("backup.remote_download_title"),
text: supervisor.localize("backup.remote_download_text"),
confirmText: supervisor.localize("backup.download"),
dismissText: this._localize("cancel"),
});
if (!confirm) {
return;

View File

@@ -89,8 +89,7 @@ class HassioCreateBackupDialog extends LitElement {
),
text: this._dialogParams!.supervisor.localize(
"backup.create_blocked_not_running",
"state",
this._dialogParams!.supervisor.info.state
{ state: this._dialogParams!.supervisor.info.state }
),
});
return;

View File

@@ -1,4 +1,5 @@
import { mdiClose } from "@mdi/js";
import { dump } from "js-yaml";
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
@@ -9,7 +10,6 @@ import "../../../../src/components/ha-expansion-panel";
import "../../../../src/components/ha-icon-button";
import "../../../../src/components/search-input";
import { HassioHardwareInfo } from "../../../../src/data/hassio/hardware";
import { dump } from "../../../../src/resources/js-yaml-dump";
import { haStyle, haStyleDialog } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { HassioHardwareDialogParams } from "./show-dialog-hassio-hardware";

View File

@@ -1,15 +1,15 @@
// Compat needs to be first import
import "../../src/resources/compatibility";
import { setCancelSyntheticClickEvents } from "@polymer/polymer/lib/utils/settings";
import "../../src/resources/roboto";
import "../../src/resources/ha-style";
import "../../src/resources/safari-14-attachshadow-patch";
import "./hassio-main";
setCancelSyntheticClickEvents(false);
import("../../src/resources/ha-style");
import("@polymer/polymer/lib/utils/settings").then(
({ setCancelSyntheticClickEvents }) => setCancelSyntheticClickEvents(false)
);
const styleEl = document.createElement("style");
styleEl.innerHTML = `
styleEl.textContent = `
body {
font-family: Roboto, sans-serif;
-moz-osx-font-smoothing: grayscale;

View File

@@ -0,0 +1,4 @@
import type { TranslationDict } from "../../../src/types";
export type BackupOrRestoreKey = keyof TranslationDict["supervisor"]["backup"] &
keyof TranslationDict["ui"]["panel"]["page-onboarding"]["restore"];

View File

@@ -25,24 +25,24 @@
"license": "Apache-2.0",
"type": "module",
"dependencies": {
"@babel/runtime": "7.23.1",
"@babel/runtime": "7.23.2",
"@braintree/sanitize-url": "6.0.4",
"@codemirror/autocomplete": "6.9.1",
"@codemirror/commands": "6.2.5",
"@codemirror/language": "6.9.1",
"@codemirror/autocomplete": "6.11.0",
"@codemirror/commands": "6.3.0",
"@codemirror/language": "6.9.2",
"@codemirror/legacy-modes": "6.3.3",
"@codemirror/search": "6.5.4",
"@codemirror/state": "6.2.1",
"@codemirror/view": "6.20.2",
"@codemirror/state": "6.3.1",
"@codemirror/view": "6.22.0",
"@egjs/hammerjs": "2.0.17",
"@formatjs/intl-datetimeformat": "6.10.3",
"@formatjs/intl-displaynames": "6.5.2",
"@formatjs/intl-getcanonicallocales": "2.2.1",
"@formatjs/intl-listformat": "7.4.2",
"@formatjs/intl-locale": "3.3.4",
"@formatjs/intl-numberformat": "8.7.2",
"@formatjs/intl-pluralrules": "5.2.6",
"@formatjs/intl-relativetimeformat": "11.2.6",
"@formatjs/intl-datetimeformat": "6.11.2",
"@formatjs/intl-displaynames": "6.6.2",
"@formatjs/intl-getcanonicallocales": "2.3.0",
"@formatjs/intl-listformat": "7.5.1",
"@formatjs/intl-locale": "3.4.1",
"@formatjs/intl-numberformat": "8.8.1",
"@formatjs/intl-pluralrules": "5.2.8",
"@formatjs/intl-relativetimeformat": "11.2.8",
"@fullcalendar/core": "6.1.9",
"@fullcalendar/daygrid": "6.1.9",
"@fullcalendar/interaction": "6.1.9",
@@ -51,11 +51,13 @@
"@fullcalendar/timegrid": "6.1.9",
"@lezer/highlight": "1.1.6",
"@lit-labs/context": "0.4.1",
"@lit-labs/motion": "1.0.4",
"@lit-labs/virtualizer": "2.0.7",
"@lit-labs/motion": "1.0.6",
"@lit-labs/observers": "2.0.2",
"@lit-labs/virtualizer": "2.0.10",
"@lrnwebcomponents/simple-tooltip": "7.0.18",
"@material/chips": "=14.0.0-canary.53b3cad2f.0",
"@material/data-table": "=14.0.0-canary.53b3cad2f.0",
"@material/mwc-base": "0.27.0",
"@material/mwc-button": "0.27.0",
"@material/mwc-checkbox": "0.27.0",
"@material/mwc-circular-progress": "0.27.0",
@@ -71,7 +73,6 @@
"@material/mwc-radio": "0.27.0",
"@material/mwc-ripple": "0.27.0",
"@material/mwc-select": "0.27.0",
"@material/mwc-slider": "0.27.0",
"@material/mwc-switch": "0.27.0",
"@material/mwc-tab": "0.27.0",
"@material/mwc-tab-bar": "0.27.0",
@@ -80,22 +81,21 @@
"@material/mwc-top-app-bar": "0.27.0",
"@material/mwc-top-app-bar-fixed": "0.27.0",
"@material/top-app-bar": "=14.0.0-canary.53b3cad2f.0",
"@material/web": "=1.0.0-pre.17",
"@mdi/js": "7.2.96",
"@mdi/svg": "7.2.96",
"@material/web": "=1.0.1",
"@mdi/js": "7.3.67",
"@mdi/svg": "7.3.67",
"@polymer/iron-flex-layout": "3.0.1",
"@polymer/iron-input": "3.0.1",
"@polymer/iron-resizable-behavior": "3.0.1",
"@polymer/paper-input": "3.2.1",
"@polymer/paper-item": "3.0.1",
"@polymer/paper-listbox": "3.0.1",
"@polymer/paper-slider": "3.0.1",
"@polymer/paper-tabs": "3.1.0",
"@polymer/paper-toast": "3.0.1",
"@polymer/polymer": "3.5.1",
"@thomasloven/round-slider": "0.6.0",
"@vaadin/combo-box": "24.1.9",
"@vaadin/vaadin-themable-mixin": "24.1.9",
"@vaadin/combo-box": "24.2.2",
"@vaadin/vaadin-themable-mixin": "24.2.2",
"@vibrant/color": "3.2.1-alpha.1",
"@vibrant/core": "3.2.1-alpha.1",
"@vibrant/quantizer-mmcq": "3.2.1-alpha.1",
@@ -105,28 +105,28 @@
"app-datepicker": "5.1.1",
"chart.js": "4.4.0",
"comlink": "4.4.1",
"core-js": "3.32.2",
"core-js": "3.33.2",
"cropperjs": "1.6.1",
"date-fns": "2.30.0",
"date-fns-tz": "2.0.0",
"deep-clone-simple": "1.1.1",
"deep-freeze": "0.0.1",
"fuse.js": "6.6.2",
"fuse.js": "7.0.0",
"google-timezones-json": "1.2.0",
"hls.js": "1.4.12",
"home-assistant-js-websocket": "8.2.0",
"home-assistant-js-websocket": "9.1.0",
"idb-keyval": "6.2.1",
"intl-messageformat": "10.5.3",
"intl-messageformat": "10.5.5",
"js-yaml": "4.1.0",
"leaflet": "1.9.4",
"leaflet-draw": "1.0.4",
"lit": "2.8.0",
"luxon": "3.4.3",
"marked": "9.0.3",
"marked": "9.1.6",
"memoize-one": "6.0.0",
"node-vibrant": "3.2.1-alpha.1",
"proxy-polyfill": "0.3.2",
"punycode": "2.3.0",
"punycode": "2.3.1",
"qr-scanner": "1.4.2",
"qrcode": "1.5.3",
"resize-observer-polyfill": "1.5.1",
@@ -138,11 +138,11 @@
"tinykeys": "2.1.0",
"tsparticles-engine": "2.12.0",
"tsparticles-preset-links": "2.12.0",
"ua-parser-js": "1.0.36",
"ua-parser-js": "1.0.37",
"unfetch": "5.0.0",
"vis-data": "7.1.7",
"vis-network": "9.1.6",
"vue": "2.7.14",
"vis-data": "7.1.8",
"vis-network": "9.1.9",
"vue": "2.7.15",
"vue2-daterange-picker": "0.6.8",
"weekstart": "2.0.0",
"workbox-cacheable-response": "7.0.0",
@@ -154,62 +154,61 @@
"xss": "1.0.14"
},
"devDependencies": {
"@babel/core": "7.23.0",
"@babel/plugin-proposal-decorators": "7.23.0",
"@babel/plugin-transform-runtime": "7.22.15",
"@babel/preset-env": "7.22.20",
"@babel/preset-typescript": "7.23.0",
"@babel/core": "7.23.3",
"@babel/plugin-proposal-decorators": "7.23.3",
"@babel/plugin-transform-runtime": "7.23.3",
"@babel/preset-env": "7.23.3",
"@babel/preset-typescript": "7.23.3",
"@bundle-stats/plugin-webpack-filter": "4.8.0",
"@koa/cors": "4.0.0",
"@lokalise/node-api": "12.0.0",
"@octokit/auth-oauth-device": "6.0.1",
"@octokit/plugin-retry": "6.0.1",
"@octokit/rest": "20.0.2",
"@open-wc/dev-server-hmr": "0.1.4",
"@rollup/plugin-babel": "6.0.3",
"@rollup/plugin-commonjs": "25.0.4",
"@rollup/plugin-json": "6.0.0",
"@rollup/plugin-node-resolve": "15.2.1",
"@rollup/plugin-replace": "5.0.2",
"@types/babel__plugin-transform-runtime": "7.9.3",
"@types/chromecast-caf-receiver": "6.0.10",
"@types/chromecast-caf-sender": "1.0.6",
"@types/esprima": "4.0.4",
"@rollup/plugin-babel": "6.0.4",
"@rollup/plugin-commonjs": "25.0.7",
"@rollup/plugin-json": "6.0.1",
"@rollup/plugin-node-resolve": "15.2.3",
"@rollup/plugin-replace": "5.0.5",
"@types/babel__plugin-transform-runtime": "7.9.5",
"@types/chromecast-caf-receiver": "6.0.12",
"@types/chromecast-caf-sender": "1.0.8",
"@types/glob": "8.1.0",
"@types/html-minifier-terser": "7.0.0",
"@types/js-yaml": "4.0.6",
"@types/leaflet": "1.9.6",
"@types/leaflet-draw": "1.0.8",
"@types/luxon": "3.3.2",
"@types/mocha": "10.0.1",
"@types/qrcode": "1.5.2",
"@types/serve-handler": "6.1.2",
"@types/sortablejs": "1.15.3",
"@types/tar": "6.1.6",
"@types/ua-parser-js": "0.7.37",
"@types/html-minifier-terser": "7.0.2",
"@types/js-yaml": "4.0.9",
"@types/leaflet": "1.9.8",
"@types/leaflet-draw": "1.0.10",
"@types/luxon": "3.3.4",
"@types/mocha": "10.0.4",
"@types/qrcode": "1.5.5",
"@types/serve-handler": "6.1.4",
"@types/sortablejs": "1.15.5",
"@types/tar": "6.1.9",
"@types/ua-parser-js": "0.7.39",
"@types/webspeechapi": "0.0.29",
"@typescript-eslint/eslint-plugin": "6.7.3",
"@typescript-eslint/parser": "6.7.3",
"@typescript-eslint/eslint-plugin": "6.10.0",
"@typescript-eslint/parser": "6.10.0",
"@web/dev-server": "0.1.38",
"@web/dev-server-rollup": "0.4.1",
"babel-loader": "9.1.3",
"babel-plugin-template-html-minifier": "4.1.0",
"chai": "4.3.8",
"chai": "4.3.10",
"del": "7.1.0",
"eslint": "8.50.0",
"eslint": "8.53.0",
"eslint-config-airbnb-base": "15.0.0",
"eslint-config-airbnb-typescript": "17.1.0",
"eslint-config-prettier": "9.0.0",
"eslint-import-resolver-webpack": "0.13.7",
"eslint-import-resolver-webpack": "0.13.8",
"eslint-plugin-disable": "2.0.3",
"eslint-plugin-import": "2.28.1",
"eslint-plugin-lit": "1.9.1",
"eslint-plugin-lit-a11y": "4.1.0",
"eslint-plugin-import": "2.29.0",
"eslint-plugin-lit": "1.10.1",
"eslint-plugin-lit-a11y": "4.1.1",
"eslint-plugin-unused-imports": "3.0.0",
"eslint-plugin-wc": "2.0.4",
"esprima": "4.0.1",
"fancy-log": "2.0.0",
"fs-extra": "11.1.1",
"glob": "10.3.7",
"glob": "10.3.10",
"gulp": "4.0.2",
"gulp-flatmap": "1.0.2",
"gulp-json-transform": "0.4.8",
@@ -220,10 +219,10 @@
"husky": "8.0.3",
"instant-mocha": "1.5.2",
"jszip": "3.10.1",
"lint-staged": "14.0.1",
"lit-analyzer": "2.0.0-pre.3",
"lint-staged": "15.1.0",
"lit-analyzer": "2.0.1",
"lodash.template": "4.5.0",
"magic-string": "0.30.3",
"magic-string": "0.30.5",
"map-stream": "0.0.7",
"mocha": "10.2.0",
"object-hash": "3.0.0",
@@ -235,19 +234,20 @@
"rollup-plugin-terser": "7.0.2",
"rollup-plugin-visualizer": "5.9.2",
"serve-handler": "6.1.5",
"sinon": "16.0.0",
"sinon": "17.0.1",
"source-map-url": "0.4.1",
"systemjs": "6.14.2",
"tar": "6.2.0",
"terser-webpack-plugin": "5.3.9",
"ts-lit-plugin": "2.0.0-pre.1",
"ts-lit-plugin": "2.0.1",
"typescript": "5.2.2",
"vinyl-buffer": "1.0.1",
"vinyl-source-stream": "2.0.0",
"webpack": "5.88.2",
"webpack": "5.89.0",
"webpack-cli": "5.1.4",
"webpack-dev-server": "4.15.1",
"webpack-manifest-plugin": "5.0.0",
"webpack-stats-plugin": "1.1.3",
"webpackbar": "5.0.2",
"workbox-build": "7.0.0"
},
@@ -255,8 +255,11 @@
"resolutions": {
"@polymer/polymer": "patch:@polymer/polymer@3.5.1#./.yarn/patches/@polymer/polymer/pr-5569.patch",
"@material/mwc-button@^0.25.3": "^0.27.0",
"lit": "2.8.0",
"clean-css": "5.3.2",
"@lit/reactive-element": "1.6.3",
"sortablejs@1.15.0": "patch:sortablejs@npm%3A1.15.0#./.yarn/patches/sortablejs-npm-1.15.0-f3a393abcc.patch",
"leaflet-draw@1.0.4": "patch:leaflet-draw@npm%3A1.0.4#./.yarn/patches/leaflet-draw-npm-1.0.4-0ca0ebcf65.patch"
},
"packageManager": "yarn@3.6.3"
"packageManager": "yarn@4.0.1"
}

View File

@@ -1,23 +1 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="480.000000pt" height="480.000000pt" viewBox="0 0 480.000000 480.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,480.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M2313 4666 c-23 -7 -56 -23 -75 -34 -47 -30 -2059 -2048 -2095 -2102
-45 -67 -77 -135 -109 -230 l-29 -85 0 -995 0 -995 27 -51 c31 -59 93 -118
152 -145 39 -18 83 -19 1001 -19 l960 0 -406 405 c-395 395 -406 406 -433 395
-15 -5 -63 -10 -107 -10 -429 0 -566 577 -181 767 67 34 86 38 164 42 105 4
165 -13 246 -67 113 -74 175 -190 176 -327 1 -44 -3 -96 -7 -115 l-8 -35 316
-315 315 -315 0 1160 -1 1160 -51 35 c-260 177 -226 567 62 704 82 39 209 48
293 21 239 -78 354 -352 242 -575 -32 -63 -89 -125 -141 -156 l-44 -26 0 -811
0 -812 315 315 c218 217 313 320 309 330 -14 35 -16 134 -4 190 26 122 111
227 230 284 82 39 209 48 293 21 115 -38 214 -130 258 -242 19 -46 23 -78 24
-153 0 -86 -3 -101 -32 -163 -40 -84 -118 -163 -198 -202 -49 -23 -77 -29
-150 -33 -50 -2 -108 1 -130 7 l-40 11 -437 -438 -438 -437 0 -307 0 -308 998
0 c981 0 998 1 1042 21 58 26 115 81 148 144 l27 50 0 995 0 995 -33 95 c-72
209 -6 135 -1147 1278 -840 843 -1040 1037 -1082 1059 -64 31 -159 39 -220 19z"/>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="640" viewBox="0 0 240 240"><path d="M120.001 0c-3.787 0-7.573 1.499-10.444 4.49L12.211 105.905a25.921 25.921 0 0 0-2.098 2.501 35.25 35.25 0 0 0-1.96 2.942c-3.01 5.021-5.285 11.318-6.074 16.898-.03.21-.088.429-.11.636a27.355 27.355 0 0 0-.213 3.317v93.023a14.78 14.78 90 0 0 14.78 14.78h90.92L67.422 198.29a20.2 20.2 90 1 1 12.542-13.06l31.17 32.474V98.726a20.2 20.2 90 1 1 17.734 0v83.44l31.001-32.299a20.2 20.2 90 1 1 12.267 13.357l-43.269 45.082V240h94.9a14.479 14.479 90 0 0 14.478-14.479v-93.314c0-1.059-.069-2.168-.214-3.314-.7-5.73-3.06-12.327-6.183-17.537a35.801 35.801 0 0 0-1.955-2.937 26.271 26.271 0 0 0-2.102-2.506L130.444 4.486C127.573 1.494 123.786-.002 120.001 0"/></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 747 B

View File

@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
version = "20230928.0"
version = "20231030.0"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"

View File

@@ -1,5 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"configMigration": true,
"extends": [
":ignoreModulesAndTests",
":label(Dependencies)",
@@ -10,7 +11,7 @@
"group:recommended",
"npm:unpublishSafe"
],
"enabledManagers": ["npm"],
"enabledManagers": ["npm", "nvm"],
"postUpdateOptions": ["yarnDedupeHighest"],
"lockFileMaintenance": {
"description": ["Run after patch releases but before next beta"],
@@ -28,11 +29,22 @@
"matchPackageNames": ["vue"],
"allowedVersions": "< 3"
},
{
"description": "Group MDI packages",
"groupName": "Material Design Icons",
"matchPackageNames": ["@mdi/js", "@mdi/svg"]
},
{
"description": "Group tsparticles engine and presets",
"groupName": "tsparticles",
"matchPackageNames": ["tsparticles-engine"],
"matchPackagePrefixes": ["tsparticles-preset-"]
},
{
"description": "Group and temporarily disable WDS packages",
"groupName": "Web Dev Server",
"matchPackagePrefixes": ["@web/dev-server"],
"enabled": false
}
]
}

View File

@@ -33,7 +33,7 @@ fi
docker run \
-v ${LOCAL_FILE}:/opt/src/${LOCAL_FILE} \
lokalise/lokalise-cli-2@sha256:f1860b26be22fa73b8c93bc5f8690f2afc867610a42de6fc27adc790e5d4425d lokalise2 \
lokalise/lokalise-cli-2:v2.6.10 lokalise2 \
--token ${LOKALISE_TOKEN} \
--project-id ${PROJECT_ID} \
file upload \

View File

@@ -8,7 +8,6 @@ import "../components/ha-alert";
import "../components/ha-checkbox";
import { computeInitialHaFormData } from "../components/ha-form/compute-initial-ha-form-data";
import "../components/ha-formfield";
import "../components/ha-markdown";
import { AuthProvider, autocompleteLoginFields } from "../data/auth";
import {
DataEntryFlowStep,
@@ -182,24 +181,13 @@ export class HaAuthFlow extends LitElement {
case "abort":
return html`
${this.localize("ui.panel.page-authorize.abort_intro")}:
<ha-markdown
allowsvg
breaks
.content=${this.localize(
`ui.panel.page-authorize.form.providers.${step.handler[0]}.abort.${step.reason}`
)}
></ha-markdown>
${this.localize(
`ui.panel.page-authorize.form.providers.${step.handler[0]}.abort.${step.reason}`
)}
`;
case "form":
return html`
${this._computeStepDescription(step)
? html`
<ha-markdown
breaks
.content=${this._computeStepDescription(step)}
></ha-markdown>
`
: nothing}
${this._computeStepDescription(step)}
<ha-auth-form
.data=${this._stepData}
.schema=${autocompleteLoginFields(step.data_schema)}
@@ -314,13 +302,7 @@ export class HaAuthFlow extends LitElement {
private _computeStepDescription(step: DataEntryFlowStepForm) {
const resourceKey =
`ui.panel.page-authorize.form.providers.${step.handler[0]}.step.${step.step_id}.description` as const;
const args: string[] = [];
const placeholders = step.description_placeholders || {};
Object.keys(placeholders).forEach((key) => {
args.push(key);
args.push(placeholders[key]);
});
return this.localize(resourceKey, ...args);
return this.localize(resourceKey, step.description_placeholders);
}
private _computeLabelCallback(step: DataEntryFlowStepForm) {

View File

@@ -26,14 +26,13 @@ export class HaAuthFormString extends HaFormString {
}
ha-auth-form-string ha-icon-button {
position: absolute;
top: 1em;
right: 12px;
--mdc-icon-button-size: 24px;
color: var(--secondary-text-color);
}
ha-auth-form-string ha-icon-button {
top: 8px;
right: 8px;
inset-inline-start: initial;
inset-inline-end: 12px;
inset-inline-end: 8px;
--mdc-icon-button-size: 40px;
--mdc-icon-size: 20px;
color: var(--secondary-text-color);
direction: var(--direction);
}
</style>
@@ -63,7 +62,7 @@ export class HaAuthFormString extends HaFormString {
.validationMessage=${this.schema.required ? "Required" : undefined}
@input=${this._valueChanged}
@change=${this._valueChanged}
></ha-auth-textfield>
></ha-auth-textfield>
${this.renderIcon()}
</ha-auth-textfield>
`;

View File

@@ -0,0 +1,9 @@
export function getAllCombinations<T>(arr: T[]) {
return arr.reduce<T[][]>(
(combinations, element) =>
combinations.concat(
combinations.map((combination) => [...combination, element])
),
[[]]
);
}

View File

@@ -58,10 +58,10 @@ const matchMaxScale = (
return outputColors.map((value) => Math.round(value * factor));
};
const mired2kelvin = (miredTemperature: number) =>
export const mired2kelvin = (miredTemperature: number) =>
Math.floor(1000000 / miredTemperature);
const kelvin2mired = (kelvintTemperature: number) =>
export const kelvin2mired = (kelvintTemperature: number) =>
Math.floor(1000000 / kelvintTemperature);
export const rgbww2rgb = (

View File

@@ -16,6 +16,7 @@ import {
mdiCarCoolantLevel,
mdiCash,
mdiChatSleep,
mdiClipboardList,
mdiClock,
mdiCloudUpload,
mdiCog,
@@ -120,6 +121,7 @@ export const FIXED_DOMAIN_ICONS = {
siren: mdiBullhorn,
stt: mdiMicrophoneMessage,
text: mdiFormTextbox,
todo: mdiClipboardList,
time: mdiClock,
timer: mdiTimerOutline,
tts: mdiSpeakerMessage,

View File

@@ -5,12 +5,15 @@ import { FrontendLocaleData, TimeZone } from "../../data/translation";
const calcZonedDate = (
date: Date,
tz: string,
fn: (date: Date, options?: any) => Date,
fn: (date: Date, options?: any) => Date | number | boolean,
options?
) => {
const inputZoned = utcToZonedTime(date, tz);
const fnZoned = fn(inputZoned, options);
return zonedTimeToUtc(fnZoned, tz);
if (fnZoned instanceof Date) {
return zonedTimeToUtc(fnZoned, tz) as Date;
}
return fnZoned;
};
export const calcDate = (
@@ -21,5 +24,16 @@ export const calcDate = (
options?
) =>
locale.time_zone === TimeZone.server
? calcZonedDate(date, config.time_zone, fn, options)
? (calcZonedDate(date, config.time_zone, fn, options) as Date)
: fn(date, options);
export const calcDateProperty = (
date: Date,
fn: (date: Date, options?: any) => boolean | number,
locale: FrontendLocaleData,
config: HassConfig,
options?
) =>
locale.time_zone === TimeZone.server
? (calcZonedDate(date, config.time_zone, fn, options) as number | boolean)
: fn(date, options);

View File

@@ -37,6 +37,23 @@ const formatDateMem = memoizeOne(
})
);
// Aug 10, 2021
export const formatDateShort = (
dateObj: Date,
locale: FrontendLocaleData,
config: HassConfig
) => formatDateShortMem(locale, config.time_zone).format(dateObj);
const formatDateShortMem = memoizeOne(
(locale: FrontendLocaleData, serverTimeZone: string) =>
new Intl.DateTimeFormat(locale.language, {
year: "numeric",
month: "short",
day: "numeric",
timeZone: locale.time_zone === "server" ? serverTimeZone : undefined,
})
);
// 10/08/2021
export const formatDateNumeric = (
dateObj: Date,
@@ -102,13 +119,13 @@ const formatDateNumericMem = memoizeOne(
);
// Aug 10
export const formatDateShort = (
export const formatDateVeryShort = (
dateObj: Date,
locale: FrontendLocaleData,
config: HassConfig
) => formatDateShortMem(locale, config.time_zone).format(dateObj);
) => formatDateVeryShortMem(locale, config.time_zone).format(dateObj);
const formatDateShortMem = memoizeOne(
const formatDateVeryShortMem = memoizeOne(
(locale: FrontendLocaleData, serverTimeZone: string) =>
new Intl.DateTimeFormat(locale.language, {
day: "numeric",

View File

@@ -1,8 +1,13 @@
import { HaDurationData } from "../../components/ha-duration-input";
import { FrontendLocaleData } from "../../data/translation";
import "../../resources/intl-polyfill";
const leftPad = (num: number) => (num < 10 ? `0${num}` : num);
export const formatDuration = (duration: HaDurationData) => {
export const formatDuration = (
locale: FrontendLocaleData,
duration: HaDurationData
) => {
const d = duration.days || 0;
const h = duration.hours || 0;
const m = duration.minutes || 0;
@@ -10,7 +15,11 @@ export const formatDuration = (duration: HaDurationData) => {
const ms = duration.milliseconds || 0;
if (d > 0) {
return `${d} day${d === 1 ? "" : "s"} ${h}:${leftPad(m)}:${leftPad(s)}`;
return `${Intl.NumberFormat(locale.language, {
style: "unit",
unit: "day",
unitDisplay: "long",
}).format(d)} ${h}:${leftPad(m)}:${leftPad(s)}`;
}
if (h > 0) {
return `${h}:${leftPad(m)}:${leftPad(s)}`;
@@ -19,10 +28,18 @@ export const formatDuration = (duration: HaDurationData) => {
return `${m}:${leftPad(s)}`;
}
if (s > 0) {
return `${s} second${s === 1 ? "" : "s"}`;
return Intl.NumberFormat(locale.language, {
style: "unit",
unit: "second",
unitDisplay: "long",
}).format(s);
}
if (ms > 0) {
return `${ms} millisecond${ms === 1 ? "" : "s"}`;
return Intl.NumberFormat(locale.language, {
style: "unit",
unit: "millisecond",
unitDisplay: "long",
}).format(ms);
}
return null;
};

View File

@@ -1,5 +1,5 @@
import { ThemeVars } from "../../data/ws-themes";
import { darkStyles, derivedStyles } from "../../resources/styles";
import { darkStyles, derivedStyles } from "../../resources/styles-data";
import type { HomeAssistant } from "../../types";
import {
hex2rgb,
@@ -41,9 +41,7 @@ export const applyThemesOnElement = (
// If there is no explicitly desired dark mode provided, we automatically
// use the active one from `themes`.
const darkMode =
themeSettings && themeSettings?.dark !== undefined
? themeSettings?.dark
: themes.darkMode;
themeSettings?.dark !== undefined ? themeSettings.dark : themes.darkMode;
let cacheKey = themeToApply;
let themeRules: Partial<ThemeVars> = {};
@@ -135,10 +133,19 @@ export const applyThemesOnElement = (
// Set and/or reset styles
if (element.updateStyles) {
// Use updateStyles() method of Polymer elements
element.updateStyles(styles);
} else if (window.ShadyCSS) {
// Implement updateStyles() method of Polymer elements
// Use ShadyCSS if available
window.ShadyCSS.styleSubtree(/** @type {!HTMLElement} */ element, styles);
} else {
for (const s in styles) {
if (s === null) {
element.style.removeProperty(s);
} else {
element.style.setProperty(s, styles[s]);
}
}
}
};

View File

@@ -18,6 +18,7 @@ import { blankBeforePercent } from "../translations/blank_before_percent";
import { LocalizeFunc } from "../translations/localize";
import { computeDomain } from "./compute_domain";
import { computeStateDomain } from "./compute_state_domain";
import { blankBeforeUnit } from "../translations/blank_before_unit";
export const computeAttributeValueDisplay = (
localize: LocalizeFunc,
@@ -55,20 +56,12 @@ export const computeAttributeValueDisplay = (
unit = getWeatherUnit(config, stateObj as WeatherEntity, attribute);
}
if (unit === "%") {
return `${formattedValue}${blankBeforePercent(locale)}${unit}`;
}
if (unit === "°") {
return `${formattedValue}${unit}`;
if (TEMPERATURE_ATTRIBUTES.has(attribute)) {
unit = config.unit_system.temperature;
}
if (unit) {
return `${formattedValue} ${unit}`;
}
if (TEMPERATURE_ATTRIBUTES.has(attribute)) {
return `${formattedValue} ${config.unit_system.temperature}`;
return `${formattedValue}${blankBeforeUnit(unit, locale)}${unit}`;
}
return formattedValue;

View File

@@ -3,13 +3,13 @@ import { UNAVAILABLE, UNKNOWN } from "../../data/entity";
import { EntityRegistryDisplayEntry } from "../../data/entity_registry";
import { FrontendLocaleData, TimeZone } from "../../data/translation";
import {
updateIsInstallingFromAttributes,
UPDATE_SUPPORT_PROGRESS,
updateIsInstallingFromAttributes,
} from "../../data/update";
import { HomeAssistant } from "../../types";
import {
formatDuration,
UNIT_TO_MILLISECOND_CONVERT,
formatDuration,
} from "../datetime/duration";
import { formatDate } from "../datetime/format_date";
import { formatDateTime } from "../datetime/format_date_time";
@@ -19,10 +19,10 @@ import {
getNumberFormatOptions,
isNumericFromAttributes,
} from "../number/format_number";
import { blankBeforePercent } from "../translations/blank_before_percent";
import { LocalizeFunc } from "../translations/localize";
import { computeDomain } from "./compute_domain";
import { supportsFeatureFromAttributes } from "./supports-feature";
import { blankBeforeUnit } from "../translations/blank_before_unit";
export const computeStateDisplaySingleEntity = (
localize: LocalizeFunc,
@@ -108,16 +108,20 @@ export const computeStateDisplayFromEntityAttributes = (
// fallback to default
}
}
const unit = !attributes.unit_of_measurement
? ""
: attributes.unit_of_measurement === "%"
? blankBeforePercent(locale) + "%"
: ` ${attributes.unit_of_measurement}`;
return `${formatNumber(
const value = formatNumber(
state,
locale,
getNumberFormatOptions({ state, attributes } as HassEntity, entity)
)}${unit}`;
);
const unit = attributes.unit_of_measurement;
if (unit) {
return `${value}${blankBeforeUnit(unit)}${unit}`;
}
return value;
}
const domain = computeDomain(entityId);

View File

@@ -1,19 +1,29 @@
// https://gist.github.com/hagemann/382adfc57adbd5af078dc93feef01fe1
export const slugify = (value: string, delimiter = "_") => {
const a =
"àáäâãåăæąçćčđďèéěėëêęğǵḧìíïîįłḿǹńňñòóöôœøṕŕřßşśšșťțùúüûǘůűūųẃẍÿýźžż·/_,:;";
const b = `aaaaaaaaacccddeeeeeeegghiiiiilmnnnnooooooprrsssssttuuuuuuuuuwxyyzzz${delimiter}${delimiter}${delimiter}${delimiter}${delimiter}${delimiter}`;
"àáâäæãåāăąçćčđďèéêëēėęěğǵḧîïíīįìıİłḿñńǹňôöòóœøōõőṕŕřßśšşșťțûüùúūǘůűųẃẍÿýžźż·";
const b = `aaaaaaaaaacccddeeeeeeeegghiiiiiiiilmnnnnoooooooooprrsssssttuuuuuuuuuwxyyzzz${delimiter}`;
const p = new RegExp(a.split("").join("|"), "g");
return value
.toString()
.toLowerCase()
.replace(/\s+/g, delimiter) // Replace spaces with delimiter
.replace(p, (c) => b.charAt(a.indexOf(c))) // Replace special characters
.replace(/&/g, `${delimiter}and${delimiter}`) // Replace & with 'and'
.replace(/[^\w-]+/g, "") // Remove all non-word characters
.replace(/-/g, delimiter) // Replace - with delimiter
.replace(new RegExp(`(${delimiter})\\1+`, "g"), "$1") // Replace multiple delimiters with single delimiter
.replace(new RegExp(`^${delimiter}+`), "") // Trim delimiter from start of text
.replace(new RegExp(`${delimiter}+$`), ""); // Trim delimiter from end of text
let slugified;
if (value === "") {
slugified = "";
} else {
slugified = value
.toString()
.toLowerCase()
.replace(p, (c) => b.charAt(a.indexOf(c))) // Replace special characters
.replace(/(\d),(?=\d)/g, "$1") // Remove Commas between numbers
.replace(/[^a-z0-9]+/g, delimiter) // Replace all non-word characters
.replace(new RegExp(`(${delimiter})\\1+`, "g"), "$1") // Replace multiple delimiters with single delimiter
.replace(new RegExp(`^${delimiter}+`), "") // Trim delimiter from start of text
.replace(new RegExp(`${delimiter}+$`), ""); // Trim delimiter from end of text
if (slugified === "") {
slugified = "unknown";
}
}
return slugified;
};

View File

@@ -13,45 +13,33 @@ export const handleStructError = (
for (const failure of err.failures()) {
if (failure.value === undefined) {
errors.push(
hass.localize(
"ui.errors.config.key_missing",
"key",
failure.path.join(".")
)
hass.localize("ui.errors.config.key_missing", {
key: failure.path.join("."),
})
);
} else if (failure.type === "never") {
warnings.push(
hass.localize(
"ui.errors.config.key_not_expected",
"key",
failure.path.join(".")
)
hass.localize("ui.errors.config.key_not_expected", {
key: failure.path.join("."),
})
);
} else if (failure.type === "union") {
continue;
} else if (failure.type === "enums") {
warnings.push(
hass.localize(
"ui.errors.config.key_wrong_type",
"key",
failure.path.join("."),
"type_correct",
failure.message.replace("Expected ", "").split(", ")[0],
"type_wrong",
JSON.stringify(failure.value)
)
hass.localize("ui.errors.config.key_wrong_type", {
key: failure.path.join("."),
type_correct: failure.message.replace("Expected ", "").split(", ")[0],
type_wrong: JSON.stringify(failure.value),
})
);
} else {
warnings.push(
hass.localize(
"ui.errors.config.key_wrong_type",
"key",
failure.path.join("."),
"type_correct",
failure.refinement || failure.type,
"type_wrong",
JSON.stringify(failure.value)
)
hass.localize("ui.errors.config.key_wrong_type", {
key: failure.path.join("."),
type_correct: failure.refinement || failure.type,
type_wrong: JSON.stringify(failure.value),
})
);
}
}

View File

@@ -0,0 +1,15 @@
import { FrontendLocaleData } from "../../data/translation";
import { blankBeforePercent } from "./blank_before_percent";
export const blankBeforeUnit = (
unit: string,
localeOptions?: FrontendLocaleData
): string => {
if (unit === "°") {
return "";
}
if (localeOptions && unit === "%") {
return blankBeforePercent(localeOptions);
}
return " ";
};

View File

@@ -23,6 +23,7 @@ export function computeDirectionStyles(isRTL: boolean, element: LitElement) {
}
export function setDirectionStyles(direction: string, element: LitElement) {
document.dir = direction;
element.style.direction = direction;
element.style.setProperty("--direction", direction);
element.style.setProperty(

View File

@@ -1,6 +1,13 @@
import "@material/mwc-button";
import { mdiAlertOctagram, mdiCheckBold } from "@mdi/js";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import {
css,
CSSResultGroup,
html,
LitElement,
nothing,
TemplateResult,
} from "lit";
import { customElement, property, state } from "lit/decorators";
import "../ha-circular-progress";
import "../ha-svg-icon";
@@ -27,7 +34,7 @@ export class HaProgressButton extends LitElement {
<slot></slot>
</mwc-button>
${!overlay
? ""
? nothing
: html`
<div class="progress">
${this._result === "success"

View File

@@ -39,7 +39,7 @@ import {
formatDate,
formatDateMonth,
formatDateMonthYear,
formatDateShort,
formatDateVeryShort,
formatDateWeekdayDay,
formatDateYear,
} from "../../common/datetime/format_date";
@@ -128,13 +128,13 @@ _adapters._date.override({
this.options.config
);
case "day":
return formatDateShort(
return formatDateVeryShort(
new Date(time),
this.options.locale,
this.options.config
);
case "week":
return formatDate(
return formatDateVeryShort(
new Date(time),
this.options.locale,
this.options.config

View File

@@ -12,6 +12,7 @@ import { styleMap } from "lit/directives/style-map";
import { clamp } from "../../common/number/clamp";
import { computeRTL } from "../../common/util/compute_rtl";
import { HomeAssistant } from "../../types";
import { debounce } from "../../common/util/debounce";
export const MIN_TIME_BETWEEN_UPDATES = 60 * 5 * 1000;
@@ -52,6 +53,12 @@ export class HaChartBase extends LitElement {
@state() private _hiddenDatasets: Set<number> = new Set();
private _paddingUpdateCount = 0;
private _paddingUpdateLock = false;
private _paddingYAxisInternal = 0;
public disconnectedCallback() {
super.disconnectedCallback();
this._releaseCanvas();
@@ -104,9 +111,44 @@ export class HaChartBase extends LitElement {
});
}
public shouldUpdate(changedProps: PropertyValues): boolean {
if (
this._paddingUpdateLock &&
changedProps.size === 1 &&
changedProps.has("paddingYAxis")
) {
return false;
}
return true;
}
private _debouncedClearUpdates = debounce(
() => {
this._paddingUpdateCount = 0;
},
2000,
false
);
public willUpdate(changedProps: PropertyValues): void {
super.willUpdate(changedProps);
if (!this._paddingUpdateLock) {
this._paddingYAxisInternal = this.paddingYAxis;
if (changedProps.size === 1 && changedProps.has("paddingYAxis")) {
this._paddingUpdateCount++;
if (this._paddingUpdateCount > 300) {
this._paddingUpdateLock = true;
// eslint-disable-next-line
console.error(
"Detected excessive chart padding updates, possibly an infinite loop. Disabling axis padding."
);
} else {
this._debouncedClearUpdates();
}
}
}
if (!this.hasUpdated || !this.chart) {
return;
}
@@ -171,10 +213,10 @@ export class HaChartBase extends LitElement {
this.height ?? this._chartHeight ?? this.clientWidth / 2
}px`,
"padding-left": `${
computeRTL(this.hass) ? 0 : this.paddingYAxis
computeRTL(this.hass) ? 0 : this._paddingYAxisInternal
}px`,
"padding-right": `${
computeRTL(this.hass) ? this.paddingYAxis : 0
computeRTL(this.hass) ? this._paddingYAxisInternal : 0
}px`,
})}
>
@@ -324,7 +366,7 @@ export class HaChartBase extends LitElement {
clamp(
context.tooltip.caretX,
100,
this.clientWidth - 100 - this.paddingYAxis
this.clientWidth - 100 - this._paddingYAxisInternal
) -
100 +
"px",

View File

@@ -141,16 +141,10 @@ export class StateHistoryChartLine extends LitElement {
`${context.dataset.label}: ${formatNumber(
context.parsed.y,
this.hass.locale,
this.data[context.datasetIndex]?.entity_id
? getNumberFormatOptions(
this.hass.states[
this.data[context.datasetIndex].entity_id
],
this.hass.entities[
this.data[context.datasetIndex].entity_id
]
)
: undefined
getNumberFormatOptions(
undefined,
this.hass.entities[this._entityIds[context.datasetIndex]]
)
)} ${this.unit}`,
},
},
@@ -180,7 +174,9 @@ export class StateHistoryChartLine extends LitElement {
return;
}
const points = e.chart.getElementsAtEventForMode(
const chart = e.chart;
const points = chart.getElementsAtEventForMode(
e,
"nearest",
{ intersect: true },
@@ -192,6 +188,7 @@ export class StateHistoryChartLine extends LitElement {
fireEvent(this, "hass-more-info", {
entityId: this._entityIds[firstPoint.datasetIndex],
});
chart.canvas.dispatchEvent(new Event("mouseout")); // to hide tooltip
}
},
};

View File

@@ -238,6 +238,7 @@ export class StateHistoryChartTimeline extends LitElement {
// @ts-ignore
entityId: this._chartData?.datasets[index]?.label,
});
chart.canvas.dispatchEvent(new Event("mouseout")); // to hide tooltip
},
};
}

View File

@@ -73,9 +73,9 @@ export class StateHistoryCharts extends LitElement {
@property({ type: Boolean }) public isLoadingData = false;
@state() private _computedStartTime!: Date;
private _computedStartTime!: Date;
@state() private _computedEndTime!: Date;
private _computedEndTime!: Date;
@state() private _maxYWidth = 0;
@@ -114,31 +114,6 @@ export class StateHistoryCharts extends LitElement {
${this.hass.localize("ui.components.history_charts.no_history_found")}
</div>`;
}
const now = new Date();
this._computedEndTime =
this.upToNow || !this.endTime || this.endTime > now ? now : this.endTime;
if (this.startTime) {
this._computedStartTime = this.startTime;
} else if (this.hoursToShow) {
this._computedStartTime = new Date(
new Date().getTime() - 60 * 60 * this.hoursToShow * 1000
);
} else {
this._computedStartTime = new Date(
this.historyData.timeline.reduce(
(minTime, stateInfo) =>
Math.min(
minTime,
new Date(stateInfo.data[0].last_changed).getTime()
),
new Date().getTime()
)
);
}
const combinedItems = this.historyData.timeline.length
? (this.virtualize
? chunkData(this.historyData.timeline, CANVAS_TIMELINE_ROWS_CHUNK)
@@ -220,10 +195,45 @@ export class StateHistoryCharts extends LitElement {
return true;
}
protected willUpdate() {
protected willUpdate(changedProps: PropertyValues) {
if (!this.hasUpdated) {
loadVirtualizer();
}
if (
[...changedProps.keys()].some(
(prop) =>
!(
["_maxYWidth", "_childYWidths", "_chartCount"] as PropertyKey[]
).includes(prop)
)
) {
// Don't recompute times when we just want to update layout
const now = new Date();
this._computedEndTime =
this.upToNow || !this.endTime || this.endTime > now
? now
: this.endTime;
if (this.startTime) {
this._computedStartTime = this.startTime;
} else if (this.hoursToShow) {
this._computedStartTime = new Date(
new Date().getTime() - 60 * 60 * this.hoursToShow * 1000
);
} else {
this._computedStartTime = new Date(
(this.historyData?.timeline ?? []).reduce(
(minTime, stateInfo) =>
Math.min(
minTime,
new Date(stateInfo.data[0].last_changed).getTime()
),
new Date().getTime()
)
);
}
}
}
protected updated(changedProps: PropertyValues) {

View File

@@ -19,6 +19,7 @@ import { isComponentLoaded } from "../../common/config/is_component_loaded";
import {
formatNumber,
numberFormatToLocale,
getNumberFormatOptions,
} from "../../common/number/format_number";
import {
getDisplayUnit,
@@ -72,8 +73,12 @@ export class StatisticsChart extends LitElement {
@property({ type: Boolean }) public isLoadingData = false;
@property() public period?: string;
@state() private _chartData: ChartData = { datasets: [] };
@state() private _statisticIds: string[] = [];
@state() private _chartOptions?: ChartOptions;
@query("ha-chart-base") private _chart?: HaChartBase;
@@ -89,7 +94,12 @@ export class StatisticsChart extends LitElement {
}
public willUpdate(changedProps: PropertyValues) {
if (!this.hasUpdated || changedProps.has("unit")) {
if (
!this.hasUpdated ||
changedProps.has("unit") ||
changedProps.has("period") ||
changedProps.has("chartType")
) {
this._createOptions();
}
if (
@@ -157,6 +167,7 @@ export class StatisticsChart extends LitElement {
},
},
ticks: {
source: this.chartType === "bar" ? "data" : undefined,
maxRotation: 0,
sampleSize: 5,
autoSkipPadding: 20,
@@ -170,6 +181,12 @@ export class StatisticsChart extends LitElement {
},
time: {
tooltipFormat: "datetime",
unit:
this.chartType === "bar" &&
this.period &&
["hour", "day", "week", "month"].includes(this.period)
? this.period
: undefined,
},
},
y: {
@@ -189,7 +206,11 @@ export class StatisticsChart extends LitElement {
label: (context) =>
`${context.dataset.label}: ${formatNumber(
context.parsed.y,
this.hass.locale
this.hass.locale,
getNumberFormatOptions(
undefined,
this.hass.entities[this._statisticIds[context.datasetIndex]]
)
)} ${
// @ts-ignore
context.dataset.unit || ""
@@ -248,6 +269,7 @@ export class StatisticsChart extends LitElement {
let colorIndex = 0;
const statisticsData = Object.entries(this.statisticsData);
const totalDataSets: ChartDataset<"line">[] = [];
const statisticIds: string[] = [];
let endTime: Date;
if (statisticsData.length === 0) {
@@ -386,6 +408,7 @@ export class StatisticsChart extends LitElement {
unit: meta?.unit_of_measurement,
band,
});
statisticIds.push(statistic_id);
}
});
@@ -411,11 +434,7 @@ export class StatisticsChart extends LitElement {
} else {
val = stat[type];
}
dataValues.push(
val !== null && val !== undefined
? Math.round(val * 100) / 100
: null
);
dataValues.push(val ?? null);
});
pushData(startDate, new Date(stat.end), dataValues);
});
@@ -431,6 +450,7 @@ export class StatisticsChart extends LitElement {
this._chartData = {
datasets: totalDataSets,
};
this._statisticIds = statisticIds;
}
static get styles(): CSSResultGroup {

View File

@@ -0,0 +1,53 @@
import { MdAssistChip } from "@material/web/chips/assist-chip";
import { css, html } from "lit";
import { customElement, property } from "lit/decorators";
@customElement("ha-assist-chip")
export class HaAssistChip extends MdAssistChip {
@property({ type: Boolean, reflect: true }) filled = false;
static override styles = [
...super.styles,
css`
:host {
--md-sys-color-primary: var(--primary-text-color);
--md-sys-color-on-surface: var(--primary-text-color);
--md-assist-chip-container-shape: 16px;
--md-assist-chip-outline-color: var(--outline-color);
--md-assist-chip-label-text-weight: 400;
--ha-assist-chip-filled-container-color: rgba(
var(--rgb-primary-text-color),
0.15
);
}
/** Material 3 doesn't have a filled chip, so we have to make our own **/
.filled {
display: flex;
pointer-events: none;
border-radius: inherit;
inset: 0;
position: absolute;
background-color: var(--ha-assist-chip-filled-container-color);
}
/** Set the size of mdc icons **/
::slotted([slot="icon"]) {
display: flex;
--mdc-icon-size: var(--md-input-chip-icon-size, 18px);
}
`,
];
protected override renderOutline() {
if (this.filled) {
return html`<span class="filled"></span>`;
}
return super.renderOutline();
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-assist-chip": HaAssistChip;
}
}

View File

@@ -0,0 +1,11 @@
import { MdChipSet } from "@material/web/chips/chip-set";
import { customElement } from "lit/decorators";
@customElement("ha-chip-set")
export class HaChipSet extends MdChipSet {}
declare global {
interface HTMLElementTagNameMap {
"ha-chip-set": HaChipSet;
}
}

View File

@@ -0,0 +1,41 @@
import { MdFilterChip } from "@material/web/chips/filter-chip";
import { css, html } from "lit";
import { customElement, property } from "lit/decorators";
@customElement("ha-filter-chip")
export class HaFilterChip extends MdFilterChip {
@property({ type: Boolean, reflect: true, attribute: "no-leading-icon" })
noLeadingIcon = false;
static override styles = [
...super.styles,
css`
:host {
--md-sys-color-primary: var(--primary-text-color);
--md-sys-color-on-surface: var(--primary-text-color);
--md-sys-color-on-surface-variant: var(--primary-text-color);
--md-sys-color-on-secondary-container: var(--primary-text-color);
--md-filter-chip-container-shape: 16px;
--md-filter-chip-outline-color: var(--outline-color);
--md-filter-chip-selected-container-color: rgba(
var(--rgb-primary-text-color),
0.15
);
}
`,
];
protected renderLeadingIcon() {
if (this.noLeadingIcon) {
// eslint-disable-next-line lit/prefer-nothing
return html``;
}
return super.renderLeadingIcon();
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-filter-chip": HaFilterChip;
}
}

View File

@@ -0,0 +1,35 @@
import { MdInputChip } from "@material/web/chips/input-chip";
import { css } from "lit";
import { customElement } from "lit/decorators";
@customElement("ha-input-chip")
export class HaInputChip extends MdInputChip {
static override styles = [
...super.styles,
css`
:host {
--md-sys-color-primary: var(--primary-text-color);
--md-sys-color-on-surface: var(--primary-text-color);
--md-sys-color-on-surface-variant: var(--primary-text-color);
--md-sys-color-on-secondary-container: var(--primary-text-color);
--md-input-chip-container-shape: 16px;
--md-input-chip-outline-color: var(--outline-color);
--md-input-chip-selected-container-color: rgba(
var(--rgb-primary-text-color),
0.15
);
}
/** Set the size of mdc icons **/
::slotted([slot="icon"]) {
display: flex;
--mdc-icon-size: var(--md-input-chip-icon-size, 18px);
}
`,
];
}
declare global {
interface HTMLElementTagNameMap {
"ha-input-chip": HaInputChip;
}
}

View File

@@ -31,6 +31,10 @@ const Component = Vue.extend({
type: Boolean,
default: true,
},
openingDirection: {
type: String,
default: "right",
},
disabled: {
type: Boolean,
default: false,
@@ -66,7 +70,7 @@ const Component = Vue.extend({
props: {
"time-picker": this.timePicker,
"auto-apply": this.autoApply,
opens: "right",
opens: this.openingDirection,
"show-dropdowns": false,
"time-picker24-hour": this.twentyfourHours,
disabled: this.disabled,
@@ -126,9 +130,9 @@ class DateRangePickerElement extends WrappedElement {
${dateRangePickerStyles}
.calendars {
display: flex;
flex-wrap: nowrap !important;
}
.daterangepicker {
left: 0px !important;
top: auto;
box-shadow: var(--ha-card-box-shadow, none);
background-color: var(--card-background-color);
@@ -252,6 +256,10 @@ class DateRangePickerElement extends WrappedElement {
direction: ltr;
text-align: left;
}
.vue-daterange-picker{
min-width: unset !important;
display: block !important;
}
`;
const shadowRoot = this.shadowRoot!;
shadowRoot.appendChild(style);

Some files were not shown because too many files have changed in this diff Show More