Compare commits

..

614 Commits

Author SHA1 Message Date
Bram Kragten
d8b4611c24 20221213.0 (#14757) 2022-12-13 17:30:15 +01:00
Philip Allgaier
9c27bb37a0 Ensure consistent light state icon brightness (#14740)
* Ensure consistent light state icon brightness

* Update hui-entity-card.ts

* Update hui-entity-card.ts

Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
2022-12-13 17:23:49 +01:00
Bram Kragten
f2b7288e92 Bumped version to 20221213.0 2022-12-13 17:22:37 +01:00
Bram Kragten
f7aecb0d6d Move groups up, after areas, move devices down (#14741) 2022-12-13 17:01:59 +01:00
Joakim Sørensen
1da8a974f8 Do not try design preview on non-forks (#14753) 2022-12-13 16:53:01 +01:00
Paul Bottein
b82d6fd35f Fix climate hvac action color (#14747) 2022-12-13 16:49:12 +01:00
Paul Bottein
62bc171b8c Only use custom color when active on tile card (#14744) 2022-12-13 14:17:13 +01:00
Paul Bottein
2d7973af79 Fix brightness on button card (#14724) 2022-12-13 14:02:48 +01:00
Paul Bottein
d64bb98bb4 Fix binary sensor color when off (#14735) 2022-12-13 12:11:09 +01:00
Paul Bottein
5cabf1d041 Use compute state display for select (#14736) 2022-12-13 11:07:57 +01:00
Philip Allgaier
180357e0db Align domain icon for person and device_tracker when away (#14652) 2022-12-13 09:59:26 +01:00
Bram Kragten
c1dba217da Make error on general config better + default timezone (#14635) 2022-12-12 20:20:56 +01:00
Steve Repsher
8d1ecdb27e Bump prettier to 2.8.1 (#14694)
* Bump prettier to 2.8.1

* Reformat ha-data-table
2022-12-12 11:45:06 -05:00
Joakim Sørensen
f83544dd38 Add action for design preview (#14721)
* Add action for design preview

* Remove netlify_build_gallery
2022-12-12 16:23:11 +01:00
Joakim Sørensen
2ae137bbc2 Add fallback URLs (#14720) 2022-12-12 16:22:34 +01:00
Bram Kragten
9f8aa0b4bf 20221212.0 (#14722) 2022-12-12 16:08:35 +01:00
Bram Kragten
149fa5fca6 Bumped version to 20221212.0 2022-12-12 15:53:20 +01:00
Paul Bottein
0fb35fd0d0 Transparent unavailable state in history (#14710)
* Use transparent color for unavailable state for history

* Remove inactive color

* Only color active state for badge icon

* Simplify condition

* Update src/components/chart/timeline-chart/textbar-element.ts

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

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-12-12 15:52:33 +01:00
Paul Bottein
544272b4df Improve entity not found tile card (#14711) 2022-12-12 15:49:31 +01:00
Philip Allgaier
b939978de1 Enable full day event mode in calendar card day grid (#14716) 2022-12-12 15:48:26 +01:00
Bram Kragten
d74fb8717c Fix sorting auto generated dashboard (#14707) 2022-12-12 15:47:05 +01:00
Philip Allgaier
f204a163d4 Show pointer cursor when hovering calender event or day number (#14712) 2022-12-12 15:21:28 +01:00
Philip Allgaier
bc9fb9a472 Fix event alignment for current day (#14717) 2022-12-12 15:21:01 +01:00
karwosts
1e654d9661 Fix gauge-editor loading of severity values. (#14700)
fixes undefined
2022-12-12 15:20:29 +01:00
Paul Bottein
03d33759b8 Use light blue for media player to improve contrast (#14713) 2022-12-12 14:09:55 +01:00
Joakim Sørensen
ef7d696f9d Adjust cast deployment (#14651)
* Adjust cast deployment

* Handle dev/master builds

* Consistant
2022-12-12 13:46:03 +01:00
Bram Kragten
545141da92 Align dev container settings with core (#14709) 2022-12-12 11:58:45 +01:00
Bram Kragten
467957005d Fix pick dashboard row (#14708) 2022-12-12 11:58:30 +01:00
Steve Repsher
348c3c9787 Revise vscode extensions (#14679) 2022-12-12 10:51:25 +01:00
Philip Allgaier
fe0492c2e0 Enable all-day / multi-day rendering for calendar (#14660) 2022-12-12 10:44:29 +01:00
Philip Allgaier
0b377c060c Only reset primary/accent color if theme actually changes (#14659)
fixes undefined
2022-12-12 10:43:20 +01:00
Jan Bouwhuis
0f971e5868 Add QoS parameter for MQTT Publish (#14559)
* Add QoS parameter for MQTT Publish

* Follow up comment
2022-12-12 09:42:37 +01:00
Philip Allgaier
1dbe8c9b64 Ensure consistent "blank before percent" handling (#14638) 2022-12-09 21:47:57 -05:00
Paul Bottein
6e4a6cb0db Improve person/alarm/lock state (#14633)
* Opening device_class as alerting

* Don't use blue color for default active color

* Improve lock colors

* Green color for disarmed alarm

* Revert "Opening device_class as alerting"

This reverts commit b78342678d430eb3967f82e759342955b44417ad.

* Don't use active color

* Revert amber color because fixed in another PR

* Improve person, lock and alarm color state

* Sort variables

* Use alarm color in alarm card
2022-12-09 21:38:59 -05:00
epenet
3f1903bd87 Add new irradiance device class (#14593) 2022-12-09 21:57:28 +01:00
epenet
9643e0268f Add new atmospheric pressure device class (#14596) 2022-12-09 21:56:57 +01:00
Paul Bottein
23573d8c26 Theme color fixes (#14672)
* Split off and unavailable colors

* off and unvailable in history panel

* Refactor tile card color code

* Use new color in state badge

* Use new colors in button and entity card

* Rename off to inactive

* Add inactive color to color picker

* Use amber instead of blue
2022-12-09 10:04:14 -05:00
Paul Bottein
3c8c1260b1 Show start pause button on tile card if vacuum support pause (#14646) 2022-12-08 19:23:43 +01:00
Joakim Sørensen
b84de87688 Adjust design deployment (#14650) 2022-12-08 17:17:56 +01:00
Joakim Sørensen
2d30994e56 Adjust demo deployment (#14649) 2022-12-08 17:17:28 +01:00
Bram Kragten
4ea19a6041 Add daily gallery build action (#14640)
Co-authored-by: Joakim Sørensen <ludeeus@ludeeus.dev>
2022-12-08 14:41:51 +00:00
Bram Kragten
af82c0d0c4 20221208.0 (#14644) 2022-12-08 15:17:56 +01:00
Bram Kragten
2b5ef1207c Bumped version to 20221208.0 2022-12-08 15:07:10 +01:00
Philip Allgaier
feddbdba96 More "state_color" variants for gallery + wording tweaks (#14641) 2022-12-08 14:05:09 +00:00
Bram Kragten
b581b95d9d Use correct close dialog function for dialog event editor` (#14604)
* Use correct close dialog function for `dialog event editor``

* Update dialog-calendar-event-editor.ts
2022-12-08 08:42:22 -05:00
Bram Kragten
8c69c772d1 Fix statistics graph card (#14631) 2022-12-08 13:20:01 +01:00
Paul Bottein
ba09120ff3 Add open label if cover is open on tile card (#14632) 2022-12-08 13:19:49 +01:00
Philip Allgaier
a8d242719f Fix disabled button state for vacuum in tile card (#14624)
fixes undefined
2022-12-08 13:19:18 +01:00
Paul Bottein
0d0028fced Fixes state history colors edge cases (#14626) 2022-12-08 12:01:18 +01:00
Erik Montnemery
d1b1eecd92 Fix showing a statistics graph with type 'change' (#14622) 2022-12-08 11:37:57 +01:00
Philip Allgaier
3b51050b52 Fix hidden/broken input_datetime date selector (#14623)
fixes undefined
2022-12-08 11:36:53 +01:00
Philip Allgaier
34e1d745be Restore correct default legend behavior for history graph card (#14612)
fixes undefined
2022-12-08 11:34:13 +01:00
Allen Porter
efda2ab626 Fix calendar event creation error handling (#14603) 2022-12-07 17:39:22 +01:00
Bram Kragten
ae354fa8da 20221207.0 (#14602) 2022-12-07 16:42:43 +01:00
Bram Kragten
ef130be352 Bumped version to 20221207.0 2022-12-07 16:41:44 +01:00
Paul Bottein
f1393e5f00 Clean up colors code and add all missing domains (#14597) 2022-12-07 14:47:54 +01:00
Bram Kragten
dac784553e Fix unresponsive date picker (#14600) 2022-12-07 10:42:40 +00:00
Philip Allgaier
d2ad67384f Consider ignored repairs for the "no repairs available" note (#14598) 2022-12-07 11:38:27 +01:00
Philip Allgaier
69d16ab9b4 Various minor tweaks (#14588) 2022-12-07 10:05:24 +01:00
Allen Porter
a941ed4f90 Fix off by one day in date input (in calendar) (#14590)
fixes undefined
2022-12-07 10:04:45 +01:00
Philip Allgaier
774259224b Fix accidental date cross-overs in local cal event creation (#14587) 2022-12-07 09:56:21 +01:00
dependabot[bot]
8a5f781ca2 Bump express from 4.17.1 to 4.18.2 (#14586)
* Bump express from 4.17.1 to 4.18.2

Bumps [express](https://github.com/expressjs/express) from 4.17.1 to 4.18.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.1...4.18.2)

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

Signed-off-by: dependabot[bot] <support@github.com>

* Deduplicate dependencies

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>
2022-12-07 05:12:42 +00:00
Bram Kragten
dacef605c7 20221206.0 (#14585) 2022-12-06 18:35:05 +01:00
Bram Kragten
2c279e2dec Bumped version to 20221206.0 2022-12-06 18:30:55 +01:00
Bram Kragten
06ee08db36 Sort generated dashboard (#14577) 2022-12-06 18:30:23 +01:00
Philip Allgaier
34dfaa5a0f Fix week start on Saturday for scheduler (#14566) 2022-12-06 18:29:49 +01:00
Philip Allgaier
b06db26540 Filter out unavailable calendars in calendar panel (#14584) 2022-12-06 18:28:29 +01:00
Philip Allgaier
076a6c4459 Catch calender events fetch errors and keep UI working (#14517)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-12-06 17:28:16 +00:00
Paul Bottein
0001cad423 Better colors in timeline chart in more info (#14581) 2022-12-06 17:15:59 +00:00
Paul Bottein
d622d9d420 Add unavailable badge for tile card (#14582)
add unavailable badge for tile card
2022-12-06 17:14:18 +00:00
Paul Bottein
228fd4b7fe Fix camera and timer active state (#14578) 2022-12-06 17:46:07 +01:00
Paul Bottein
e6f2e8058b Color adjustments for entity state (#14557) 2022-12-06 17:45:24 +01:00
Philip Allgaier
83ba594cc4 Visual fixes and resize observer for scheduler form (#14527) 2022-12-06 13:29:14 +01:00
Philip Allgaier
ff64dc2631 Prevent invalid event durations in calendar (#14545)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-12-06 12:23:04 +00:00
Steve Repsher
745753c526 Make corrections to .gitignore for directories (#14567) 2022-12-06 13:04:18 +01:00
Bram Kragten
f5385ba277 Check if cast message came from logged in instance (#12354) 2022-12-06 12:47:17 +01:00
epenet
1a69503eab Allow cm in precipitation units (#14568) 2022-12-06 11:16:33 +01:00
Philip Allgaier
8ba46f7f57 Add "show_names" option to history graphs (#14546) 2022-12-06 01:41:08 +01:00
Bram Kragten
bbdb84482a 20221205.0 (#14562) 2022-12-05 22:49:02 +01:00
Bram Kragten
08ffe375b9 Bumped version to 20221205.0 2022-12-05 22:48:02 +01:00
Philip Allgaier
8699f3e3a8 Use rounded corners for calendar (#14525)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-12-05 19:59:09 +00:00
Philip Allgaier
ecdd07ff4d Add calendar event recurrence rule translations (#14544)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-12-05 18:28:48 +01:00
Philip Allgaier
f0f699a37e Auto remove empty items from shopping list (#14487) 2022-12-05 16:33:47 +01:00
Paul Bottein
75b1b1c9a0 Fix media browser gender translations (#14551) 2022-12-05 15:13:22 +00:00
Philip Allgaier
0ae8246d8a Simplify calendar "listWeek" and enable for "initial_view" (#9993)
fixes undefined
2022-12-05 16:11:12 +01:00
Philip Allgaier
b644407260 Consistent table style for calendar and scheduler (#14528) 2022-12-05 16:08:00 +01:00
Philip Allgaier
b389127f78 Prevent "ha-chip" focus outline frame (#14535) 2022-12-05 15:55:23 +01:00
Philip Allgaier
20dff9d25d Fix YAML validation for automation action service call enabling/disabling (#14536)
fixes undefined
2022-12-05 15:33:41 +01:00
Philip Allgaier
076ddb71b6 Show proper media title in media bar (split URI) (#14464) 2022-12-05 15:32:24 +01:00
Franck Nijhof
f0127511b0 Handle optional state enum from sensor entities (#14428) 2022-12-05 15:01:18 +01:00
Philip Allgaier
07ad429f8c Fix first day of the week locale issue with scheduler (#14529)
fixes undefined
2022-12-05 14:54:38 +01:00
Jan Bouwhuis
ef3caf91f1 Fix retreiving topic value when using MQTT publish (#14554)
fixes undefined
2022-12-05 14:33:50 +01:00
Bram Kragten
4fcfcbeefb Simplify 2022-12-05 14:31:44 +01:00
Philip Allgaier
f18997c7c3 Prevent identical double debug log downloads for integration (#14537)
fixes undefined
2022-12-05 14:31:19 +01:00
Bram Kragten
2ed8a4053b set backpath for supervisor addons panel (#14555) 2022-12-05 13:30:28 +00:00
Philip Allgaier
1105c92569 Add support for calendar event description (#14522) 2022-12-05 14:28:43 +01:00
Philip Allgaier
76a682fa28 Ensure calendar event texts are aligned (#14521) 2022-12-05 14:26:11 +01:00
Philip Allgaier
d059b97a2f Prevent issues in "ha-form" with undefined "disabled" state (#14518)
fixes undefined
2022-12-05 14:25:30 +01:00
Philip Allgaier
96080f3c78 Set initial calendar event date based on active calendar view (#14516) 2022-12-05 14:24:31 +01:00
Steve Repsher
00274ebf66 Fix localize key errors for helpers (#14496) 2022-12-05 14:22:17 +01:00
Philip Allgaier
7e58bd59c3 Fix rounded corners for expansion panel (#14531)
fixes undefined
2022-12-05 14:21:13 +01:00
Paul Bottein
04ef783f5b Fix adjust statistic parameter name (#14552) 2022-12-05 12:49:21 +01:00
dependabot[bot]
340449d064 Bump dessant/lock-threads from 3.0.0 to 4.0.0 (#14550)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-05 09:25:02 +01:00
dependabot[bot]
24f2ad8be9 Bump @braintree/sanitize-url from 5.0.2 to 6.0.0 (#14549)
Bumps [@braintree/sanitize-url](https://github.com/braintree/sanitize-url) from 5.0.2 to 6.0.0.
- [Release notes](https://github.com/braintree/sanitize-url/releases)
- [Changelog](https://github.com/braintree/sanitize-url/blob/main/CHANGELOG.md)
- [Commits](https://github.com/braintree/sanitize-url/compare/v5.0.2...v6.0.0)

---
updated-dependencies:
- dependency-name: "@braintree/sanitize-url"
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-05 00:22:55 -05:00
dependabot[bot]
3eac53e209 Bump async from 2.6.2 to 2.6.4 (#14548)
Bumps [async](https://github.com/caolan/async) from 2.6.2 to 2.6.4.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/v2.6.4/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/v2.6.2...v2.6.4)

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

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-04 23:54:32 -05:00
Philip Allgaier
65cef9d996 Prevent negative media player progress (#14547) 2022-12-04 21:11:53 -05:00
dependabot[bot]
4c5f4508b2 Bump decode-uri-component from 0.2.0 to 0.2.2 (#14543) 2022-12-04 17:48:40 -05:00
Allen Porter
1aa6bd5577 Fix recurrence rule generation for UNTIL rules (#14541) 2022-12-04 14:38:43 +01:00
Bram Kragten
3dfd401036 20221201.1 (#14506) 2022-12-01 17:38:27 +01:00
Bram Kragten
71a5d8c6f9 Bumped version to 20221201.1 2022-12-01 17:37:08 +01:00
Bram Kragten
a0bf582cc9 dont force update translations 2022-12-01 17:35:47 +01:00
Bram Kragten
77a53ffc6c 20221201.0 (#14505) 2022-12-01 17:13:52 +01:00
Bram Kragten
b6f1d78b7f Merge branch 'master' into dev 2022-12-01 17:11:26 +01:00
Bram Kragten
1fda303b23 Bumped version to 20221201.0 2022-12-01 17:05:23 +01:00
Bram Kragten
241645fe8d Fix timezone issues calendar (#14501) 2022-12-01 17:04:45 +01:00
Steve Repsher
faa57e4c02 Improve filtering and performance for icon picker (#14401)
Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
2022-12-01 16:59:45 +01:00
Paul Bottein
915563ce6c Improve constrast for tile card state (#14504) 2022-12-01 16:54:35 +01:00
J. Nick Koston
44502d2c8d Add the ability to enable debug logs in the config entry overflow (#14319) 2022-12-01 16:53:41 +01:00
Paul Bottein
b97a9ef311 Consider moisture as alerting binary sensor (#14503) 2022-12-01 14:48:27 +00:00
Bram Kragten
1a66b8a374 Add script to setup translation fetching (#14481)
* Add script to setup translation fetching

* Update bootstrap
2022-12-01 09:00:29 -05:00
Bram Kragten
4190ff5a2b Sort language, country, currency (#14500) 2022-12-01 13:38:50 +01:00
Paul Bottein
dfc461ce05 Add support for entity translation key (#14482) 2022-12-01 12:53:44 +01:00
Steve Repsher
dff7f653b1 Fix checking existence of downloaded translations (#14493) 2022-11-30 16:53:26 -05:00
Bram Kragten
eccc6a8cdb 20221130.0 (#14492)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Joakim Sørensen <ludeeus@ludeeus.dev>
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
Co-authored-by: puddly <32534428+puddly@users.noreply.github.com>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Bagira <bagdi.istvan@gmail.com>
Co-authored-by: Ben Randall <veleek@gmail.com>
Co-authored-by: uvjustin <46082645+uvjustin@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: Chris <31055115+darthsebulba04@users.noreply.github.com>
Co-authored-by: Aaron Carson <aaron@aaroncarson.co.uk>
Co-authored-by: David F. Mulcahey <david.mulcahey@me.com>
Co-authored-by: Yosi Levy <37745463+yosilevy@users.noreply.github.com>
Co-authored-by: Alex van den Hoogen <alex3305@gmail.com>
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
Co-authored-by: Jani Lahti <jani.lahti@iki.fi>
Co-authored-by: RoboMagus <68224306+RoboMagus@users.noreply.github.com>
Co-authored-by: Brynley McDonald <brynley+github@zephire.nz>
Co-authored-by: Denis Shulyaka <Shulyaka@gmail.com>
Co-authored-by: KablammoNick <nick@kablammo.net>
Co-authored-by: Allen Porter <allen@thebends.org>
Co-authored-by: Philip Allgaier <mail@spacegaier.de>
2022-11-30 22:43:19 +01:00
dependabot[bot]
52235c6187 Bump ejs from 3.1.6 to 3.1.8 (#14491)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-11-30 21:35:39 +00:00
Bram Kragten
594b402bd5 Bumped version to 20221130.0 2022-11-30 22:26:07 +01:00
Philip Allgaier
684f6db4df Gallery: Added switch and gauge component pages + CSS vars (#14479) 2022-11-30 22:22:02 +01:00
dependabot[bot]
883e5e3a6c Bump minimist from 1.2.5 to 1.2.7 (#14490)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-30 22:15:56 +01:00
Bram Kragten
29452841c2 Add basic matter config panel (#14489)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2022-11-30 21:12:46 +00:00
Allen Porter
9b6e33cfec Add Calendar Event creation and deletion dialogs (#14036)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-11-30 21:20:41 +01:00
Paul Bottein
e43f3b193e Rename indicator property and add show-handle property for ha bar slider (#14466) 2022-11-30 21:18:27 +01:00
Paul Bottein
40d0455936 Fix common tests (#14485) 2022-11-30 19:50:53 +01:00
Paul Bottein
90a7c2d2ff Set border radius to 10px for tile slider and buttons (#14488) 2022-11-30 19:50:26 +01:00
Paul Bottein
d4cda0c106 Rename tile extras to tile features (#14483) 2022-11-30 18:35:13 +01:00
Bram Kragten
92d022747b Add core country and language settings (#14478) 2022-11-29 20:54:18 +01:00
Steve Repsher
ee6f97b802 Fetch nightly translations during build (#13724)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-11-29 19:33:43 +01:00
Paul Bottein
cb97918005 Show percentage for light, cover and fan for tile card (#14475) 2022-11-29 15:06:36 +00:00
J. Nick Koston
f1f0baf787 Add buttons to download logs (#14404)
Co-authored-by: Joakim Sørensen <ludeeus@ludeeus.dev>
2022-11-29 15:56:28 +01:00
Paul Bottein
c0240eed67 Show icon preview when changing device class (#14472)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2022-11-29 15:27:10 +01:00
Paul Bottein
aeeacc6cad Use new colors for state icon (#14358)
* Use new colors for state icon

* feedbacks

* Remove arming case
2022-11-29 15:22:50 +01:00
Paul Bottein
fcfdad3d94 And vacuum commands extra for tile card (#14434) 2022-11-29 15:15:47 +01:00
Paul Bottein
566b93ec1f Fixes area creation in area picker (#14452) 2022-11-29 15:15:12 +01:00
KablammoNick
5c452cb9e0 Update icons for shade device class (#14455)
* Update icons for shade device class

MDI v6.7.96 added icons for roller-shade and roller-shade-closed - this changes shade device class to match, rather than blinds/blinds-open.

* Split blind/shade device classes and update blind icons
2022-11-29 11:15:51 +01:00
Paul Bottein
06c1d9f6ef Replace gas by water in translation (#14473) 2022-11-29 09:39:22 +00:00
Paul Bottein
bfd96944f9 Add switch bar (#14429)
* Add basic swich support

* Add color and reversed state

* Fix slotted icon

* Update gallery/src/pages/components/ha-bar-switch.ts

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

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-11-28 16:58:18 +01:00
Bram Kragten
c119163422 Add grouping by device to generated dashboard config (#14398) 2022-11-28 15:56:35 +00:00
Paul Bottein
4846fa1a74 Improve combobox overlay observer (#14463) 2022-11-28 16:53:35 +01:00
Paul Bottein
aec0eb3c78 Improve state colors and add documentation for entity state (#14437)
* Add documentation for entity icons and colors

* Add domains

* Add domains

* improve colors

* Add fan color

* Change fan to cyan

* color rules adjustments
2022-11-28 14:37:07 +01:00
Denis Shulyaka
92e7254c54 humidifier card: add on-off button (#13443)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-11-28 13:42:41 +01:00
Paul Bottein
bafe581562 Add light brightness extra for tile (#14446) 2022-11-28 12:51:21 +01:00
Brynley McDonald
e6a153a802 Add margin to the device automation form (#14418) 2022-11-28 12:48:08 +01:00
Bram Kragten
fce87ff0fe Add support for hardware option flows (#14364) 2022-11-28 12:47:27 +01:00
Joakim Sørensen
e6b3475b5b Allow homeassistant URL in repair issues (#14456)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-11-28 12:47:12 +01:00
RoboMagus
f969299567 Fix water comparison in EnergyDashboard (#14460)
fixes undefined
2022-11-28 12:46:42 +01:00
Paul Bottein
7a87dc4d8a Add ui-color selector (#14348) 2022-11-28 12:45:53 +01:00
Paul Bottein
d6fa1427f1 Use toggle as default icon_tap_action for scenes and buttons in tile card (#14386) 2022-11-28 12:37:27 +01:00
Bram Kragten
aa1e9cedca Fix add integration discovery (#14432)
* Fix add integration discovery

* Update show-dialog-config-flow.ts

* Update src/panels/config/integrations/dialog-add-integration.ts

Co-authored-by: Joakim Sørensen <ludeeus@ludeeus.dev>

Co-authored-by: Joakim Sørensen <ludeeus@ludeeus.dev>
2022-11-28 11:32:59 +00:00
Bram Kragten
147b1f34ac Fixes for disabled/unavailable entities (#14451) 2022-11-28 12:13:54 +01:00
dependabot[bot]
0cfba81eae Bump softprops/action-gh-release from 0.1.14 to 0.1.15 (#14461)
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 0.1.14 to 0.1.15.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v0.1.14...v0.1.15)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-28 11:38:11 +01:00
Franck Nijhof
a9d44fcb61 Add Text entity (#14447) 2022-11-24 21:23:50 +01:00
Bram Kragten
0aa2c9044a Fix picking energy sensors for gas (#14448) 2022-11-24 14:12:20 +00:00
Jani Lahti
9bae4a646d Fixed spelling of _(un)subscribeBootstrapIntegrations() (#14439)
Fixed spelling of (un)subscribeBootstrapIntegrations()
2022-11-24 10:28:24 +00:00
Bram Kragten
15a0847db8 Fix energy usage graph (#14438) 2022-11-24 10:59:55 +01:00
Bram Kragten
8b817b35b0 Improvements to stat charts (#14427) 2022-11-24 10:54:01 +01:00
Joakim Sørensen
f95a3c75f6 Use issue scoped translation for repair abort reason (#14445) 2022-11-24 10:30:57 +01:00
epenet
2223ffd7ee Add precipitation device class (#14232) 2022-11-21 21:25:09 +01:00
Alex van den Hoogen
590ad5b8a0 Only show hover on clickable rows in data table (#14326)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-11-21 21:24:28 +01:00
Yosi Levy
2bb9961fc2 Update popup align markdown LTR (#14372) 2022-11-21 21:22:55 +01:00
David F. Mulcahey
3e2fb09251 Clean up the ZHA pairing UI (#14287) 2022-11-21 21:20:58 +01:00
Bram Kragten
fc80daa3e0 Bump typescript to 4.9.3 (#14430) 2022-11-21 20:27:47 +01:00
Paulus Schoutsen
2aa7b95a5a Device info: Show connected devices (#14421) 2022-11-21 12:39:22 -05:00
Aaron Carson
c2436fb157 Update incorrect copy (#14415) 2022-11-21 16:21:20 +00:00
Paul Bottein
a958c6296b Add cover and light controls to tile card (#14244) 2022-11-21 17:13:15 +01:00
dependabot[bot]
fe4191aea9 Bump loader-utils from 1.4.0 to 1.4.2 (#14425)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-21 16:42:48 +01:00
Paul Bottein
49d9cf41fe fix closed cover state (#14424) 2022-11-21 16:34:17 +01:00
Erik Montnemery
0bfb2b4a56 Don't fetch unneeded statistics from core (#14423) 2022-11-21 16:24:57 +01:00
dependabot[bot]
1a68a2f4d7 Bump terser from 4.8.0 to 4.8.1 (#14426)
Bumps [terser](https://github.com/terser/terser) from 4.8.0 to 4.8.1.
- [Release notes](https://github.com/terser/terser/releases)
- [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/terser/terser/compare/v4.8.0...v4.8.1)

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

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-21 14:40:07 +01:00
Steve Repsher
1197e5a35b Bump @vaadin to 23.2.9 (#14408) 2022-11-21 11:34:37 +01:00
Paul Bottein
c6386284d1 Fix entity active states (#14341)
* fix media player state

* Fix active states

* Consider idle media player as active

* improve custom cases
2022-11-17 15:49:33 +01:00
Bram Kragten
185d2f1d52 Add change option to statistics chart (#14396) 2022-11-16 17:09:54 +00:00
Bram Kragten
c5ec1797f6 Dont use lovelace in new dashboard urls (#14395) 2022-11-16 17:53:46 +01:00
Paul Bottein
048b345c75 Use relative time display for timestamp sensor, buttons and scene in tile card (#14385)
Use relative time display for timestamp sensor, buttons and scene
2022-11-16 17:47:25 +01:00
J. Nick Koston
70868da305 Fix selecting YAML only integrations in submenus (#14377) 2022-11-16 17:15:49 +01:00
Chris
cef3dbfdf0 Capatalize Earth (#14382)
* Capatalize Earth

* Modify correct en file.

Captalize Earth.

* Undo change to wrong file

* Remove final line feed

* Try again to remove lf...

* Actually remove lf this time

Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>
2022-11-15 20:37:43 +00:00
Paul Bottein
bda5b97c91 Select suggested area for device during config flow (#14383) 2022-11-15 15:09:27 +01:00
J. Nick Koston
ae15dd678b Fix logbook reporting unknown states as unavailable (#14359)
Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
2022-11-15 08:07:50 -06:00
J. Nick Koston
681c745e84 Add locking, unlocking, and jammed states to logbook (#14360) 2022-11-15 08:07:28 -06:00
uvjustin
23b59978ab Bump hls.js to v1.2.5 (#14342) 2022-11-14 19:36:35 -05:00
Ben Randall
90b9eaeb19 fix: don't render extra fields when there are none (#14374) 2022-11-14 16:30:51 +00:00
Bagira
65426bd2d0 Fix color_rgb and color_temp selector import (#14369) 2022-11-12 02:09:49 +00:00
Erik Montnemery
1cb44ce857 Convert units in statistics graph card (#13970)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-11-11 13:21:53 +00:00
Paul Bottein
1c03dc9b77 Use entity based color for state history (#14330) 2022-11-10 09:51:13 +01:00
Paul Bottein
238e844068 Use light color for tile card (#14321) 2022-11-10 09:49:25 +01:00
puddly
ec6a4b4e7a Add hardware as a config flow discovery source (#14281)
Add `hardware` as a discovery source
2022-11-10 09:22:01 +01:00
Paul Bottein
ac65882fdd Fix config entry selector import (#14334) 2022-11-08 21:10:19 -05:00
Bram Kragten
c92e6423e8 20221108.0 (#14332) 2022-11-08 14:19:23 +01:00
Bram Kragten
db0d24c807 Merge branch 'master' into dev 2022-11-08 14:18:46 +01:00
Bram Kragten
9e56ddcc69 Bumped version to 20221108.0 2022-11-08 14:16:42 +01:00
Alex van den Hoogen
dd4c3c28ee Fix expansion of all tabs in more info dialogs (#14283) 2022-11-07 20:30:06 +01:00
puddly
245202c125 Search for boards explicitly in the return value of hardware/info (#14320) 2022-11-07 20:28:01 +01:00
puddly
8b8a85b4b8 Make borders for discovery card header seamless (#14322) 2022-11-07 20:24:09 +01:00
Bram Kragten
0aae285236 Rename disabled attribute on integration card (#14268) 2022-11-07 14:45:02 +01:00
Sven Serlier
31ac274a51 Lovelace to dashboard (#14267) 2022-11-07 14:44:34 +01:00
Bram Kragten
6f07e7ca59 Hide legend for stats chart in more info, only shade area for min and… (#14273) 2022-11-05 18:33:43 +01:00
Bram Kragten
fa506202ac Bumped version to 20221102.1 2022-11-02 19:19:35 +01:00
Bram Kragten
c810c67a53 Bumped version to 20221102.1 2022-11-02 19:18:25 +01:00
Bram Kragten
663c58512d 20221102.1 (#14264) 2022-11-02 19:15:35 +01:00
Bram Kragten
3cd64675df Fix water costs (#14263) 2022-11-02 17:59:00 +00:00
Bram Kragten
79c8b7dc27 Fix statistic card default config (#14262) 2022-11-02 17:26:09 +00:00
Steve Repsher
98a32041d4 Add name attribute to autocomplete fields (#14258) 2022-11-02 18:22:02 +01:00
Paul Bottein
ffbcb0a343 Fix iOS safe padding (#14261) 2022-11-02 18:19:53 +01:00
Bram Kragten
ab4dd47e51 20221102.0 (#14259) 2022-11-02 11:06:39 +01:00
Bram Kragten
c7cb8cf762 Merge branch 'master' into dev 2022-11-02 10:35:59 +01:00
Bram Kragten
a5ab4eaf0e Bumped version to 20221102.0 2022-11-02 10:33:32 +01:00
NobleKangaroo
d52dbde909 Fix dialog resizing (#14256) 2022-11-02 10:16:05 +01:00
Yosi Levy
1cde9e882e Audio message trash fix (#14250) 2022-11-02 10:14:50 +01:00
Bram Kragten
8cb0d38d78 Fix back button on subview (#14251) 2022-11-02 10:11:50 +01:00
Paulus Schoutsen
9cb168c439 Set default unit for US unit system to gl instead of ft3 (#14257)
Mention gl instead of ft3
2022-11-02 10:10:23 +01:00
Bram Kragten
2add29c4eb 20221031.0 (#14248) 2022-10-31 18:51:59 +01:00
Bram Kragten
e2104c1591 Bumped version to 20221031.0 2022-10-31 17:25:39 +01:00
Bram Kragten
17ac81a708 Fix video size more info (#14246)
* Fix video size more info

* add comment
2022-10-31 17:24:20 +01:00
David F. Mulcahey
42386c7dee Fix ZHA neighbor table in the manage device dialog (#14236)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-10-31 15:20:49 +00:00
Bram Kragten
2e988bf5c3 Default size of hui-image to 16:9 during loading (#14245) 2022-10-31 16:06:33 +01:00
Paul Bottein
3356d559c9 Activate all entities config filters when clicking clear filter (#14225) 2022-10-31 15:44:08 +01:00
Paul Bottein
43755deb39 Consider standby media player as inactive for tile card (#14226) 2022-10-31 15:43:16 +01:00
Paul Bottein
9778c0731c Add badges for tile card (#14231) 2022-10-31 15:42:44 +01:00
Paul Bottein
ebc0edac10 fix margin with ha form grid (#14240) 2022-10-31 15:40:58 +01:00
Paul Bottein
effc9467c2 Entity picture option was not in the right section (#14243) 2022-10-31 15:40:26 +01:00
Paul Bottein
68e94d7222 Add type expandable for ha-form (#14197)
* Add type group for ha-form

* rename to expandable

* Add aria level

* apply suggestions
2022-10-28 17:49:59 +02:00
Jaroslav Hanslík
c4992c477b Fixed typo in water consumption text (#14229) 2022-10-28 11:34:54 -04:00
Bram Kragten
449c1f2469 Change water units to L/gal (#14223) 2022-10-27 17:10:35 -04:00
Bram Kragten
d52e521ef8 20221027.0 (#14222) 2022-10-27 22:03:05 +02:00
Bram Kragten
03d03f9903 5 minute more info stats (#14221) 2022-10-27 22:02:28 +02:00
Bram Kragten
1122698351 Bumped version to 20221027.0 2022-10-27 22:01:13 +02:00
Bram Kragten
9d730919d5 Add statistic card (#14198)
* Add statistic card

* Update selector.ts

* Update translations

* review
2022-10-27 21:59:55 +02:00
Paul Bottein
6326bb010f Only show existing weekdays (#14219) 2022-10-27 20:55:40 +02:00
Paul Bottein
2ab5da6d84 Allow null selector (#14212) 2022-10-27 13:17:42 -04:00
Steve Repsher
a56b2e3270 Rename autofill to autocomplete for text selector (#14202) 2022-10-27 15:30:08 +02:00
Paul Bottein
523d936010 Fix min height on lovelace panel for ios (#14207) 2022-10-27 15:29:47 +02:00
Bram Kragten
b3e2beac5a don't use entity name as label in more info stats (#14213) 2022-10-27 15:29:22 +02:00
Paul Bottein
4c8e863c0e Use firstday of the week for range shortcuts in date pickers (#14210) 2022-10-27 14:24:24 +02:00
Paulus Schoutsen
69074df1ab 20221026.0 (#14203) 2022-10-26 14:52:03 -04:00
Paulus Schoutsen
16848d03ae Bumped version to 20221026.0 2022-10-26 14:48:30 -04:00
Bram Kragten
dd9683674d Add my link to add zwave and zigbee devices (#14126) 2022-10-26 14:47:43 -04:00
Bram Kragten
822917d060 Add water to energy dashboard (#14194) 2022-10-26 14:44:07 -04:00
Bram Kragten
7cc6809f53 Use statistics for sensors in more info history (#14199)
* Use statistics for sensors in more info history

* use state instead of sum

* Update ha-more-info-history.ts

* change to hour
2022-10-26 19:29:12 +02:00
Paul Bottein
57291183ca update border radius to 12px (#14201) 2022-10-26 16:54:05 +00:00
Paul Bottein
504e8dd946 Add option to show entity picture in tile card (#14196)
Add option to show entity picture
2022-10-26 18:31:10 +02:00
Bram Kragten
5c4517517d Fix enlarging more info dialog (#14200) 2022-10-26 16:25:13 +00:00
Steve Repsher
1b917a5b04 Add autocomplete to login and MFA setup (#14065) 2022-10-26 16:10:19 +02:00
Bram Kragten
527c4f71c2 Add icons to device config dashboard (#14184)
* Add icons to device config dashboard

* Add `alt=""`
2022-10-26 15:19:56 +02:00
Paul Bottein
3ac6e6f307 Group fields in tile editor (#14175)
* group form into multiple groups

* display appearence form as grid

* Add translations
2022-10-26 13:51:58 +02:00
Rob Jackson
9e955dbaaa Remove conditional element from DOM when hidden (#13955) 2022-10-26 13:27:56 +02:00
epenet
e0a56956e0 Add wind_speed sensor device class (#14030) 2022-10-26 13:27:39 +02:00
Josh McCarty
66ed1b18be Format numeric entities with integer value and step as integer instead of float (#14112) 2022-10-26 13:27:14 +02:00
Paul Bottein
d445bf2505 Move re-order button at triggers/conditions/actions level. (#14185) 2022-10-26 13:21:36 +02:00
David F. Mulcahey
16bd1f5883 Update ZHA manage device dialog to use a form for cluster command arguments (#14052) 2022-10-26 13:19:48 +02:00
Michael
c12e6662dd Add week period to statistics card (#14162) 2022-10-25 22:36:20 +02:00
Bram Kragten
0b18875d70 remove hardware from integration descriptions (#14189) 2022-10-25 19:21:00 +00:00
Erik Montnemery
57fb8f9f01 Adapt to energy sensors supporting GJ (#14181) 2022-10-25 16:48:32 +02:00
Bram Kragten
f1139e09f9 Fix back handling of add integration dialog (#14187) 2022-10-25 15:15:18 +02:00
Joakim Sørensen
51febc2218 Use warning in ha-alert for breaks_in_ha_version (#14186) 2022-10-25 12:25:16 +00:00
Paul Bottein
c8d16af1b5 Add state color to tile card (#14128)
* remove unused imports

* fix white color

* Introduce state color

* add color to css

* add battery colors

* Improve sensor color

* add binary sensor color

* add person color

* improve on/off state color

* add climate color

* only apply color when entity is activet push -f
2022-10-25 14:02:09 +02:00
NobleKangaroo
66a75c4714 Fix camera dialog (#14179) 2022-10-25 10:46:57 +00:00
Paul Bottein
cb8e602340 Refactor ha-form margins (#14176) 2022-10-25 12:29:59 +02:00
epenet
de008f65a3 Allow gas units to be overriden (#14173) 2022-10-25 12:29:28 +02:00
Steve Repsher
ab1b778439 Pass helper to ha-form subtypes (#14165) 2022-10-25 12:29:05 +02:00
Franck Nijhof
62ac9155fc Add icons to automations dashboard (#14182)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-10-25 12:26:41 +02:00
Paul Bottein
68302d0896 Fix more info dialog edit button for script (#14180) 2022-10-25 12:24:08 +02:00
Franck Nijhof
a76f456ebc Remove default sequence from new scripts (#14183) 2022-10-25 12:03:56 +02:00
epenet
9d3eaba46b All new water device class (#14174) 2022-10-24 21:06:51 +02:00
Michel van de Wetering
5bb9538861 Add icon for receiver deviceclass (#14158) 2022-10-24 14:37:46 +02:00
dependabot[bot]
fe1beb0d59 Bump home-assistant/wheels from 2022.06.7 to 2022.10.1 (#14171)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-24 14:30:02 +02:00
Piero
153161d2cb Disable sidebar edit mode on drawer close (#14169) 2022-10-24 11:06:58 +02:00
Bram Kragten
370864e0ed fix back button in hassio addons (#14161) 2022-10-24 11:03:32 +02:00
Tomasz
9b6fca2c0e Fix back button in ha-card (add border-radius) (#14172) 2022-10-24 11:03:09 +02:00
Paul Bottein
55467666f7 Add slider bar (#14094)
* Add slider bar

* a11y feedbacks

* allow undefined values

* rename variable

* Add end style

* Add vertical slider

* Allow theming

* Improve theming

* Improve colors

* fix properties

* stepped value for aria value

* use vertical instead of orientation

* Improve a11y

* force role slider
2022-10-24 09:25:26 +02:00
Steve Repsher
928f20ada5 Revert "Fix typo when deleting an integration. Fixes #14135" (#14149)
Revert "Fix typo when deleting an integration. Fixes #14135 (#14137)"

This reverts commit 1f9763d6c8.
2022-10-22 15:30:31 +02:00
Bram Kragten
b53e86ad03 Bumped version to 20221021.0 2022-10-21 21:16:10 +02:00
Bram Kragten
112ec10b30 Add support for virtual integrations (#14138) 2022-10-20 23:08:55 -04:00
Kris Noble
1b4989a7dc Fix typo when deleting an integration (#14145)
Fixes #14135, resubmitted modifying the correct file
2022-10-20 21:27:00 +00:00
Kris Noble
1f9763d6c8 Fix typo when deleting an integration. Fixes #14135 (#14137) 2022-10-20 17:55:21 +00:00
Yosi Levy
b495667e8d Various dev tools RTL fixes (#14118) 2022-10-20 11:22:56 +02:00
Brandon Rothweiler
a46e72ffbd Fix duplicate trigger IDs showing in the Triggered By condition (#14122) 2022-10-20 11:20:46 +02:00
Bram Kragten
0a2eb05062 Only change dialog for camera in info tab (#14130) 2022-10-20 11:19:35 +02:00
Bram Kragten
c9b5fe9a85 Bumped version to 20221020.0 2022-10-20 10:15:36 +02:00
Igor Santos
58d5a07a43 Allow negative values in gauge severity config GUI (#14123) 2022-10-19 20:20:18 +00:00
Josh McCarty
c44de09a7c Add any step for input number settings to match server-side validation (#14121) 2022-10-19 22:07:01 +02:00
epenet
a0b645d1b9 Add precipitation_intensity sensor device class (#14027) 2022-10-19 22:02:01 +02:00
epenet
0b6c6b2b98 Rename imperial unit system to us_customary (#14092) 2022-10-19 22:00:11 +02:00
krazos
bad3edc340 Fix translation of Duplicate label in automation and script editors (#14131) 2022-10-19 21:59:49 +02:00
epenet
d3015c362d Add support for mm/h on generic speed (#14031) 2022-10-19 15:02:39 +02:00
Franck Nijhof
fbb8ff4362 Integrations v2.1: compatibility with hubs, devices and services (#14114) 2022-10-19 12:41:57 +02:00
Bram Kragten
6393d59035 make open in new icon a bit smaller (#14125) 2022-10-19 10:49:56 +02:00
Bram Kragten
62de708b2b Align border radius (#14124) 2022-10-19 10:49:47 +02:00
Alex van den Hoogen
6c4c65730c Set more-info dialog max-width to fit all languages (#14110) 2022-10-17 16:15:01 +00:00
Travis Collins
23f8373b16 fix history graph configuration timeline update (#14101) 2022-10-17 18:02:11 +02:00
Paul Bottein
dec8883f2a Introduce tile card (#14085) 2022-10-17 11:43:49 +02:00
Josh McCarty
a475b06d49 Format entity & sensor card with manual units; fix param comment typo (#14090) 2022-10-17 11:15:37 +02:00
Travis Collins
0972cb4583 Fix pickers not getting focus (#14068)
* fix focus pickers

* await nextRender instead of setTimeout

* use bram's code

* Update src/components/ha-target-picker.ts

Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>

Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>
2022-10-17 11:01:17 +02:00
Yosi Levy
dad7c43fd2 Fix min width so entire date/time will be presented (#14105) 2022-10-17 10:53:06 +02:00
Paul Bottein
7e6a9f1653 Remove box shadow for ha-card (#14063)
* Remove box shadow for ha-card

* add raised style in case of raised card needed

* add box-sizing: border-box

* Allow box-shadow theming

* Restore box-shadow theme in date range picker

* Restore hui unused entities card box shadow none

* Apply suggestions from code review

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

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-10-17 10:20:11 +02:00
Brandon Rothweiler
f627e98902 Improve pluralization in automation descriptions (#14080)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-10-17 09:50:11 +02:00
Travis Collins
0d623794ed Mark attribute as optional (#14067)
* Mark attribute as optional

* move optional to a separate translation

* indicate required fields, not optional fields
2022-10-17 09:45:28 +02:00
Paul Bottein
0a3fa3e218 Ha selector UI action (#14082)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-10-13 12:43:24 +00:00
Paul Bottein
19887fbd54 Remove undefined key in lovelace card config (#14081) 2022-10-13 14:31:55 +02:00
Bram Kragten
fe9967550b Load selector elements dynamic (#14084)
Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
2022-10-13 14:28:49 +02:00
Matthias de Baat
9b19b6f203 Remove confusing header image (#14070)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-10-13 09:30:37 +00:00
Yosi Levy
797718f478 Fix automation trace RTL (#14079) 2022-10-13 11:26:19 +02:00
Paul Bottein
9ea0e3a75f Fix keyboard keys for tap action (#14071) 2022-10-13 11:17:04 +02:00
Josh McCarty
0b76b60f6e Format input_number field consistently (#14076) 2022-10-13 11:14:43 +02:00
karliemeads
d8be662bd6 Fix timezone problem for "Today" in the Date Picker. (#14043) 2022-10-13 11:04:28 +02:00
jrobles98
c478a15846 Fix Map Card styling boundaries (#14050) 2022-10-13 11:04:04 +02:00
Paul Bottein
811208363b Bigger pin for ha-slider to support 4 digits numbers (#14072) 2022-10-12 22:45:08 +02:00
Steve Repsher
969772663b Fix localize key errors in options flow, repairs flow, and integrations (#14060) 2022-10-11 15:47:41 +02:00
Patrick ZAJDA
c3b9438b3b Also handle enter key on ignore menu for discovered integrations (#14061) 2022-10-11 15:46:11 +02:00
pataar
9b51df02d6 Update yarn to version 3.2.3 (#13992) 2022-10-11 15:45:34 +02:00
Pierre
8a4b0b081a fix(mobile): add safe-area-inset on app layout and specific views (#14032) 2022-10-11 15:45:15 +02:00
Bram Kragten
1ecc88291d Handle multiple times in time trigger (#14006) 2022-10-11 15:41:21 +02:00
Erik Montnemery
fb80da013e Use color temperatures in Kelvin in more_info_light (#14016) 2022-10-10 20:12:36 +02:00
Steve Repsher
a4fcb743fa Add autocomplete to onboarding, cloud, and password change (#14040) 2022-10-10 19:54:16 +02:00
Steve Repsher
8444fe0a07 Include backend translations in Lokalise download (#13981) 2022-10-10 17:12:25 +02:00
Steve Repsher
1442f6d546 Fix localize key error in developer tools & remove exception (#14045) 2022-10-10 17:05:34 +02:00
Sven Serlier
c468fba36f Fix demo leak sensor (#14046) 2022-10-10 17:04:49 +02:00
karliemeads
2afbfb01bd Fix zero for a slider in a blueprint (#14053)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-10-10 15:00:10 +00:00
Paul Bottein
907466d060 Add first weekday option in profile (#13991) 2022-10-10 16:58:27 +02:00
jrobles98
4deee46864 Refactor css variable because of a typo in dialogs, no change in any behaviour (#14056) 2022-10-10 14:53:52 +00:00
Brandon Rothweiler
391cc95883 Automation description small fixes (#14055) 2022-10-10 16:43:32 +02:00
Michael Varrieur
0c800344d2 Add custom selectUnit, use in relativeTime function (#14008) 2022-10-10 14:26:02 +00:00
Joakim Sørensen
08279f35cf Ignore progress if no progress (#14024) 2022-10-10 16:21:46 +02:00
Paul Bottein
05f2ef8a37 Some fixes for low carbon display (#14020) 2022-10-10 16:21:02 +02:00
Travis Collins
3a41b4e65b Fix calendar card list view (#14013) 2022-10-10 14:16:49 +00:00
karliemeads
e08c12c4dd Validate hours after tabbing out of field during time input (#13949) 2022-10-10 15:56:43 +02:00
dependabot[bot]
bb0884c4bb Bump actions/stale from 6.0.0 to 6.0.1 (#14058)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-10 13:27:57 +02:00
Bram Kragten
45646eaf0b 20221010.0 (#14059) 2022-10-10 09:23:02 +02:00
Bram Kragten
d735b2b722 Update pyproject.toml 2022-10-10 09:22:06 +02:00
Paulus Schoutsen
310b110b8b Fix Google Cloud enable/disable toggle (#14035) 2022-10-07 14:20:39 +00:00
Bram Kragten
06557709ae 20221006.0 (#14023) 2022-10-06 17:36:53 +02:00
Bram Kragten
1b5571557c Bumped version to 20221006.0 2022-10-06 16:51:53 +02:00
Erik Montnemery
712ecbd13c Adjust statistics issues (#14022)
* Adjust statistics issues

* Fix lint error

* Quote units

* prettier

* screw lit/quoted-expressions

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-10-06 16:51:00 +02:00
Bram Kragten
ea286b6fac Update translations 2022-10-06 16:31:50 +02:00
karliemeads
a2953138f4 Fix onboarding create new user password checks (#14010) 2022-10-06 16:07:16 +02:00
Bram Kragten
b327d6e0bc 20221005.0 (#14007) 2022-10-05 16:42:29 +02:00
Bram Kragten
88983806ae Bumped version to 20221005.0 2022-10-05 16:38:36 +02:00
Bram Kragten
1ac701d1c8 change yaml integration dialog (#14003)
* change yaml integration dialog

* Update dialog-yaml-integration.ts

* Update src/panels/config/integrations/dialog-yaml-integration.ts

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

Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
2022-10-05 16:26:06 +02:00
karliemeads
aaeca323d4 Highlight focus on show/hide password toggle (#13997) 2022-10-05 15:01:43 +02:00
Erik Montnemery
83a4fd6c1b Improve explanation of configuration validation (#14000) 2022-10-05 12:12:28 +02:00
Bram Kragten
ef9643ddaf Fix energy demo (#14002) 2022-10-05 11:03:49 +02:00
Bram Kragten
af93ec1b92 Fix zwave config flow (#14001) 2022-10-05 10:45:39 +02:00
Bram Kragten
4dce9404a4 20221004.0 (#13987) 2022-10-04 17:09:56 +02:00
Raman Gupta
ed54c70e75 Update zwave_js firmware update event interfaces (#13982) 2022-10-04 16:43:05 +02:00
Bram Kragten
114507b5cb Bumped version to 20221004.0 2022-10-04 16:42:19 +02:00
Bram Kragten
8eddaa1914 Filter out homekit and matter iot standards (#13985)
* Filter out homekit and matter iot standards

* add divider between discovered

* Update dialog-add-integration.ts

* Update ha-domain-integrations.ts

* Update en.json

* Change headers

* update styling

* translation
2022-10-04 16:25:30 +02:00
krazos
37394f7bc5 Update script picker to use relative time for last_triggered (#13973) 2022-10-04 11:40:12 +02:00
krazos
d5cdd53fab Update scene dashboard to use relative time for last_activated (#13974) 2022-10-04 11:39:55 +02:00
krazos
0ac2393ecb Update automation picker to use differenceInDays from date-fns (#13980) 2022-10-04 10:45:15 +02:00
Arun S. Sekher
c38892a162 Add Malayalam language. (#13854)
* Add Malayalam language.

Update translationMetadata.json to add the language Malayalam.

* Apply suggestions from code review

Remove two extra spaces on line 121.

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

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-10-04 08:33:08 +02:00
Allen Porter
c77e5dee84 Allow remote WebRTC playback using STUN server from RTSPtoWeb integration (#13942)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-10-03 21:10:57 -04:00
Bram Kragten
3752336a9a 20221003.0 (#13979) 2022-10-03 20:02:17 +02:00
Bram Kragten
70d4fe1285 main col device data table none narrow (#13977) 2022-10-03 20:02:00 +02:00
Bram Kragten
d3738adf11 Bumped version to 20221003.0 2022-10-03 19:41:15 +02:00
Bram Kragten
7ededd2766 Disable trigger id for read only automation (#13976) 2022-10-03 17:40:22 +00:00
Franck Nijhof
ed8b07b7e2 Render automation description as Markdown (#13975) 2022-10-03 19:29:55 +02:00
Erik Montnemery
c12189b27f Add isExternalStatistic helper (#13969) 2022-10-03 19:11:03 +02:00
Allen Porter
9c923e45c5 Improve video user experience by loading camera thumbnail as initial video background image (#13943) 2022-10-03 18:38:25 +02:00
Paul Bottein
66bfdb6d12 Fix empty value combobox (#13971) 2022-10-03 17:42:30 +02:00
Erik Montnemery
aa673774a8 Correct filtering of statistics when adding gas energy source (#13968) 2022-10-03 13:38:22 +02:00
mbo18
8c7974e466 Add icon to device class duration (#13961)
* Add icon to device class duration

* Change to mdiProgressClock
2022-10-03 13:37:37 +02:00
Bram Kragten
a70e2342a2 Add main column to data table (#13966) 2022-10-03 13:37:00 +02:00
Paul Bottein
b5c9aae1aa Update delete area dialog (#13967) 2022-10-03 10:39:54 +00:00
Bram Kragten
93893d0237 Don't include all homekit discovery items for integrations that suppo… (#13960) 2022-10-03 11:43:17 +02:00
Bram Kragten
ad3dcb355f Use formatDateNumeric in repair dialog (#13964) 2022-10-03 11:43:06 +02:00
Kyle Niewiada
952b433b2c Support typing negative values for ha-form-float (#13940) 2022-10-03 11:02:00 +02:00
Yosi Levy
200fff506c Fix alignment of float label (#13958) 2022-10-03 10:22:01 +02:00
Bram Kragten
e84b9b7c6f 20221002.0 (#13953) 2022-10-02 20:43:53 +02:00
Bram Kragten
e2a89b1157 Bumped version to 20221002.0 2022-10-02 20:19:51 +02:00
Bram Kragten
cb0310593c Change add application credential flow (#13951)
* Change add application credential flow

* Update step-flow-abort.ts

* import

* Add missing credential docs link

* Load description, show only that if available

* Update dialog-add-application-credential.ts

* pass along manifest

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2022-10-02 20:19:32 +02:00
Bram Kragten
c14d9ab957 Link discovered homekit devices to domain (#13950) 2022-10-02 13:10:41 -04:00
Bram Kragten
dd695545d3 Make duplicate script/automation work in picker for yaml (#13952)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2022-10-02 13:10:15 -04:00
Franck Nijhof
176d8567f4 Add condition description for trigger condition (#13941) 2022-10-02 17:39:15 +02:00
Bram Kragten
4f4a95c04e Normalize automation config (#13938)
* Normalize automation config

* gen

* Update ha-automation-action-choose.ts
2022-10-01 18:02:24 -04:00
Erik Montnemery
6393944a1b Adapt to removal of statistics state_unit_of_measurement (#13935)
* Adapt to removal of statistics state_unit_of_measurement

* Tweak
2022-10-01 18:55:05 +02:00
Paul Bottein
f768c5ef7f Remove back path from UI (#13936)
Remove back path from UI as it can be edited with yaml editor
2022-09-30 22:23:55 +02:00
Bram Kragten
650d579d05 Link google assistant, alexa and cloud to cloud config (#13933) 2022-09-30 14:52:20 -04:00
Bram Kragten
9811f2681c Add add device fab to devices page (#13931) 2022-09-30 17:37:09 +02:00
Paul Bottein
6a3ac9116e Add yaml mode to view editor (#13926) 2022-09-30 17:29:29 +02:00
amitfin
2a6ef9b955 Read correctly the minutes of a schedule (#13929) 2022-09-30 17:21:54 +02:00
Bram Kragten
b9395e1c97 Add support for brand images (#13930) 2022-09-30 14:50:01 +02:00
Paul Bottein
cd8c1f42ca Remove inert property on combobox overlay when items change (#13928) 2022-09-30 14:41:09 +02:00
Joakim Sørensen
0ec887ad50 Remove test devices from move datadisk dialog (#13927) 2022-09-30 11:27:59 +02:00
Erik Montnemery
f8a7737eb9 Align with backend statistics WS API changes (#13913)
Align with backend statists WS API changes
2022-09-30 08:38:56 +02:00
Bram Kragten
3e01597a38 20220929.0 (#13920) 2022-09-29 18:23:01 +02:00
Bram Kragten
6d230ebd65 Bumped version to 20220929.0 2022-09-29 18:17:14 +02:00
Bram Kragten
9035e8e9dc Add back loading manifests of loaded integrations (#13919) 2022-09-29 18:14:34 +02:00
Bram Kragten
7ff138534f Show non-editable scripts in UI (#13917) 2022-09-29 12:11:48 -04:00
Bram Kragten
0b76183acd Show non-editable automations in UI (#13900) 2022-09-29 12:11:29 -04:00
Paul Bottein
9f658c10c3 Hide restored scripts from scripts list (#13916) 2022-09-29 15:48:26 +02:00
Bram Kragten
72ed6fdd6b fix brand discovery 2022-09-29 14:51:56 +02:00
Bram Kragten
3bdc5ad420 optimize 2022-09-29 14:41:25 +02:00
Bram Kragten
8d2f7d99af Fixes for add integration (#13914) 2022-09-29 14:32:24 +02:00
Bram Kragten
b88317f1d3 change values when unsupported_unit_metadata_can_convert (#13903) 2022-09-28 22:52:40 -04:00
Bram Kragten
8ccd0426dd Add my support for brands (#13909) 2022-09-28 20:34:11 -04:00
Bram Kragten
c17e8ba65a hide none config flow integrations from brand (#13907)
* hide none config flow integrations from brand

* filter

* Add support for not config flow domain integrations
2022-09-28 22:42:23 +02:00
Bram Kragten
d9f1540115 add support for stats units_changed_can_convert issues (#13902) 2022-09-28 12:46:07 -04:00
Bram Kragten
1b480248d1 Update translations 2022-09-28 18:31:40 +02:00
Bram Kragten
e88bb1114b 20220928.0 (#13904) 2022-09-28 18:14:25 +02:00
Bram Kragten
80e868e281 Merge branch 'master' into dev 2022-09-28 17:51:19 +02:00
Bram Kragten
d8a49c6eec Bumped version to 20220928.0 2022-09-28 17:43:09 +02:00
uvjustin
594ee85bbe Add stream orientation to camera entity registry settings (#13512) 2022-09-28 17:41:32 +02:00
Mark Parker
182b8f809c Prevent service call error if preset_mode is null (#13825) 2022-09-28 17:40:08 +02:00
Bram Kragten
8e4bebb694 Integrations v2 (#13887)
* WIP: Integrations v2

* update

* manifests

* update wording

* show yaml only

* Show spinner

* Update

* Use virtulizer

* Update

* change interval if 5 min stats

* remove yaml

* fix application credentials

* Add zwave and zigbee device support

* make back button bigger

* margin
2022-09-28 17:39:40 +02:00
Paul Bottein
dddb922593 Add Learn how it works link to cloud account (#13693) 2022-09-28 13:05:50 +00:00
Bram Kragten
da38cbccf1 change interval if 5 min stats 2022-09-28 15:03:01 +02:00
Erik Montnemery
71c43058ea Support displaying relative change in statistics graph cards (#13837)
* Support displaying relative change in statistics graph cards

* Address review comments

* Add option to display state

* Drop absolute sum option

* Drop period if invalid

* prevent fetching stats twice

* Change stat_types to supported ones for statistics

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-09-28 12:51:41 +00:00
Erik Montnemery
f9d119d33d Add icons for new sensor device classes (#13895) 2022-09-28 14:00:47 +02:00
Erik Montnemery
d3b97ae91c Add support for overriding sensor weight unit (#13897) 2022-09-28 12:15:23 +02:00
Paul Bottein
5146fa1d9e Update join beta dialog (#13847) 2022-09-28 09:27:34 +00:00
Paul Bottein
fc86a66c33 Use unique id for script (#13817)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-09-28 09:27:09 +00:00
Ignacio Hernandez-Ros
3959a7475c Bug Fix, can't create schedule on Sunday (#13876) 2022-09-28 09:08:30 +00:00
Paul Bottein
61d09072a7 Update Uninstall add-on dialog (#13898) 2022-09-28 11:02:09 +02:00
Paul Bottein
4a07d3d39b Update Restart add-on dialog (#13896) 2022-09-28 11:01:12 +02:00
Paul Bottein
be30cdb51f Update change password dialog (#13888)
* Update change password dialog

* Improve wording

* Update modal for people page

* Remove useless async
2022-09-28 11:00:36 +02:00
Meow
894258d7b8 fixed duplicate unit_of_measurement (#13884) 2022-09-28 10:53:25 +02:00
Erik Montnemery
296d5f8ffe Add support for overriding sensor distance unit (#13831) 2022-09-28 09:11:34 +02:00
Erik Montnemery
d1c2020ee4 Add support for overriding sensor speed unit (#13832) 2022-09-28 08:49:42 +02:00
Erik Montnemery
3c1b2aa4f3 Add support for overriding sensor volume unit (#13833) 2022-09-28 08:22:16 +02:00
Bram Kragten
17a11809de Prevent re-creation of custom panel when content was not changed (#13747) 2022-09-27 13:39:05 -04:00
David F. Mulcahey
3083d5b04c Clean up ZHA configuration UI (#13610) 2022-09-27 16:02:45 +02:00
Paul Bottein
0848c096b9 Fix script config form (#13878) 2022-09-27 15:40:38 +02:00
Paul Bottein
8d5c36a96a Fix more info with unnamed entity (#13859) 2022-09-27 15:39:49 +02:00
Paul Bottein
cc76a6c5ed Add unique_id to entity registry (#13886) 2022-09-27 15:39:14 +02:00
Paul Bottein
01fd2787be Update add application credentials dialog (#13879) 2022-09-27 15:38:29 +02:00
Paul Bottein
c79955e76a Add subview option to dashboard views (#13822) 2022-09-27 15:37:48 +02:00
dependabot[bot]
51874329d1 Bump actions/stale from 5.2.0 to 6.0.0 (#13874)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-26 14:15:58 +02:00
Erik Montnemery
6252955bb5 Simplify energy settings (#13846) 2022-09-23 09:03:17 +02:00
Paul Bottein
5422fda990 Update import blueprint dialog (#13840) 2022-09-22 15:24:15 +02:00
Paul Bottein
db8bc9d34a Update delete automation dialog (#13765) 2022-09-22 15:22:20 +02:00
Paul Bottein
9f19bdde65 Allow proxy in codespaces env for core (#13842) 2022-09-22 15:21:42 +02:00
Bram Kragten
7336c1280f Fix select issues (#13839) 2022-09-22 15:19:59 +02:00
Bram Kragten
8e245c8a83 Fix move data disk dialog (#13845) 2022-09-22 15:19:34 +02:00
Allen Porter
5a150ac80d Prompt user to remove application credentials when deleting the integration configuration (#13159)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-09-22 10:47:08 +02:00
Paul Bottein
eac13980ff Add navigation picker for dashboards (#13826)
* Add navigation picker for dashboards

* Rename to navigation

* Fix empty title and path

* Use hass panels instead of fetching dashboards

* Apply suggestions
2022-09-21 14:42:51 +02:00
Erik Montnemery
977fdd9fbb Add missing translations to statistics graph card editor (#13836) 2022-09-21 09:30:58 +00:00
Paul Bottein
cedde3d6a2 Avoid overflow with combobox (#13835) 2022-09-21 11:23:22 +02:00
Bram Kragten
56c78ae108 Fix price units for gas (#13824) 2022-09-21 11:16:19 +02:00
Erik Montnemery
82a641a200 Fix unit columns for statistics developer tool (#13830) 2022-09-21 11:15:57 +02:00
Erik Montnemery
04181e9c28 Adapt energy to core changes (#13779) 2022-09-20 17:44:03 -04:00
Paul Bottein
4b8960c236 Update Move datadisk (not found) dialog (#13812) 2022-09-19 12:39:05 +00:00
Paul Bottein
fc104e7280 Fix name in confirmation delete dialog (#13815) 2022-09-19 12:34:06 +02:00
Paul Bottein
8c125f4dee Update Delete automation trigger/condition/action dialog (#13813) 2022-09-19 12:33:27 +02:00
Paul Bottein
b93f457d53 Add destructive style to scene delete button (#13814) 2022-09-19 12:32:17 +02:00
Paul Bottein
e8ce6ad919 Improve confirm unsaved dialog (#13807) 2022-09-19 11:35:33 +02:00
Salamandar
0ce695577c Fix shortcuts for non-qwerty keyboard layouts (revert #12892) (#13190) 2022-09-19 08:21:45 +00:00
Franck Nijhof
50b67751d9 Fix time trigger description pointing to entity (#13786) 2022-09-19 10:11:56 +02:00
Franck Nijhof
05515f21c3 Add timer states to state selector (#13788) 2022-09-19 10:11:10 +02:00
Paul Bottein
063c377797 Fix back button on automation editor on Safari (#13806) 2022-09-19 10:10:50 +02:00
dependabot[bot]
aee11da671 Bump actions/stale from 5.1.1 to 5.2.0 (#13805)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-19 09:22:59 +02:00
Paul Bottein
5fcb219fcd Update delete script dialog (#13768) 2022-09-16 16:40:41 +02:00
Paul Bottein
a97dfbb51f Update delete blueprint dialog (#13770) 2022-09-16 16:40:25 +02:00
Paul Bottein
c5f4e8ffdd Update certificate information dialog (#13773) 2022-09-16 16:40:10 +02:00
Paul Bottein
7ffd30643a Update delete person dialog (#13763) 2022-09-16 16:39:51 +02:00
Paul Bottein
dcfcd54f10 Update delete scene dialog (#13767) 2022-09-16 16:39:29 +02:00
Paul Bottein
3b103619ec Update delete resource dialog (#13764) 2022-09-16 16:38:29 +02:00
Paulus Schoutsen
614c1574ca Type outgoing messages on EM and add matter (#13775) 2022-09-16 08:33:21 -04:00
Paul Bottein
e1e3f9d925 Update delete and disable integration dialog (#13772) 2022-09-16 13:52:26 +02:00
Paul Bottein
0ba4a07b92 Update webhook dialog (#13774) 2022-09-16 13:50:44 +02:00
Paul Bottein
5a5f31b32c Update restart Home Assistant dialog (#13776) 2022-09-16 13:49:15 +02:00
Paul Bottein
ff92768973 Update reboot shutdown host dialog (#13777) 2022-09-16 13:48:55 +02:00
Erik Montnemery
bb0529ecd2 Improve statistics graph editor (#13630) 2022-09-16 13:48:10 +02:00
Paul Bottein
bc62e9372b Update delete dashboard dialog (#13762) 2022-09-16 13:40:41 +02:00
Erik Montnemery
087a897cbe Add comment about input number not supporting initial (#13758) 2022-09-16 13:40:08 +02:00
Franck Nijhof
589efa8cc5 Exclude scenes, schedules & updates from scenes (#13759) 2022-09-16 13:39:38 +02:00
Bram Kragten
c93179c307 Use primary color for active tabs in traces (#13760) 2022-09-16 13:38:45 +02:00
Paul Bottein
9e416e829c Do not recreate entities list at each re-order (#13751) 2022-09-16 13:38:31 +02:00
Paul Bottein
e13c632afa Update delete user dialog (#13761)
* Add destructive confirmation style

* Update delete user dialog
2022-09-15 16:21:25 +02:00
Erik Montnemery
544c8fe3bb Improve StatisticsChart to only fetch needed metadata (#13617) 2022-09-15 11:58:26 +00:00
Paul Bottein
81b21f874b Improve cover entity definition (#13750) 2022-09-15 12:31:36 +02:00
Bram Kragten
ea319d55ef Allow to disable a select option (#13618) 2022-09-15 12:00:00 +02:00
Paul Bottein
8c03bbdccc Improve light entity definition (#13744) 2022-09-15 11:58:36 +02:00
Paul Bottein
321914d53a Fix empty hardware when fetching hardware info (#13738) 2022-09-14 09:13:32 +00:00
Paul Bottein
fe46f759c9 Fix system blank page (#13731) 2022-09-14 09:09:05 +02:00
Paul Bottein
490d46396e Fix system blank page (#13731) 2022-09-14 09:08:37 +02:00
Bram Kragten
7ec28c4314 Bumped version to 20220907.2 2022-09-14 09:03:46 +02:00
Bram Kragten
e9f4307d15 Fix hass subpage (#13730) 2022-09-14 09:03:39 +02:00
Bram Kragten
3c62bc9b18 Fix hass subpage (#13730) 2022-09-14 09:02:51 +02:00
Erik Montnemery
28bae5071c Revert "Add initial field to the helper input_number in UI" (#13713) 2022-09-13 21:01:03 +02:00
Bram Kragten
e9281ad9f1 Bumped version to 20220907.1 2022-09-13 20:58:07 +02:00
Bram Kragten
78187c5b0b improve duration rendering for state trigger (#13723) 2022-09-13 20:57:54 +02:00
Bram Kragten
f164ad0b89 use the correct inputmode (#13722) 2022-09-13 20:57:18 +02:00
Erik Montnemery
48b10005e3 Revert "Add initial field to the helper input_number in UI" (#13713) 2022-09-13 14:53:55 -04:00
Bram Kragten
b3d64fc52a use the correct inputmode (#13722) 2022-09-13 18:53:19 +00:00
Bram Kragten
23e5a47b3b improve duration rendering for state trigger (#13723) 2022-09-13 20:49:39 +02:00
Pierre
55d84973c6 fix: add previous repeat action configuration on change (#13717) 2022-09-13 20:31:40 +02:00
Paul Bottein
de90a62de7 Show confirm dialog when clicking traces (#13716) 2022-09-13 20:31:17 +02:00
Joakim Sørensen
3a17f2d73e Fix open config flow when coming from a my link (#13720) 2022-09-13 20:30:52 +02:00
Paul Bottein
8f6a09f44c Don't use selector inside choose action (#13705) 2022-09-13 20:30:35 +02:00
Paul Bottein
d78191efa6 Fix rtl support for hass subpage layout (#13702) 2022-09-13 20:30:17 +02:00
Joakim Sørensen
749d869e03 Guard repairs subscription (#13708) 2022-09-13 20:30:02 +02:00
Erik Montnemery
5d6f446c30 Fix customizing sensor unit (#13710) 2022-09-13 20:29:47 +02:00
Joakim Plate
3cf14bb2e1 Revert "Either show range or fix target temperature... #13638 (#13706) 2022-09-13 20:29:29 +02:00
Paul Bottein
f7253a73a5 Fix script config editor (#13703) 2022-09-13 20:27:10 +02:00
Joakim Plate
cfabaa8716 Display entity friendly name for disabled entities (#13696) 2022-09-13 20:26:49 +02:00
Paul Bottein
032f497687 Fix empty value for state picker (#13699) 2022-09-13 20:26:29 +02:00
Felipe Santos
432483b3d2 Use newspaper icon for change log button (#13668) 2022-09-13 20:26:08 +02:00
krazos
e95d5b1afb Eliminate redundant "for" in trigger description (#13669) 2022-09-13 20:21:24 +02:00
Bram Kragten
330f3e5ce4 use input instead of change (#13660) 2022-09-13 20:20:54 +02:00
Paul Bottein
fee6ae3045 Move automation trace actions to overflow menu (#13656) 2022-09-13 20:20:38 +02:00
Joakim Sørensen
5e431a07ad Guard more of the hardware panel (#13650) 2022-09-13 20:20:20 +02:00
uvjustin
5d4c090b26 Bump hls.js to v1.2.3 (#13718) 2022-09-13 20:15:01 +02:00
Pierre
b84240edbc fix: add previous repeat action configuration on change (#13717) 2022-09-13 20:00:20 +02:00
Paul Bottein
f4dc74b2e8 Show confirm dialog when clicking traces (#13716) 2022-09-13 19:59:35 +02:00
Joakim Sørensen
c95d19299b Fix open config flow when coming from a my link (#13720) 2022-09-13 19:58:32 +02:00
Paul Bottein
7696df56ac Don't use selector inside choose action (#13705) 2022-09-13 10:43:38 +02:00
Paul Bottein
771733d326 Fix rtl support for hass subpage layout (#13702) 2022-09-13 10:42:15 +02:00
Joakim Sørensen
4f3c708109 Guard repairs subscription (#13708) 2022-09-13 10:41:19 +02:00
Erik Montnemery
d2078a7e50 Fix customizing sensor unit (#13710) 2022-09-13 10:40:48 +02:00
Joakim Plate
d70cb24722 Revert "Either show range or fix target temperature... #13638 (#13706) 2022-09-13 10:40:18 +02:00
Paul Bottein
6902537666 Fix script config editor (#13703) 2022-09-12 11:04:07 -05:00
Joakim Plate
9ea1f61971 Display entity friendly name for disabled entities (#13696) 2022-09-12 15:55:03 +02:00
Paul Bottein
782c95cf04 Fix empty value for state picker (#13699) 2022-09-12 15:53:18 +02:00
Erik Montnemery
d5d6216cfe Move recorder statistics API to data/recorder.ts (#13672)
* Move recorder statistics API to data/recorder.ts

* Fix import

* prettier
2022-09-12 13:23:02 +02:00
Felipe Santos
1086c85964 Use newspaper icon for change log button (#13668) 2022-09-12 12:22:49 +02:00
krazos
47c0901df2 Eliminate redundant "for" in trigger description (#13669) 2022-09-12 11:57:53 +02:00
J. Nick Koston
d323ab6726 Add support for subscribing to config entry changes (#13585) 2022-09-11 10:22:26 -05:00
Erik Montnemery
07b5856190 Don't call deprecated history/* statistics API (#13658) 2022-09-08 16:03:35 -04:00
Bram Kragten
462dee0351 use input instead of change (#13660) 2022-09-08 17:43:36 +02:00
Paul Bottein
f181a085de Move automation trace actions to overflow menu (#13656) 2022-09-08 12:00:52 +02:00
Joakim Sørensen
bf5589b88d Guard more of the hardware panel (#13650) 2022-09-07 19:59:08 -05:00
Bram Kragten
c5428d8581 20220907.0 (#13646) 2022-09-07 16:54:32 +02:00
Bram Kragten
fd431f36f7 Fix state picker (#13644) 2022-09-07 16:43:04 +02:00
Bram Kragten
7acf3a049e Bumped version to 20220907.0 2022-09-07 16:33:01 +02:00
Bram Kragten
cfb0e8b39e cleanup script editor (#13639) 2022-09-07 16:26:32 +02:00
Bram Kragten
a3abbf3812 remove tabs from trace pages (#13640) 2022-09-07 16:26:22 +02:00
Philip Allgaier
980156d23a Add separator option to overflow icon menu (#13627) 2022-09-07 13:56:18 +00:00
Paul Bottein
37c2a3636e Improve scene layout (#13641) 2022-09-07 15:33:17 +02:00
Raman Gupta
b682d13486 Change typing of zwave_js API return based on lib version bump (#13393) 2022-09-07 08:13:13 -05:00
Philip Allgaier
7f82b90c25 Either show range or fix target temperature control in climate more-info (#13638) 2022-09-07 14:27:54 +02:00
Paul Bottein
3e9d6ea2c5 Bring reorder mode to script sequence (#13636) 2022-09-07 14:25:06 +02:00
Paul Bottein
57c5c1c191 Remove re order mode for blueprint automation editor (#13637) 2022-09-07 14:23:42 +02:00
Paul Bottein
b553a3fd92 Some fixes for automation picker and editor (#13634) 2022-09-07 07:47:56 -04:00
Paul Bottein
d1964e92ea Some fixes for script picker and editor (#13635)
* Show error when user try to delete or duplicate yaml only script

* Use same layout as automation
2022-09-07 07:47:24 -04:00
Zack Barett
a889969bb8 Fix Back button on Safari and disable information menu item until saved (#13633) 2022-09-07 01:53:09 +00:00
Paul Bottein
f80b2c578b Fix run script translation (#13626)
fix translation
2022-09-06 17:42:15 +00:00
Paulus Schoutsen
579f73e08f 20220906.0 (#13623) 2022-09-06 11:53:07 -04:00
Bram Kragten
d13c6d3e7b Bumped version to 20220906.0 2022-09-06 17:38:39 +02:00
Bram Kragten
e78c875e8e Add last activated column to scenes data table (#13622) 2022-09-06 17:34:49 +02:00
Bram Kragten
5e8c54b00f Update ha-config-helpers.ts 2022-09-06 16:50:02 +02:00
Paul Bottein
71bc74893f Add overflow menu for script picker (#13620) 2022-09-06 16:48:22 +02:00
Paul Bottein
df72e5099e Add overflow menu for scene picker (#13621) 2022-09-06 16:48:09 +02:00
Paulus Schoutsen
e6862daa38 Avoid script editor dirty on load (#13619) 2022-09-06 15:33:53 +02:00
Paul Bottein
66db8c999f Open external device configuration url to a new tab/window (#13613)
* Open external device configuration url to a new tab/window

* Remove rel in action options
2022-09-06 10:24:03 +00:00
Joakim Sørensen
00bc315fc1 Fetch OS info from Supervisor if we do not return anything for hardware (#13614)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-09-06 09:48:41 +00:00
Paul Bottein
f461825a59 Fix icon picker in dialog (#13616) 2022-09-06 09:48:13 +00:00
Bram Kragten
8c98326e31 Fix netlify demo deploy (#13611) 2022-09-05 20:24:09 -04:00
Bram Kragten
7bb619b0c3 Update translations 2022-09-06 01:26:34 +02:00
Bram Kragten
07bc9081b8 dont remove id from automation config (#13609) 2022-09-05 22:46:30 +00:00
Philip Allgaier
91fa5972d1 Prevent combo box issues with duplicate labels (#13608) 2022-09-06 00:33:39 +02:00
Bram Kragten
abbfde19a2 20220905.0 (#13604) 2022-09-05 19:54:14 +02:00
Bram Kragten
ccd617d68e Bumped version to 20220905.0 2022-09-05 19:39:30 +02:00
Bram Kragten
8a7f35cee6 Improve rename automation dialog (#13601) 2022-09-05 19:38:51 +02:00
Bram Kragten
e510e5b371 Link logbook row to trace if available (#13599)
* Link logbook row to trace if available

* Update ha-logbook-renderer.ts
2022-09-05 19:36:09 +02:00
Paul Bottein
aa6ee0f6d2 Fix icon picker reset by hass update (#13587)
* Fix icon picker reset by hass update

* Update src/components/ha-icon-picker.ts

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

* Only update when not opened

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-09-05 19:01:20 +02:00
Bram Kragten
f3449c4d9b Add description to automation editor (#13603) 2022-09-05 19:00:54 +02:00
Matthias de Baat
3c289deb21 Add remove, delete, add and create guidelines (#13593)
Co-authored-by: Philip Allgaier <philip.allgaier@gmx.de>
2022-09-05 18:28:54 +02:00
Paul Bottein
847d163cc8 Disable close on outside click for rename + mode dialogs (#13602) 2022-09-05 16:26:32 +00:00
Paul Bottein
28d11703fc Reorder overflow menu (#13596) 2022-09-05 18:18:58 +02:00
Bram Kragten
1f003ae3be Remove tabs from area and device pages (#13600) 2022-09-05 18:18:32 +02:00
chpego
a57d7813e7 typo dialogs (#13598) 2022-09-05 15:55:48 +00:00
J. Nick Koston
5842b10a10 Handle logbook updates where the new records are in the middle of the old records (#13595) 2022-09-05 17:47:48 +02:00
Paul Bottein
8ee9655bd5 On larger screens, move traces button out of the overflow menu (#13597) 2022-09-05 17:44:10 +02:00
Paul Bottein
3ef567dcd5 Automation change mode dialog (#13591) 2022-09-05 17:43:34 +02:00
Joakim Sørensen
37f6b4f6be Show hardware if hassio or hardware (#13594) 2022-09-05 16:47:28 +02:00
Philip Allgaier
a817faae54 Add back blank before percent sign ("%") based on language (#13590)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2022-09-05 12:49:21 +00:00
Paul Bottein
ab745f6e8e Reorder automation elements (#13548) 2022-09-05 08:19:38 -04:00
Bram Kragten
02d608b704 only show cpu and mem when available (#13589) 2022-09-05 08:12:04 -04:00
Bram Kragten
310df387e7 Fix tag trigger (#13588) 2022-09-05 08:08:52 -04:00
Bram Kragten
fe8e79a67f Remove tabs from scene and script edit page (#13592) 2022-09-05 08:03:00 -04:00
Paulus Schoutsen
8ffe676827 Move edit description into rename dialog (#13580) 2022-09-05 10:49:07 +02:00
David F. Mulcahey
f032d0dbcf Fix ZHA visualization page (#13584) 2022-09-04 22:25:03 -04:00
Philip Allgaier
81cc745c0a Align wording in automation and script editor overflow menus (#13575) 2022-09-03 13:22:42 -04:00
Michel van de Wetering
43f9c9ebc9 Add mediadescription for channel media type (#13434) 2022-09-03 11:44:02 +02:00
Michel van de Wetering
a9d1feb196 Hide soundmode when mediaplayer is off or unavailable (#13347) 2022-09-03 11:41:24 +02:00
Paulus Schoutsen
8ec2c38f72 20220902.0 (#13571) 2022-09-02 16:15:38 -04:00
Paulus Schoutsen
72aea57105 Bumped version to 20220902.0 2022-09-02 16:14:53 -04:00
Philip Allgaier
031ecf5be8 Align visuals of automation and script editor after redesign (#13567) 2022-09-02 13:03:53 -04:00
Paul Bottein
93e7927686 Fix automation trace link (#13563) 2022-09-02 13:02:50 -04:00
Paul Bottein
320d8e6190 Improve blueprint editor layout (#13564) 2022-09-02 13:02:36 -04:00
Paul Bottein
efa4f65686 Add information in overflow menu (#13570) 2022-09-02 13:02:01 -04:00
Paul Bottein
ec257710ff Add overflow menu to automation picker (#13569) 2022-09-02 13:01:05 -04:00
Paulus Schoutsen
ffad6f340f Fix some descriptions (#13562) 2022-09-01 21:43:30 -05:00
Paulus Schoutsen
0b637fc9bd Dev -> Master 20220901.0 (#13561) 2022-09-01 16:42:16 -04:00
Zack Barett
9f9b0b6457 Bumped version to 20220901.0 (#13560) 2022-09-01 20:11:10 +00:00
Zack Barett
a4227680de Fix Unable to select last slot (#13559) 2022-09-01 19:54:32 +00:00
Zack Barett
5cfd263617 Fix Sunday issue and add minutes to events (#13556) 2022-09-01 16:06:51 +00:00
Bram Kragten
430e671901 unique-id -> id (#13552) 2022-09-01 11:51:38 -04:00
Ernst Klamer
8fcd396445 Add icon for device class moisture (#13553) 2022-09-01 11:48:04 -04:00
Erik Montnemery
e273b6b659 Improve delete device button and confirmation dialog (#13500) 2022-09-01 10:38:56 -05:00
Bram Kragten
2751adf440 remove duplicate controls blueprint automation (#13554) 2022-09-01 10:37:22 -05:00
Matthias de Baat
d661450121 Typo on dialogs page (#13555) 2022-09-01 10:36:56 -05:00
Steve Repsher
4511ded205 Add semantic heading to script editor (#13546) 2022-09-01 16:19:08 +02:00
Erik Montnemery
2bf0c5d72d Only update device class if changed by user (#13551) 2022-09-01 12:25:32 +00:00
Steve Repsher
604e5d5e09 Add semantic headings to automation editor (#13542)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2022-08-31 14:15:14 -05:00
Paulus Schoutsen
5466705d97 20220831.0 (#13541) 2022-08-31 12:45:33 -04:00
Bram Kragten
774aee406c Fix tag trigger (#13540)
* Fix tag trigger

* Fix
2022-08-31 12:28:50 -04:00
Zack Barett
775837b60f Bumped version to 20220831.0 (#13539) 2022-08-31 18:28:31 +02:00
Bram Kragten
030b2b921a Format duration object (#13538) 2022-08-31 16:24:24 +00:00
Bram Kragten
229bc26327 Don't fire change on tag picker when not changed (#13537) 2022-08-31 16:08:35 +00:00
Bram Kragten
99e85173eb Change padding buttons entity settings (#13536) 2022-08-31 15:48:54 +00:00
Bram Kragten
be0c22d7ae Fix header mobile automation editor (#13534) 2022-08-31 15:42:00 +00:00
Zack Barett
fee1092a08 Fix Selection on IOS (#13533) 2022-08-31 15:40:03 +00:00
Bram Kragten
d041bd9fd3 use device and area names in service call description (#13532) 2022-08-31 15:30:44 +00:00
Zack Barett
df4b83349e Merge pull request #13329 from home-assistant/dev 2022-08-02 10:20:21 -05:00
Zack Barett
61b42249ec Merge pull request #13302 from home-assistant/dev
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2022-07-28 10:31:47 -05:00
Bram Kragten
40616b6af2 Merge pull request #13286 from home-assistant/dev 2022-07-27 12:41:33 +02:00
751 changed files with 28513 additions and 209620 deletions

View File

@@ -5,33 +5,39 @@
"context": ".."
},
"appPort": "8124:8123",
"context": "..",
"postCreateCommand": "script/bootstrap",
"extensions": [
"github.vscode-pull-request-github",
"dbaeumer.vscode-eslint",
"ms-vscode.vscode-typescript-tslint-plugin",
"esbenp.prettier-vscode",
"bierner.lit-html",
"runem.lit-plugin",
"ms-python.vscode-pylance"
],
"containerEnv": {
"WORKSPACE_DIRECTORY": "${containerWorkspaceFolder}"
},
"settings": {
"terminal.integrated.shell.linux": "/bin/bash",
"files.eol": "\n",
"editor.tabSize": 2,
"editor.formatOnPaste": false,
"editor.formatOnSave": true,
"editor.formatOnType": true,
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"files.trimTrailingWhitespace": true
"customizations": {
"vscode": {
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"runem.lit-plugin",
"github.vscode-pull-request-github",
"eamodio.gitlens"
],
"settings": {
"files.eol": "\n",
"editor.tabSize": 2,
"editor.formatOnPaste": false,
"editor.formatOnSave": true,
"editor.formatOnType": true,
"editor.renderWhitespace": "boundary",
"editor.rulers": [80],
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"files.trimTrailingWhitespace": true,
"terminal.integrated.shell.linux": "/usr/bin/zsh",
"gitlens.showWelcomeOnInstall": false,
"gitlens.showWhatsNewAfterUpgrades": false,
"workbench.startupEditor": "none"
}
}
}
}

90
.github/workflows/cast_deployment.yaml vendored Normal file
View File

@@ -0,0 +1,90 @@
name: Cast deployment
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * *"
push:
branches:
- master
env:
NODE_VERSION: 16
NODE_OPTIONS: --max_old_space_size=6144
jobs:
deploy_dev:
runs-on: ubuntu-latest
name: Deploy Development
if: github.event_name != 'push'
environment:
name: Cast Development
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
steps:
- name: Check out files from GitHub
uses: actions/checkout@v3
with:
ref: dev
- name: Set up Node ${{ env.NODE_VERSION }}
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: yarn
- name: Install dependencies
run: yarn install
env:
CI: true
- name: Build Cast
run: ./node_modules/.bin/gulp build-cast
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy to Netlify
id: deploy
uses: netlify/actions/cli@master
with:
args: deploy --dir=cast/dist --alias dev
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_CAST_SITE_ID }}
deploy_master:
runs-on: ubuntu-latest
name: Deploy Production
if: github.event_name == 'push'
environment:
name: Cast Production
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
steps:
- name: Check out files from GitHub
uses: actions/checkout@v3
with:
ref: master
- name: Set up Node ${{ env.NODE_VERSION }}
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: yarn
- name: Install dependencies
run: yarn install
env:
CI: true
- name: Build Cast
run: ./node_modules/.bin/gulp build-cast
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy to Netlify
id: deploy
uses: netlify/actions/cli@master
with:
args: deploy --dir=cast/dist --prod
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_CAST_SITE_ID }}

View File

@@ -13,6 +13,7 @@ on:
env:
NODE_VERSION: 16
NODE_OPTIONS: --max_old_space_size=6144
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
lint:

View File

@@ -1,6 +1,9 @@
name: Demo
name: Demo deployment
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * *"
push:
branches:
- dev
@@ -12,24 +15,34 @@ env:
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: Demo
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
steps:
- name: Check out files from GitHub
uses: actions/checkout@v3
- name: Set up Node ${{ env.NODE_VERSION }}
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: yarn
- name: Install dependencies
run: yarn install
env:
CI: true
- name: Build Demo
run: ./node_modules/.bin/gulp build-demo
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy to Netlify
id: deploy
uses: netlify/actions/cli@master
with:
args: deploy --dir=demo/dist --prod
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_DEMO_DEV_SITE_ID }}
with:
args: deploy --dir=demo/dist --prod

View File

@@ -0,0 +1,45 @@
name: Design deployment
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * *"
env:
NODE_VERSION: 16
NODE_OPTIONS: --max_old_space_size=6144
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: Design
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
steps:
- name: Check out files from GitHub
uses: actions/checkout@v3
- name: Set up Node ${{ env.NODE_VERSION }}
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: yarn
- name: Install dependencies
run: yarn install
env:
CI: true
- name: Build Gallery
run: ./node_modules/.bin/gulp build-gallery
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy to Netlify
id: deploy
uses: netlify/actions/cli@master
with:
args: deploy --dir=gallery/dist --prod
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_GALLERY_SITE_ID }}

54
.github/workflows/design_preview.yaml vendored Normal file
View File

@@ -0,0 +1,54 @@
name: Design preview
on:
pull_request:
types:
- opened
- synchronize
- reopened
- labeled
branches:
- dev
env:
NODE_VERSION: 16
NODE_OPTIONS: --max_old_space_size=6144
jobs:
preview:
runs-on: ubuntu-latest
# Skip running on forks since it won't have access to secrets
# Skip running PRs without 'needs design preview' label
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@v3
- name: Set up Node ${{ env.NODE_VERSION }}
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: yarn
- name: Install dependencies
run: yarn install
env:
CI: true
- name: Build Gallery
run: ./node_modules/.bin/gulp build-gallery
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy preview to Netlify
id: deploy
uses: netlify/actions/cli@master
with:
args: deploy --dir=gallery/dist --alias "deploy-preview-${{ github.event.number }}"
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_GALLERY_SITE_ID }}
- name: Generate summary
run: |
echo "${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}" >> "$GITHUB_STEP_SUMMARY"

View File

@@ -9,7 +9,7 @@ jobs:
lock:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v3.0.0
- uses: dessant/lock-threads@v4.0.0
with:
github-token: ${{ github.token }}
issue-lock-inactive-days: "30"

View File

@@ -1,19 +0,0 @@
name: Netlify
on:
schedule:
- cron: "0 0 * * *"
jobs:
trigger_builds:
name: Trigger netlify build preview
runs-on: "ubuntu-latest"
steps:
- name: Trigger Cast build
run: curl -X POST -d {} https://api.netlify.com/build_hooks/${{ secrets.NETLIFY_CAST_DEV_BUILD_HOOK }}
- name: Trigger Demo build
run: curl -X POST -d {} https://api.netlify.com/build_hooks/${{ secrets.NETLIFY_DEMO_DEV_BUILD_HOOK }}
- name: Trigger Design build
run: curl -X POST -d "NIGHTLY" https://api.netlify.com/build_hooks/${{ secrets.NETLIFY_GALLERY_DEV_BUILD_HOOK }}

View File

@@ -49,9 +49,8 @@ jobs:
run: |
pip install build
yarn install
export SKIP_FETCH_NIGHTLY_TRANSLATIONS=1
script/build_frontend
rm -rf dist home_assistant_frontend.egg-info
python3 -m build

View File

@@ -52,11 +52,11 @@ jobs:
python3 -m pip install twine build
export TWINE_USERNAME="__token__"
export TWINE_PASSWORD="${{ secrets.TWINE_TOKEN }}"
export SKIP_FETCH_NIGHTLY_TRANSLATIONS=1
script/release
- name: Upload release assets
uses: softprops/action-gh-release@v0.1.14
uses: softprops/action-gh-release@v0.1.15
with:
files: |
dist/*.whl
@@ -75,7 +75,7 @@ jobs:
echo "home-assistant-frontend==$version" > ./requirements.txt
- name: Build wheels
uses: home-assistant/wheels@2022.06.7
uses: home-assistant/wheels@2022.10.1
with:
abi: cp310
tag: musllinux_1_2

View File

@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: 90 days stale policy
uses: actions/stale@v5.1.1
uses: actions/stale@v6.0.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 90

17
.gitignore vendored
View File

@@ -2,19 +2,20 @@
.reify-cache
# build
build
hass_frontend/*
dist
build/
dist/
/hass_frontend/
/translations/
# yarn
.yarn/*
.yarn/**
!.yarn/patches
!.yarn/releases
!.yarn/plugins
!.yarn/sdks
!.yarn/versions
.pnp.*
node_modules/*
/node_modules/
yarn-error.log
npm-debug.log
@@ -26,11 +27,11 @@ npm-debug.log
# venv stuff
pyvenv.cfg
pip-selfcheck.json
venv/*
/venv/
.venv
# vscode
.vscode/*
.vscode/**
!.vscode/extensions.json
!.vscode/launch.json
!.vscode/tasks.json
@@ -45,4 +46,4 @@ src/cast/dev_const.ts
.tool-versions
# Home Assistant config
/config
/config/

View File

@@ -2,7 +2,8 @@
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"bierner.lit-html",
"runem.lit-plugin"
"runem.lit-plugin",
"github.vscode-pull-request-github",
"eamodio.gitlens"
]
}

8
.vscode/tasks.json vendored
View File

@@ -191,7 +191,13 @@
"runOptions": {
"instanceLimit": 1
}
}
},
{
"label": "Setup and fetch nightly translations",
"type": "gulp",
"task": "setup-and-fetch-nightly-translations",
"problemMatcher": []
}
],
"inputs": [
{

File diff suppressed because one or more lines are too long

783
.yarn/releases/yarn-3.2.3.cjs vendored Executable file

File diff suppressed because one or more lines are too long

View File

@@ -6,4 +6,4 @@ plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"
yarnPath: .yarn/releases/yarn-3.2.0.cjs
yarnPath: .yarn/releases/yarn-3.2.3.cjs

View File

@@ -1,7 +0,0 @@
{
"rules": {
"import/no-extraneous-dependencies": 0,
"no-restricted-syntax": 0,
"no-console": 0
}
}

View File

@@ -1,7 +1,12 @@
{
"extends": "../.eslintrc.json",
"rules": {
"import/no-extraneous-dependencies": 0,
"global-require": 0
"no-console": "off",
"import/no-extraneous-dependencies": "off",
"import/extensions": "off",
"import/no-dynamic-require": "off",
"global-require": "off",
"@typescript-eslint/no-var-requires": "off",
"prefer-arrow-callback": "off"
}
}

View File

@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("path");
// Currently only supports CommonJS modules, as require is synchronous. `import` would need babel running asynchronous.
@@ -29,7 +28,6 @@ module.exports = function inlineConstants(babel, options, cwd) {
const absolute = module.startsWith(".")
? require.resolve(module, { paths: [cwd] })
: module;
// eslint-disable-next-line import/no-dynamic-require
return [absolute, require(absolute)];
})
);

View File

@@ -1,9 +1,9 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("path");
const env = require("./env.js");
const paths = require("./paths.js");
// 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"),

View File

@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const fs = require("fs");
const path = require("path");
const paths = require("./paths.js");

View File

@@ -1,17 +1,12 @@
const del = require("del");
const gulp = require("gulp");
const fs = require("fs");
const fs = require("fs/promises");
const mapStream = require("map-stream");
const inDirFrontend = "translations/frontend";
const inDirBackend = "translations/backend";
const downloadDir = "translations/downloads";
const srcMeta = "src/translations/translationMetadata.json";
const encoding = "utf8";
const tasks = [];
function hasHtml(data) {
return /<[a-z][\s\S]*>/i.test(data);
}
@@ -46,50 +41,29 @@ function checkHtml() {
});
}
let taskName = "clean-downloaded-translations";
gulp.task(taskName, function () {
return del([`${downloadDir}/**`]);
// Backend translations do not currently pass HTML check so are excluded here for now
gulp.task("check-translations-html", function () {
return gulp.src([`${inDirFrontend}/*.json`]).pipe(checkHtml());
});
tasks.push(taskName);
taskName = "check-translations-html";
gulp.task(taskName, function () {
return gulp.src(`${downloadDir}/*.json`).pipe(checkHtml());
});
tasks.push(taskName);
taskName = "check-all-files-exist";
gulp.task(taskName, function () {
const file = fs.readFileSync(srcMeta, { encoding });
gulp.task("check-all-files-exist", async function () {
const file = await fs.readFile(srcMeta, { encoding });
const meta = JSON.parse(file);
const writings = [];
Object.keys(meta).forEach((lang) => {
if (!fs.existsSync(`${inDirFrontend}/${lang}.json`)) {
fs.writeFileSync(`${inDirFrontend}/${lang}.json`, JSON.stringify({}));
}
if (!fs.existsSync(`${inDirBackend}/${lang}.json`)) {
fs.writeFileSync(`${inDirBackend}/${lang}.json`, JSON.stringify({}));
}
writings.push(
fs.writeFile(`${inDirFrontend}/${lang}.json`, JSON.stringify({}), {
flag: "wx",
}),
fs.writeFile(`${inDirBackend}/${lang}.json`, JSON.stringify({}), {
flag: "wx",
})
);
});
return Promise.resolve();
await Promise.allSettled(writings);
});
tasks.push(taskName);
taskName = "move-downloaded-translations";
gulp.task(taskName, function () {
return gulp.src(`${downloadDir}/*.json`).pipe(gulp.dest(inDirFrontend));
});
tasks.push(taskName);
taskName = "check-downloaded-translations";
gulp.task(
taskName,
gulp.series(
"check-translations-html",
"move-downloaded-translations",
"check-all-files-exist",
"clean-downloaded-translations"
)
"check-downloaded-translations",
gulp.series("check-translations-html", "check-all-files-exist")
);
tasks.push(taskName);
module.exports = tasks;

View File

@@ -1,6 +1,4 @@
// Tasks to generate entry HTML
/* eslint-disable import/no-dynamic-require */
/* eslint-disable global-require */
const gulp = require("gulp");
const fs = require("fs-extra");
const path = require("path");
@@ -91,7 +89,9 @@ gulp.task("gen-pages-prod", (done) => {
});
gulp.task("gen-index-app-dev", (done) => {
let latestAppJS, latestCoreJS, latestCustomPanelJS;
let latestAppJS;
let latestCoreJS;
let latestCustomPanelJS;
if (env.useWDS()) {
latestAppJS = "http://localhost:8000/src/entrypoints/app.ts";

View File

@@ -0,0 +1,170 @@
// Task to download the latest Lokalise translations from the nightly workflow artifacts
const fs = require("fs/promises");
const path = require("path");
const process = require("process");
const del = require("del");
const gulp = require("gulp");
const jszip = require("jszip");
const tar = require("tar");
const { Octokit } = require("@octokit/rest");
const { createOAuthDeviceAuth } = require("@octokit/auth-oauth-device");
const MAX_AGE = 24; // hours
const OWNER = "home-assistant";
const REPO = "frontend";
const WORKFLOW_NAME = "nightly.yaml";
const ARTIFACT_NAME = "translations";
const CLIENT_ID = "Iv1.3914e28cb27834d1";
const EXTRACT_DIR = "translations";
const TOKEN_FILE = path.join(EXTRACT_DIR, "token.json");
const ARTIFACT_FILE = path.join(EXTRACT_DIR, "artifact.json");
let allowTokenSetup = false;
gulp.task("allow-setup-fetch-nightly-translations", (done) => {
allowTokenSetup = true;
done();
});
gulp.task("fetch-nightly-translations", async function () {
// Skip all when environment flag is set (assumes translations are already in place)
if (process.env?.SKIP_FETCH_NIGHTLY_TRANSLATIONS) {
console.log("Skipping fetch due to environment signal");
return;
}
// Read current translations artifact info if it exists,
// and stop if they are not old enough
let currentArtifact;
try {
currentArtifact = JSON.parse(await fs.readFile(ARTIFACT_FILE, "utf-8"));
const currentAge =
(Date.now() - Date.parse(currentArtifact.created_at)) / 3600000;
if (currentAge < MAX_AGE) {
console.log(
"Keeping current translations (only %s hours old)",
currentAge.toFixed(1)
);
return;
}
} catch {
currentArtifact = null;
}
// To store file writing promises
const createExtractDir = fs.mkdir(EXTRACT_DIR, { recursive: true });
const writings = [];
// Authenticate to GitHub using GitHub action token if it exists,
// otherwise look for a saved user token or generate a new one if none
let tokenAuth;
if (process.env.GITHUB_TOKEN) {
tokenAuth = { token: process.env.GITHUB_TOKEN };
} else {
try {
tokenAuth = JSON.parse(await fs.readFile(TOKEN_FILE, "utf-8"));
} catch {
if (!allowTokenSetup) {
console.log("No token found so build wil continue with English only");
return;
}
const auth = createOAuthDeviceAuth({
clientType: "github-app",
clientId: CLIENT_ID,
onVerification: (verification) => {
console.log(
"Task needs to authenticate to GitHub to fetch the translations from nightly workflow\n" +
"Please go to %s to authorize this task\n" +
"\nEnter user code: %s\n\n" +
"This code will expire in %s minutes\n" +
"Task will automatically continue after authorization and token will be saved for future use",
verification.verification_uri,
verification.user_code,
(verification.expires_in / 60).toFixed(0)
);
},
});
tokenAuth = await auth({ type: "oauth" });
writings.push(
createExtractDir.then(
fs.writeFile(TOKEN_FILE, JSON.stringify(tokenAuth, null, 2))
)
);
}
}
// Authenticate with token and request workflow runs from GitHub
console.log("Fetching new translations...");
const octokit = new Octokit({
userAgent: "Fetch Nightly Translations",
auth: tokenAuth.token,
});
const workflowRunsResponse = await octokit.rest.actions.listWorkflowRuns({
owner: OWNER,
repo: REPO,
workflow_id: WORKFLOW_NAME,
status: "success",
event: "schedule",
per_page: 1,
exclude_pull_requests: true,
});
if (workflowRunsResponse.data.total_count === 0) {
throw Error("No successful nightly workflow runs found");
}
const latestNightlyRun = workflowRunsResponse.data.workflow_runs[0];
// Stop if current is already the latest, otherwise Find the translations artifact
if (currentArtifact?.workflow_run.id === latestNightlyRun.id) {
console.log("Stopping because current translations are still the latest");
return;
}
const latestArtifact = (
await octokit.actions.listWorkflowRunArtifacts({
owner: OWNER,
repo: REPO,
run_id: latestNightlyRun.id,
})
).data.artifacts.find((artifact) => artifact.name === ARTIFACT_NAME);
if (!latestArtifact) {
throw Error("Latest nightly workflow run has no translations artifact");
}
writings.push(
createExtractDir.then(
fs.writeFile(ARTIFACT_FILE, JSON.stringify(latestArtifact, null, 2))
)
);
// Remove the current translations
const deleteCurrent = Promise.all(writings).then(
del([`${EXTRACT_DIR}/*`, `!${ARTIFACT_FILE}`, `!${TOKEN_FILE}`])
);
// Get the download URL and follow the redirect to download (stored as ArrayBuffer)
const downloadResponse = await octokit.actions.downloadArtifact({
owner: OWNER,
repo: REPO,
artifact_id: latestArtifact.id,
archive_format: "zip",
});
if (downloadResponse.status !== 200) {
throw Error("Failure downloading translations artifact");
}
// Artifact is a tarball, but GitHub adds it to a zip file
console.log("Unpacking downloaded translations...");
const zip = await jszip.loadAsync(downloadResponse.data);
await deleteCurrent;
const extractStream = zip.file(/.*/)[0].nodeStream().pipe(tar.extract());
await new Promise((resolve, reject) => {
extractStream.on("close", resolve).on("error", reject);
});
});
gulp.task(
"setup-and-fetch-nightly-translations",
gulp.series(
"allow-setup-fetch-nightly-translations",
"fetch-nightly-translations"
)
);

View File

@@ -1,4 +1,3 @@
/* eslint-disable */
// Run demo develop mode
const gulp = require("gulp");
const fs = require("fs");
@@ -41,7 +40,7 @@ gulp.task("gather-gallery-pages", async function gatherPages() {
}
processed.add(pageId);
const [category, name] = pageId.split("/", 2);
const [category] = pageId.split("/", 2);
const demoFile = path.resolve(pageDir, `${pageId}.ts`);
const descriptionFile = path.resolve(pageDir, `${pageId}.markdown`);

View File

@@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const del = require("del");
const path = require("path");
const gulp = require("gulp");

View File

@@ -5,9 +5,9 @@ const rollup = require("rollup");
const handler = require("serve-handler");
const http = require("http");
const log = require("fancy-log");
const open = require("open");
const rollupConfig = require("../rollup");
const paths = require("../paths");
const open = require("open");
const bothBuilds = (createConfigFunc, params) =>
gulp.series(
@@ -30,11 +30,11 @@ const bothBuilds = (createConfigFunc, params) =>
);
function createServer(serveOptions) {
const server = http.createServer((request, response) => {
return handler(request, response, {
const server = http.createServer((request, response) =>
handler(request, response, {
public: serveOptions.root,
});
});
})
);
server.listen(
serveOptions.port,

View File

@@ -1,7 +1,5 @@
// Generate service worker.
// Based on manifest, create a file with the content as service_worker.js
/* eslint-disable import/no-dynamic-require */
/* eslint-disable global-require */
const gulp = require("gulp");
const path = require("path");
const fs = require("fs-extra");

View File

@@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const crypto = require("crypto");
const del = require("del");
const path = require("path");
@@ -15,6 +13,8 @@ const { mapFiles } = require("../util");
const env = require("../env");
const paths = require("../paths");
require("./fetch-nightly_translations");
const inFrontendDir = "translations/frontend";
const inBackendDir = "translations/backend";
const workDir = "build/translations";
@@ -23,10 +23,13 @@ const coreDir = workDir + "/core";
const outDir = workDir + "/output";
let mergeBackend = false;
gulp.task("translations-enable-merge-backend", (done) => {
mergeBackend = true;
done();
});
gulp.task(
"translations-enable-merge-backend",
gulp.parallel((done) => {
mergeBackend = true;
done();
}, "allow-setup-fetch-nightly-translations")
);
// Panel translations which should be split from the core translations.
const TRANSLATION_FRAGMENTS = Object.keys(
@@ -170,17 +173,24 @@ gulp.task("build-master-translation", () => {
.pipe(transform((data, file) => lokaliseTransform(data, data, file)))
.pipe(
merge({
fileName: "translationMaster.json",
fileName: "en.json",
})
)
.pipe(gulp.dest(workDir));
.pipe(gulp.dest(fullDir));
});
gulp.task("build-merged-translations", () =>
gulp
.src([inFrontendDir + "/*.json", workDir + "/test.json"], {
allowEmpty: true,
})
.src(
[
inFrontendDir + "/*.json",
"!" + inFrontendDir + "/en.json",
workDir + "/test.json",
],
{
allowEmpty: true,
}
)
.pipe(transform((data, file) => lokaliseTransform(data, data, file)))
.pipe(
flatmap((stream, file) => {
@@ -193,7 +203,7 @@ gulp.task("build-merged-translations", () =>
// than a base translation + region.
const tr = path.basename(file.history[0], ".json");
const subtags = tr.split("-");
const src = [workDir + "/translationMaster.json"];
const src = [fullDir + "/en.json"];
for (let i = 1; i <= subtags.length; i++) {
const lang = subtags.slice(0, i).join("-");
if (lang === "test") {
@@ -378,7 +388,6 @@ gulp.task("build-translation-write-metadata", () =>
if (value.nativeName) {
newData[key] = value;
} else {
// eslint-disable-next-line no-console
console.warn(
`Skipping language ${key}. Native name was not translated.`
);
@@ -411,8 +420,10 @@ gulp.task(
gulp.task(
"build-translations",
gulp.series(
"clean-translations",
"ensure-translations-build-dir",
gulp.parallel(
"fetch-nightly-translations",
gulp.series("clean-translations", "ensure-translations-build-dir")
),
"create-translations",
"build-translation-fingerprints",
"build-translation-write-metadata"
@@ -422,8 +433,10 @@ gulp.task(
gulp.task(
"build-supervisor-translations",
gulp.series(
"clean-translations",
"ensure-translations-build-dir",
gulp.parallel(
"fetch-nightly-translations",
gulp.series("clean-translations", "ensure-translations-build-dir")
),
"build-master-translation",
"build-merged-translations",
"build-translation-fragment-supervisor",

View File

@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-var-requires */
// Tasks to run webpack.
const fs = require("fs");
const gulp = require("gulp");
@@ -69,7 +68,6 @@ const doneHandler = (done) => (err, stats) => {
}
if (stats.hasErrors() || stats.hasWarnings()) {
// eslint-disable-next-line no-console
console.log(stats.toString("minimal"));
}

View File

@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("path");
module.exports = {

View File

@@ -81,13 +81,13 @@ module.exports = function (opts = {}) {
opts.workerRegexp.flags
);
if (!workerRegexp.test(code)) {
return;
return undefined;
}
const ms = new MagicString(code);
// Reset the regexp
workerRegexp.lastIndex = 0;
while (true) {
for (;;) {
const match = workerRegexp.exec(code);
if (!match) {
break;
@@ -98,6 +98,7 @@ module.exports = function (opts = {}) {
// Parse the optional options object
if (match[3] && match[3].length > 0) {
// FIXME: ooooof!
// eslint-disable-next-line @typescript-eslint/no-implied-eval
optionsObject = new Function(`return ${match[3].slice(1)};`)();
}
delete optionsObject.type;
@@ -110,12 +111,14 @@ module.exports = function (opts = {}) {
}
// Find worker file and store it as a chunk with ID prefixed for our loader
// eslint-disable-next-line no-await-in-loop
const resolvedWorkerFile = (await this.resolve(workerFile, id)).id;
let chunkRefId;
if (resolvedWorkerFile in refIds) {
chunkRefId = refIds[resolvedWorkerFile];
} else {
this.addWatchFile(resolvedWorkerFile);
// eslint-disable-next-line no-await-in-loop
const source = await getBundledWorker(
resolvedWorkerFile,
rollupOptions

View File

@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("path");
const commonjs = require("@rollup/plugin-commonjs");

View File

@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("path");
const fs = require("fs");

View File

@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const webpack = require("webpack");
const path = require("path");
const TerserPlugin = require("terser-webpack-plugin");
@@ -103,7 +102,6 @@ const createWebpackConfig = ({
? path.resolve(context, resource)
: require.resolve(resource);
} catch (err) {
// eslint-disable-next-line no-console
console.error(
"Error in Home Assistant ignore plugin",
resource,

View File

@@ -213,7 +213,7 @@
</p>
<ul>
<li>Google Chrome (all platforms except iOS)</li>
<li>Microsoft Edge (all platforms)</li>
<li>Microsoft Edge (all platforms except iOS)</li>
</ul>
</div>

View File

@@ -88,7 +88,7 @@ class HcCast extends LitElement {
>
${(this.lovelaceConfig
? this.lovelaceConfig.views
: [generateDefaultViewConfig([], [], [], {}, () => "")]
: [generateDefaultViewConfig({}, {}, {}, {}, () => "")]
).map(
(view, idx) => html`
<paper-icon-item
@@ -181,7 +181,7 @@ class HcCast extends LitElement {
private async _handlePickView(ev: Event) {
const path = (ev.currentTarget as any).getAttribute("data-path");
await ensureConnectedCastSession(this.castManager!, this.auth!);
castSendShowLovelaceView(this.castManager, path);
castSendShowLovelaceView(this.castManager, path, this.auth.data.hassUrl);
}
private async _handleLogout() {

View File

@@ -44,7 +44,7 @@ class HcLayout extends LitElement {
<div class="footer">
<a href="./faq.html">Frequently Asked Questions</a> Found a bug?
<a
href="https://github.com/home-assistant/home-assistant-polymer/issues"
href="https://github.com/home-assistant/frontend/issues"
target="_blank"
>Let us know!</a
>

View File

@@ -33,7 +33,6 @@ import { castContext } from "../cast_context";
import "./hc-launch-screen";
let resourcesLoaded = false;
@customElement("hc-main")
export class HcMain extends HassElement {
@state() private _showDemo = false;
@@ -46,6 +45,8 @@ export class HcMain extends HassElement {
@state() private _urlPath?: string | null;
private _hassUUID?: string;
private _unsubLovelace?: UnsubscribeFunc;
public processIncomingMessage(msg: HassMessage) {
@@ -125,6 +126,7 @@ export class HcMain extends HassElement {
if (this.hass) {
status.hassUrl = this.hass.auth.data.hassUrl;
status.hassUUID = this._hassUUID;
status.lovelacePath = this._lovelacePath;
status.urlPath = this._urlPath;
}
@@ -163,6 +165,18 @@ export class HcMain extends HassElement {
};
private async _handleGetStatusMessage(msg: GetStatusMessage) {
if (
(this.hass && msg.hassUUID && msg.hassUUID !== this._hassUUID) ||
(this.hass && msg.hassUrl && msg.hassUrl !== this.hass.auth.data.hassUrl)
) {
this._error = "Not connected to the same Home Assistant instance.";
this._sendError(
ReceiverErrorCode.WRONG_INSTANCE,
this._error,
msg.senderId!
);
}
this._sendStatus(msg.senderId!);
}
@@ -179,6 +193,7 @@ export class HcMain extends HassElement {
expires_in: 0,
}),
});
this._hassUUID = msg.hassUUID;
} catch (err: any) {
const errorMessage = this._getErrorMessage(err);
this._error = errorMessage;
@@ -209,9 +224,29 @@ export class HcMain extends HassElement {
if (!this.hass) {
this._sendStatus(msg.senderId!);
this._error = "Cannot show Lovelace because we're not connected.";
this._sendError(ReceiverErrorCode.NOT_CONNECTED, this._error);
this._sendError(
ReceiverErrorCode.NOT_CONNECTED,
this._error,
msg.senderId!
);
return;
}
if (
(msg.hassUUID && msg.hassUUID !== this._hassUUID) ||
(msg.hassUrl && msg.hassUrl !== this.hass.auth.data.hassUrl)
) {
this._sendStatus(msg.senderId!);
this._error =
"Cannot show Lovelace because we're not connected to the same Home Assistant instance.";
this._sendError(
ReceiverErrorCode.WRONG_INSTANCE,
this._error,
msg.senderId!
);
return;
}
this._error = undefined;
if (msg.urlPath === "lovelace") {
msg.urlPath = null;

View File

@@ -508,7 +508,7 @@ export const demoEntitiesArsaboo: DemoConfig["entities"] = (localize) =>
origin_addresses: ["XYZ"],
status: "OK",
mode: "driving",
units: "imperial",
units: "us_customary",
duration_in_traffic: "41 mins",
duration: "44 mins",
distance: "34.3 mi",
@@ -527,7 +527,7 @@ export const demoEntitiesArsaboo: DemoConfig["entities"] = (localize) =>
origin_addresses: ["XYZ"],
status: "OK",
mode: "driving",
units: "imperial",
units: "us_customary",
duration_in_traffic: "37 mins",
duration: "37 mins",
distance: "30.2 mi",

View File

@@ -1196,7 +1196,7 @@ export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
left: "15%",
},
type: "state-icon",
entity: "binary_sensor.water_leak_sensor_158d0002338651",
entity: "binary_sensor.water_leak_sensor_158d00026e26dc",
},
{
prefix: "Kitchen: ",
@@ -1206,7 +1206,7 @@ export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
top: "89%",
left: "32%",
},
entity: "binary_sensor.water_leak_sensor_158d0002338651",
entity: "binary_sensor.water_leak_sensor_158d00026e26dc",
},
{
style: {
@@ -1215,7 +1215,7 @@ export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
left: "60%",
},
type: "state-icon",
entity: "binary_sensor.water_leak_sensor_158d00026e26dc",
entity: "binary_sensor.water_leak_sensor_158d0002338651",
},
{
prefix: "Bathroom: ",
@@ -1225,7 +1225,7 @@ export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
top: "89%",
left: "77%",
},
entity: "binary_sensor.water_leak_sensor_158d00026e26dc",
entity: "binary_sensor.water_leak_sensor_158d0002338651",
},
],
type: "picture-elements",

View File

@@ -138,7 +138,7 @@ if (!window.cardTools) {
return cardTools.createThing("row", config);
const domain = config.entity.split(".", 1)[0];
Object.assign(config, { type: DEFAULT_ROWS[domain] || "text" });
Object.assign(config, { type: DEFAULT_ROWS[domain] || "simple" });
return cardTools.createThing("entity-row", config);
};

View File

@@ -20,6 +20,7 @@ import { mockHistory } from "./stubs/history";
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 { mockSystemLog } from "./stubs/system_log";
import { mockTemplate } from "./stubs/template";
@@ -45,6 +46,7 @@ class HaDemo extends HomeAssistantAppEl {
mockAuth(hass);
mockTranslations(hass);
mockHistory(hass);
mockRecorder(hass);
mockShoppingList(hass);
mockSystemLog(hass);
mockTemplate(hass);
@@ -61,12 +63,14 @@ class HaDemo extends HomeAssistantAppEl {
area_id: null,
disabled_by: null,
entity_id: "sensor.co2_intensity",
id: "sensor.co2_intensity",
name: null,
icon: null,
platform: "co2signal",
hidden_by: null,
entity_category: null,
has_entity_name: false,
unique_id: "co2_intensity",
},
{
config_entry_id: "co2signal",
@@ -74,12 +78,14 @@ class HaDemo extends HomeAssistantAppEl {
area_id: null,
disabled_by: null,
entity_id: "sensor.grid_fossil_fuel_percentage",
id: "sensor.co2_intensity",
name: null,
icon: null,
platform: "co2signal",
hidden_by: null,
entity_category: null,
has_entity_name: false,
unique_id: "grid_fossil_fuel_percentage",
},
]);
@@ -116,3 +122,9 @@ class HaDemo extends HomeAssistantAppEl {
}
customElements.define("ha-demo", HaDemo);
declare global {
interface HTMLElementTagNameMap {
"ha-demo": HaDemo;
}
}

View File

@@ -1,90 +1,101 @@
import { format, startOfToday, startOfTomorrow } from "date-fns/esm";
import { EnergySolarForecasts } from "../../../src/data/energy";
import {
EnergyInfo,
EnergyPreferences,
EnergySolarForecasts,
FossilEnergyConsumption,
} from "../../../src/data/energy";
import { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
export const mockEnergy = (hass: MockHomeAssistant) => {
hass.mockWS("energy/get_prefs", () => ({
energy_sources: [
{
type: "grid",
flow_from: [
{
stat_energy_from: "sensor.energy_consumption_tarif_1",
stat_cost: "sensor.energy_consumption_tarif_1_cost",
entity_energy_from: "sensor.energy_consumption_tarif_1",
entity_energy_price: null,
number_energy_price: null,
},
{
stat_energy_from: "sensor.energy_consumption_tarif_2",
stat_cost: "sensor.energy_consumption_tarif_2_cost",
entity_energy_from: "sensor.energy_consumption_tarif_2",
entity_energy_price: null,
number_energy_price: null,
},
],
flow_to: [
{
stat_energy_to: "sensor.energy_production_tarif_1",
stat_compensation: "sensor.energy_production_tarif_1_compensation",
entity_energy_to: "sensor.energy_production_tarif_1",
entity_energy_price: null,
number_energy_price: null,
},
{
stat_energy_to: "sensor.energy_production_tarif_2",
stat_compensation: "sensor.energy_production_tarif_2_compensation",
entity_energy_to: "sensor.energy_production_tarif_2",
entity_energy_price: null,
number_energy_price: null,
},
],
cost_adjustment_day: 0,
},
{
type: "solar",
stat_energy_from: "sensor.solar_production",
config_entry_solar_forecast: ["solar_forecast"],
},
/* {
type: "battery",
stat_energy_from: "sensor.battery_output",
stat_energy_to: "sensor.battery_input",
}, */
{
type: "gas",
stat_energy_from: "sensor.energy_gas",
stat_cost: "sensor.energy_gas_cost",
entity_energy_from: "sensor.energy_gas",
entity_energy_price: null,
number_energy_price: null,
},
],
device_consumption: [
{
stat_consumption: "sensor.energy_car",
},
{
stat_consumption: "sensor.energy_ac",
},
{
stat_consumption: "sensor.energy_washing_machine",
},
{
stat_consumption: "sensor.energy_dryer",
},
{
stat_consumption: "sensor.energy_heat_pump",
},
{
stat_consumption: "sensor.energy_boiler",
},
],
}));
hass.mockWS("energy/info", () => ({ cost_sensors: [] }));
hass.mockWS("energy/fossil_energy_consumption", ({ period }) => ({
start: period === "month" ? 250 : period === "day" ? 10 : 2,
}));
hass.mockWS(
"energy/get_prefs",
(): EnergyPreferences => ({
energy_sources: [
{
type: "grid",
flow_from: [
{
stat_energy_from: "sensor.energy_consumption_tarif_1",
stat_cost: "sensor.energy_consumption_tarif_1_cost",
entity_energy_price: null,
number_energy_price: null,
},
{
stat_energy_from: "sensor.energy_consumption_tarif_2",
stat_cost: "sensor.energy_consumption_tarif_2_cost",
entity_energy_price: null,
number_energy_price: null,
},
],
flow_to: [
{
stat_energy_to: "sensor.energy_production_tarif_1",
stat_compensation:
"sensor.energy_production_tarif_1_compensation",
entity_energy_price: null,
number_energy_price: null,
},
{
stat_energy_to: "sensor.energy_production_tarif_2",
stat_compensation:
"sensor.energy_production_tarif_2_compensation",
entity_energy_price: null,
number_energy_price: null,
},
],
cost_adjustment_day: 0,
},
{
type: "solar",
stat_energy_from: "sensor.solar_production",
config_entry_solar_forecast: ["solar_forecast"],
},
/* {
type: "battery",
stat_energy_from: "sensor.battery_output",
stat_energy_to: "sensor.battery_input",
}, */
{
type: "gas",
stat_energy_from: "sensor.energy_gas",
stat_cost: "sensor.energy_gas_cost",
entity_energy_price: null,
number_energy_price: null,
},
],
device_consumption: [
{
stat_consumption: "sensor.energy_car",
},
{
stat_consumption: "sensor.energy_ac",
},
{
stat_consumption: "sensor.energy_washing_machine",
},
{
stat_consumption: "sensor.energy_dryer",
},
{
stat_consumption: "sensor.energy_heat_pump",
},
{
stat_consumption: "sensor.energy_boiler",
},
],
})
);
hass.mockWS(
"energy/info",
(): EnergyInfo => ({ cost_sensors: {}, solar_forecast_domains: [] })
);
hass.mockWS(
"energy/fossil_energy_consumption",
({ period }): FossilEnergyConsumption => ({
start: period === "month" ? 250 : period === "day" ? 10 : 2,
})
);
const todayString = format(startOfToday(), "yyyy-MM-dd");
const tomorrowString = format(startOfTomorrow(), "yyyy-MM-dd");
hass.mockWS(

View File

@@ -1,12 +1,4 @@
import {
addDays,
addHours,
addMonths,
differenceInHours,
endOfDay,
} from "date-fns/esm";
import { HassEntity } from "home-assistant-js-websocket";
import { StatisticValue } from "../../../src/data/history";
import { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
interface HistoryQueryParams {
@@ -72,331 +64,6 @@ const generateHistory = (state, deltas) => {
const incrementalUnits = ["clients", "queries", "ads"];
const generateMeanStatistics = (
id: string,
start: Date,
end: Date,
period: "5minute" | "hour" | "day" | "month" = "hour",
initValue: number,
maxDiff: number
) => {
const statistics: StatisticValue[] = [];
let currentDate = new Date(start);
currentDate.setMinutes(0, 0, 0);
let lastVal = initValue;
const now = new Date();
while (end > currentDate && currentDate < now) {
const delta = Math.random() * maxDiff;
const mean = lastVal + delta;
statistics.push({
statistic_id: id,
start: currentDate.toISOString(),
end: currentDate.toISOString(),
mean,
min: mean - Math.random() * maxDiff,
max: mean + Math.random() * maxDiff,
last_reset: "1970-01-01T00:00:00+00:00",
state: mean,
sum: null,
});
lastVal = mean;
currentDate =
period === "day"
? addDays(currentDate, 1)
: period === "month"
? addMonths(currentDate, 1)
: addHours(currentDate, 1);
}
return statistics;
};
const generateSumStatistics = (
id: string,
start: Date,
end: Date,
period: "5minute" | "hour" | "day" | "month" = "hour",
initValue: number,
maxDiff: number
) => {
const statistics: StatisticValue[] = [];
let currentDate = new Date(start);
currentDate.setMinutes(0, 0, 0);
let sum = initValue;
const now = new Date();
while (end > currentDate && currentDate < now) {
const add = Math.random() * maxDiff;
sum += add;
statistics.push({
statistic_id: id,
start: currentDate.toISOString(),
end: currentDate.toISOString(),
mean: null,
min: null,
max: null,
last_reset: "1970-01-01T00:00:00+00:00",
state: initValue + sum,
sum,
});
currentDate =
period === "day"
? addDays(currentDate, 1)
: period === "month"
? addMonths(currentDate, 1)
: addHours(currentDate, 1);
}
return statistics;
};
const generateCurvedStatistics = (
id: string,
start: Date,
end: Date,
_period: "5minute" | "hour" | "day" | "month" = "hour",
initValue: number,
maxDiff: number,
metered: boolean
) => {
const statistics: StatisticValue[] = [];
let currentDate = new Date(start);
currentDate.setMinutes(0, 0, 0);
let sum = initValue;
const hours = differenceInHours(end, start) - 1;
let i = 0;
let half = false;
const now = new Date();
while (end > currentDate && currentDate < now) {
const add = Math.random() * maxDiff;
sum += i * add;
statistics.push({
statistic_id: id,
start: currentDate.toISOString(),
end: currentDate.toISOString(),
mean: null,
min: null,
max: null,
last_reset: "1970-01-01T00:00:00+00:00",
state: initValue + sum,
sum: metered ? sum : null,
});
currentDate = addHours(currentDate, 1);
if (!half && i > hours / 2) {
half = true;
}
i += half ? -1 : 1;
}
return statistics;
};
const statisticsFunctions: Record<
string,
(
id: string,
start: Date,
end: Date,
period: "5minute" | "hour" | "day" | "month"
) => StatisticValue[]
> = {
"sensor.energy_consumption_tarif_1": (
id: string,
start: Date,
end: Date,
period = "hour"
) => {
if (period !== "hour") {
return generateSumStatistics(
id,
start,
end,
period,
0,
period === "day" ? 17 : 504
);
}
const morningEnd = new Date(start.getTime() + 10 * 60 * 60 * 1000);
const morningLow = generateSumStatistics(
id,
start,
morningEnd,
period,
0,
0.7
);
const eveningStart = new Date(start.getTime() + 20 * 60 * 60 * 1000);
const morningFinalVal = morningLow.length
? morningLow[morningLow.length - 1].sum!
: 0;
const empty = generateSumStatistics(
id,
morningEnd,
eveningStart,
period,
morningFinalVal,
0
);
const eveningLow = generateSumStatistics(
id,
eveningStart,
end,
period,
morningFinalVal,
0.7
);
return [...morningLow, ...empty, ...eveningLow];
},
"sensor.energy_consumption_tarif_2": (
id: string,
start: Date,
end: Date,
period = "hour"
) => {
if (period !== "hour") {
return generateSumStatistics(
id,
start,
end,
period,
0,
period === "day" ? 17 : 504
);
}
const morningEnd = new Date(start.getTime() + 9 * 60 * 60 * 1000);
const eveningStart = new Date(start.getTime() + 20 * 60 * 60 * 1000);
const highTarif = generateSumStatistics(
id,
morningEnd,
eveningStart,
period,
0,
0.3
);
const highTarifFinalVal = highTarif.length
? highTarif[highTarif.length - 1].sum!
: 0;
const morning = generateSumStatistics(id, start, morningEnd, period, 0, 0);
const evening = generateSumStatistics(
id,
eveningStart,
end,
period,
highTarifFinalVal,
0
);
return [...morning, ...highTarif, ...evening];
},
"sensor.energy_production_tarif_1": (id, start, end, period = "hour") =>
generateSumStatistics(id, start, end, period, 0, 0),
"sensor.energy_production_tarif_1_compensation": (
id,
start,
end,
period = "hour"
) => generateSumStatistics(id, start, end, period, 0, 0),
"sensor.energy_production_tarif_2": (id, start, end, period = "hour") => {
if (period !== "hour") {
return generateSumStatistics(
id,
start,
end,
period,
0,
period === "day" ? 17 : 504
);
}
const productionStart = new Date(start.getTime() + 9 * 60 * 60 * 1000);
const productionEnd = new Date(start.getTime() + 21 * 60 * 60 * 1000);
const dayEnd = new Date(endOfDay(productionEnd));
const production = generateCurvedStatistics(
id,
productionStart,
productionEnd,
period,
0,
0.15,
true
);
const productionFinalVal = production.length
? production[production.length - 1].sum!
: 0;
const morning = generateSumStatistics(
id,
start,
productionStart,
period,
0,
0
);
const evening = generateSumStatistics(
id,
productionEnd,
dayEnd,
period,
productionFinalVal,
0
);
const rest = generateSumStatistics(
id,
dayEnd,
end,
period,
productionFinalVal,
1
);
return [...morning, ...production, ...evening, ...rest];
},
"sensor.solar_production": (id, start, end, period = "hour") => {
if (period !== "hour") {
return generateSumStatistics(
id,
start,
end,
period,
0,
period === "day" ? 17 : 504
);
}
const productionStart = new Date(start.getTime() + 7 * 60 * 60 * 1000);
const productionEnd = new Date(start.getTime() + 23 * 60 * 60 * 1000);
const dayEnd = new Date(endOfDay(productionEnd));
const production = generateCurvedStatistics(
id,
productionStart,
productionEnd,
period,
0,
0.3,
true
);
const productionFinalVal = production.length
? production[production.length - 1].sum!
: 0;
const morning = generateSumStatistics(
id,
start,
productionStart,
period,
0,
0
);
const evening = generateSumStatistics(
id,
productionEnd,
dayEnd,
period,
productionFinalVal,
0
);
const rest = generateSumStatistics(
id,
dayEnd,
end,
period,
productionFinalVal,
2
);
return [...morning, ...production, ...evening, ...rest];
},
};
export const mockHistory = (mockHass: MockHomeAssistant) => {
mockHass.mockAPI(
new RegExp("history/period/.+"),
@@ -466,43 +133,4 @@ export const mockHistory = (mockHass: MockHomeAssistant) => {
return results;
}
);
mockHass.mockWS("recorder/get_statistics_metadata", () => []);
mockHass.mockWS("history/list_statistic_ids", () => []);
mockHass.mockWS(
"history/statistics_during_period",
({ statistic_ids, start_time, end_time, period }, hass) => {
const start = new Date(start_time);
const end = end_time ? new Date(end_time) : new Date();
const statistics: Record<string, StatisticValue[]> = {};
statistic_ids.forEach((id: string) => {
if (id in statisticsFunctions) {
statistics[id] = statisticsFunctions[id](id, start, end, period);
} else {
const entityState = hass.states[id];
const state = entityState ? Number(entityState.state) : 1;
statistics[id] =
entityState && "last_reset" in entityState.attributes
? generateSumStatistics(
id,
start,
end,
period,
state,
state * (state > 80 ? 0.01 : 0.05)
)
: generateMeanStatistics(
id,
start,
end,
period,
state,
state * (state > 80 ? 0.05 : 0.1)
);
}
});
return statistics;
}
);
};

342
demo/src/stubs/recorder.ts Normal file
View File

@@ -0,0 +1,342 @@
import {
addDays,
addHours,
addMonths,
differenceInHours,
endOfDay,
} from "date-fns";
import {
Statistics,
StatisticsMetaData,
StatisticValue,
} from "../../../src/data/recorder";
import { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
const generateMeanStatistics = (
start: Date,
end: Date,
period: "5minute" | "hour" | "day" | "month" = "hour",
initValue: number,
maxDiff: number
): StatisticValue[] => {
const statistics: StatisticValue[] = [];
let currentDate = new Date(start);
currentDate.setMinutes(0, 0, 0);
let lastVal = initValue;
const now = new Date();
while (end > currentDate && currentDate < now) {
const delta = Math.random() * maxDiff;
const mean = lastVal + delta;
statistics.push({
start: currentDate.getTime(),
end: currentDate.getTime(),
mean,
min: mean - Math.random() * maxDiff,
max: mean + Math.random() * maxDiff,
last_reset: 0,
state: mean,
sum: null,
});
lastVal = mean;
currentDate =
period === "day"
? addDays(currentDate, 1)
: period === "month"
? addMonths(currentDate, 1)
: addHours(currentDate, 1);
}
return statistics;
};
const generateSumStatistics = (
start: Date,
end: Date,
period: "5minute" | "hour" | "day" | "month" = "hour",
initValue: number,
maxDiff: number
): StatisticValue[] => {
const statistics: StatisticValue[] = [];
let currentDate = new Date(start);
currentDate.setMinutes(0, 0, 0);
let sum = initValue;
const now = new Date();
while (end > currentDate && currentDate < now) {
const add = Math.random() * maxDiff;
sum += add;
statistics.push({
start: currentDate.getTime(),
end: currentDate.getTime(),
mean: null,
min: null,
max: null,
last_reset: 0,
state: initValue + sum,
sum,
});
currentDate =
period === "day"
? addDays(currentDate, 1)
: period === "month"
? addMonths(currentDate, 1)
: addHours(currentDate, 1);
}
return statistics;
};
const generateCurvedStatistics = (
start: Date,
end: Date,
_period: "5minute" | "hour" | "day" | "month" = "hour",
initValue: number,
maxDiff: number,
metered: boolean
): StatisticValue[] => {
const statistics: StatisticValue[] = [];
let currentDate = new Date(start);
currentDate.setMinutes(0, 0, 0);
let sum = initValue;
const hours = differenceInHours(end, start) - 1;
let i = 0;
let half = false;
const now = new Date();
while (end > currentDate && currentDate < now) {
const add = Math.random() * maxDiff;
sum += i * add;
statistics.push({
start: currentDate.getTime(),
end: currentDate.getTime(),
mean: null,
min: null,
max: null,
last_reset: 0,
state: initValue + sum,
sum: metered ? sum : null,
});
currentDate = addHours(currentDate, 1);
if (!half && i > hours / 2) {
half = true;
}
i += half ? -1 : 1;
}
return statistics;
};
const statisticsFunctions: Record<
string,
(
id: string,
start: Date,
end: Date,
period: "5minute" | "hour" | "day" | "month"
) => StatisticValue[]
> = {
"sensor.energy_consumption_tarif_1": (
_id: string,
start: Date,
end: Date,
period = "hour"
) => {
if (period !== "hour") {
return generateSumStatistics(
start,
end,
period,
0,
period === "day" ? 17 : 504
);
}
const morningEnd = new Date(start.getTime() + 10 * 60 * 60 * 1000);
const morningLow = generateSumStatistics(start, morningEnd, period, 0, 0.7);
const eveningStart = new Date(start.getTime() + 20 * 60 * 60 * 1000);
const morningFinalVal = morningLow.length
? morningLow[morningLow.length - 1].sum!
: 0;
const empty = generateSumStatistics(
morningEnd,
eveningStart,
period,
morningFinalVal,
0
);
const eveningLow = generateSumStatistics(
eveningStart,
end,
period,
morningFinalVal,
0.7
);
return [...morningLow, ...empty, ...eveningLow];
},
"sensor.energy_consumption_tarif_2": (
_id: string,
start: Date,
end: Date,
period = "hour"
) => {
if (period !== "hour") {
return generateSumStatistics(
start,
end,
period,
0,
period === "day" ? 17 : 504
);
}
const morningEnd = new Date(start.getTime() + 9 * 60 * 60 * 1000);
const eveningStart = new Date(start.getTime() + 20 * 60 * 60 * 1000);
const highTarif = generateSumStatistics(
morningEnd,
eveningStart,
period,
0,
0.3
);
const highTarifFinalVal = highTarif.length
? highTarif[highTarif.length - 1].sum!
: 0;
const morning = generateSumStatistics(start, morningEnd, period, 0, 0);
const evening = generateSumStatistics(
eveningStart,
end,
period,
highTarifFinalVal,
0
);
return [...morning, ...highTarif, ...evening];
},
"sensor.energy_production_tarif_1": (_id, start, end, period = "hour") =>
generateSumStatistics(start, end, period, 0, 0),
"sensor.energy_production_tarif_1_compensation": (
_id,
start,
end,
period = "hour"
) => generateSumStatistics(start, end, period, 0, 0),
"sensor.energy_production_tarif_2": (_id, start, end, period = "hour") => {
if (period !== "hour") {
return generateSumStatistics(
start,
end,
period,
0,
period === "day" ? 17 : 504
);
}
const productionStart = new Date(start.getTime() + 9 * 60 * 60 * 1000);
const productionEnd = new Date(start.getTime() + 21 * 60 * 60 * 1000);
const dayEnd = new Date(endOfDay(productionEnd));
const production = generateCurvedStatistics(
productionStart,
productionEnd,
period,
0,
0.15,
true
);
const productionFinalVal = production.length
? production[production.length - 1].sum!
: 0;
const morning = generateSumStatistics(start, productionStart, period, 0, 0);
const evening = generateSumStatistics(
productionEnd,
dayEnd,
period,
productionFinalVal,
0
);
const rest = generateSumStatistics(
dayEnd,
end,
period,
productionFinalVal,
1
);
return [...morning, ...production, ...evening, ...rest];
},
"sensor.solar_production": (_id, start, end, period = "hour") => {
if (period !== "hour") {
return generateSumStatistics(
start,
end,
period,
0,
period === "day" ? 17 : 504
);
}
const productionStart = new Date(start.getTime() + 7 * 60 * 60 * 1000);
const productionEnd = new Date(start.getTime() + 23 * 60 * 60 * 1000);
const dayEnd = new Date(endOfDay(productionEnd));
const production = generateCurvedStatistics(
productionStart,
productionEnd,
period,
0,
0.3,
true
);
const productionFinalVal = production.length
? production[production.length - 1].sum!
: 0;
const morning = generateSumStatistics(start, productionStart, period, 0, 0);
const evening = generateSumStatistics(
productionEnd,
dayEnd,
period,
productionFinalVal,
0
);
const rest = generateSumStatistics(
dayEnd,
end,
period,
productionFinalVal,
2
);
return [...morning, ...production, ...evening, ...rest];
},
};
export const mockRecorder = (mockHass: MockHomeAssistant) => {
mockHass.mockWS(
"recorder/get_statistics_metadata",
(): StatisticsMetaData[] => []
);
mockHass.mockWS(
"recorder/list_statistic_ids",
(): StatisticsMetaData[] => []
);
mockHass.mockWS(
"recorder/statistics_during_period",
({ statistic_ids, start_time, end_time, period }, hass): Statistics => {
const start = new Date(start_time);
const end = end_time ? new Date(end_time) : new Date();
const statistics: Record<string, StatisticValue[]> = {};
statistic_ids.forEach((id: string) => {
if (id in statisticsFunctions) {
statistics[id] = statisticsFunctions[id](id, start, end, period);
} else {
const entityState = hass.states[id];
const state = entityState ? Number(entityState.state) : 1;
statistics[id] =
entityState && "last_reset" in entityState.attributes
? generateSumStatistics(
start,
end,
period,
state,
state * (state > 80 ? 0.01 : 0.05)
)
: generateMeanStatistics(
start,
end,
period,
state,
state * (state > 80 ? 0.05 : 0.1)
);
}
});
return statistics;
}
);
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -1,35 +0,0 @@
#!/bin/bash
TARGET_LABEL="needs design preview"
if [[ "$NETLIFY" != "true" ]]; then
echo "This script can only be run on Netlify"
exit 1
fi
function createStatus() {
state="$1"
description="$2"
target_url="$3"
curl -X POST -H "Accept: application/vnd.github.v3+json" -H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/home-assistant/frontend/statuses/$COMMIT_REF" \
-d '{"state": "'"${state}"'", "context": "Netlify/Design Preview Build", "description": "'"$description"'", "target_url": "'"$target_url"'"}'
}
if [[ "${PULL_REQUEST}" == "true" ]]; then
if [[ "$(curl -sSLf -H "Accept: application/vnd.github.v3+json" -H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/home-assistant/frontend/pulls/${REVIEW_ID}" | jq '.labels[].name' -r)" =~ "$TARGET_LABEL" ]]; then
createStatus "pending" "Building design preview" "https://app.netlify.com/sites/home-assistant-gallery/deploys/$BUILD_ID"
gulp build-gallery
if [ $? -eq 0 ]; then
createStatus "success" "Build complete" "$DEPLOY_PRIME_URL"
else
createStatus "error" "Build failed" "https://app.netlify.com/sites/home-assistant-gallery/deploys/$BUILD_ID"
fi
else
createStatus "success" "Build was not requested by PR label"
fi
elif [[ "$INCOMING_HOOK_BODY" == "NIGHTLY" ]]; then
gulp build-gallery
fi

View File

@@ -0,0 +1,56 @@
---
title: When to use remove, delete, add and create
subtitle: The difference between remove/delete and add/create.
---
# Remove vs Delete
Remove and Delete are quite similar, but can be frustrating if used inconsistently.
## Remove
Take away and set aside, but kept in existence.
For example:
* Removing a user's permission
* Removing a user from a group
* Removing links between items
* Removing a widget
* Removing a link
* Removing an item from a cart
## Delete
Erase, rendered nonexistent or nonrecoverable.
For example:
* Deleting a field
* Deleting a value in a field
* Deleting a task
* Deleting a group
* Deleting a permission
* Deleting a calendar event
# Add vs Create
In most cases, Create can be paired with Delete, and Add can be paired with Remove.
## Add
An already-exisiting item.
For example:
* Adding a permission to a user
* Adding a user to a group
* Adding links between items
* Adding a widget
* Adding a link
* Adding an item to a cart
## Create
Something made from scratch.
For example:
* Creating a new field
* Creating a new value in a field
* Creating a new task
* Creating a new group
* Creating a new permission
* Creating a new calendar event
Based on this is [UX magazine article](https://uxmag.com/articles/ui-copy-remove-vs-delete2-banner).

View File

@@ -36,6 +36,7 @@ const conditions = [
{ condition: "sun", after: "sunset" },
{ condition: "sun", after: "sunrise", offset: "-01:00" },
{ condition: "zone", entity_id: "device_tracker.person", zone: "zone.home" },
{ condition: "trigger", id: "motion" },
{ condition: "time" },
{ condition: "template" },
];

View File

@@ -1,5 +1,5 @@
/* eslint-disable lit/no-template-arrow */
import { LitElement, TemplateResult, html } from "lit";
import { LitElement, TemplateResult, html, css } from "lit";
import { customElement, state } from "lit/decorators";
import { provideHass } from "../../../../src/fake_data/provide_hass";
import type { HomeAssistant } from "../../../../src/types";
@@ -47,6 +47,8 @@ const SCHEMAS: { name: string; actions: Action[] }[] = [
class DemoHaAutomationEditorAction extends LitElement {
@state() private hass!: HomeAssistant;
@state() private _disabled = false;
private data: any = SCHEMAS.map((info) => info.actions);
constructor() {
@@ -67,6 +69,15 @@ class DemoHaAutomationEditorAction extends LitElement {
this.requestUpdate();
};
return html`
<div class="options">
<ha-formfield label="Disabled">
<ha-switch
.name=${"disabled"}
.checked=${this._disabled}
@change=${this._handleOptionChange}
></ha-switch>
</ha-formfield>
</div>
${SCHEMAS.map(
(info, sampleIdx) => html`
<demo-black-white-row
@@ -81,6 +92,7 @@ class DemoHaAutomationEditorAction extends LitElement {
.hass=${this.hass}
.actions=${this.data[sampleIdx]}
.sampleIdx=${sampleIdx}
.disabled=${this._disabled}
@value-changed=${valueChanged}
></ha-automation-action>
`
@@ -90,6 +102,20 @@ class DemoHaAutomationEditorAction extends LitElement {
)}
`;
}
private _handleOptionChange(ev) {
this[`_${ev.target.name}`] = ev.target.checked;
}
static styles = css`
.options {
max-width: 800px;
margin: 16px auto;
}
.options ha-formfield {
margin-right: 16px;
}
`;
}
declare global {

View File

@@ -1,5 +1,5 @@
/* eslint-disable lit/no-template-arrow */
import { LitElement, TemplateResult, html } from "lit";
import { LitElement, TemplateResult, html, css } from "lit";
import { customElement, state } from "lit/decorators";
import { provideHass } from "../../../../src/fake_data/provide_hass";
import type { HomeAssistant } from "../../../../src/types";
@@ -83,6 +83,8 @@ const SCHEMAS: { name: string; conditions: ConditionWithShorthand[] }[] = [
class DemoHaAutomationEditorCondition extends LitElement {
@state() private hass!: HomeAssistant;
@state() private _disabled = false;
private data: any = SCHEMAS.map((info) => info.conditions);
constructor() {
@@ -103,6 +105,15 @@ class DemoHaAutomationEditorCondition extends LitElement {
this.requestUpdate();
};
return html`
<div class="options">
<ha-formfield label="Disabled">
<ha-switch
.name=${"disabled"}
.checked=${this._disabled}
@change=${this._handleOptionChange}
></ha-switch>
</ha-formfield>
</div>
${SCHEMAS.map(
(info, sampleIdx) => html`
<demo-black-white-row
@@ -117,6 +128,7 @@ class DemoHaAutomationEditorCondition extends LitElement {
.hass=${this.hass}
.conditions=${this.data[sampleIdx]}
.sampleIdx=${sampleIdx}
.disabled=${this._disabled}
@value-changed=${valueChanged}
></ha-automation-condition>
`
@@ -126,6 +138,20 @@ class DemoHaAutomationEditorCondition extends LitElement {
)}
`;
}
private _handleOptionChange(ev) {
this[`_${ev.target.name}`] = ev.target.checked;
}
static styles = css`
.options {
max-width: 800px;
margin: 16px auto;
}
.options ha-formfield {
margin-right: 16px;
}
`;
}
declare global {

View File

@@ -1,5 +1,5 @@
/* eslint-disable lit/no-template-arrow */
import { LitElement, TemplateResult, html } from "lit";
import { LitElement, TemplateResult, html, css } from "lit";
import { customElement, state } from "lit/decorators";
import { provideHass } from "../../../../src/fake_data/provide_hass";
import type { HomeAssistant } from "../../../../src/types";
@@ -107,6 +107,8 @@ const SCHEMAS: { name: string; triggers: Trigger[] }[] = [
class DemoHaAutomationEditorTrigger extends LitElement {
@state() private hass!: HomeAssistant;
@state() private _disabled = false;
private data: any = SCHEMAS.map((info) => info.triggers);
constructor() {
@@ -127,6 +129,15 @@ class DemoHaAutomationEditorTrigger extends LitElement {
this.requestUpdate();
};
return html`
<div class="options">
<ha-formfield label="Disabled">
<ha-switch
.name=${"disabled"}
.checked=${this._disabled}
@change=${this._handleOptionChange}
></ha-switch>
</ha-formfield>
</div>
${SCHEMAS.map(
(info, sampleIdx) => html`
<demo-black-white-row
@@ -141,6 +152,7 @@ class DemoHaAutomationEditorTrigger extends LitElement {
.hass=${this.hass}
.triggers=${this.data[sampleIdx]}
.sampleIdx=${sampleIdx}
.disabled=${this._disabled}
@value-changed=${valueChanged}
></ha-automation-trigger>
`
@@ -150,6 +162,20 @@ class DemoHaAutomationEditorTrigger extends LitElement {
)}
`;
}
private _handleOptionChange(ev) {
this[`_${ev.target.name}`] = ev.target.checked;
}
static styles = css`
.options {
max-width: 800px;
margin: 16px auto;
}
.options ha-formfield {
margin-right: 16px;
}
`;
}
declare global {

View File

@@ -2,8 +2,6 @@
title: "Logo"
---
![Using our logo](/images/using-our-logo.png)
# Using our logo
As a community, we are proud of our logo. Follow these guidelines to ensure it always looks its best. Our logo follows Google's material design spec and uses the blue interface color.

View File

@@ -1,5 +1,5 @@
---
title: Alerts
title: Alert
subtitle: An alert displays a short, important message in a way that attracts the user's attention without interrupting the user's task.
---

View File

@@ -0,0 +1,3 @@
---
title: Bar Slider
---

View File

@@ -0,0 +1,169 @@
import { css, html, LitElement, TemplateResult } from "lit";
import { customElement, state } from "lit/decorators";
import { ifDefined } from "lit/directives/if-defined";
import { repeat } from "lit/directives/repeat";
import "../../../../src/components/ha-bar-slider";
import "../../../../src/components/ha-card";
const sliders: {
id: string;
label: string;
mode?: "start" | "end" | "cursor";
class?: string;
}[] = [
{
id: "slider-start",
label: "Slider (start mode)",
mode: "start",
},
{
id: "slider-end",
label: "Slider (end mode)",
mode: "end",
},
{
id: "slider-cursor",
label: "Slider (cursor mode)",
mode: "cursor",
},
{
id: "slider-start-custom",
label: "Slider (start mode) and custom style",
mode: "start",
class: "custom",
},
{
id: "slider-end-custom",
label: "Slider (end mode) and custom style",
mode: "end",
class: "custom",
},
{
id: "slider-cursor-custom",
label: "Slider (cursor mode) and custom style",
mode: "cursor",
class: "custom",
},
];
@customElement("demo-components-ha-bar-slider")
export class DemoHaBarSlider extends LitElement {
@state() private value = 50;
@state() private sliderPosition?: number;
handleValueChanged(e: CustomEvent) {
this.value = e.detail.value as number;
}
handleSliderMoved(e: CustomEvent) {
this.sliderPosition = e.detail.value as number;
}
protected render(): TemplateResult {
return html`
<ha-card>
<div class="card-content">
<p><b>Slider values</b></p>
<table>
<tbody>
<tr>
<td>position</td>
<td>${this.sliderPosition ?? "-"}</td>
</tr>
<tr>
<td>value</td>
<td>${this.value ?? "-"}</td>
</tr>
</tbody>
</table>
</div>
</ha-card>
${repeat(sliders, (slider) => {
const { id, label, ...config } = slider;
return html`
<ha-card>
<div class="card-content">
<label id=${id}>${label}</label>
<pre>Config: ${JSON.stringify(config)}</pre>
<ha-bar-slider
.value=${this.value}
.mode=${config.mode}
class=${ifDefined(config.class)}
@value-changed=${this.handleValueChanged}
@slider-moved=${this.handleSliderMoved}
aria-labelledby=${id}
>
</ha-bar-slider>
</div>
</ha-card>
`;
})}
<ha-card>
<div class="card-content">
<p class="title"><b>Vertical</b></p>
<div class="vertical-sliders">
${repeat(sliders, (slider) => {
const { id, label, ...config } = slider;
return html`
<ha-bar-slider
.value=${this.value}
.mode=${config.mode}
vertical
class=${ifDefined(config.class)}
@value-changed=${this.handleValueChanged}
@slider-moved=${this.handleSliderMoved}
aria-label=${label}
>
</ha-bar-slider>
`;
})}
</div>
</div>
</ha-card>
`;
}
static get styles() {
return css`
ha-card {
max-width: 600px;
margin: 24px auto;
}
pre {
margin-top: 0;
margin-bottom: 8px;
}
p {
margin: 0;
}
label {
font-weight: 600;
}
.custom {
--slider-bar-color: #ffcf4c;
--slider-bar-background: #ffcf4c64;
--slider-bar-thickness: 100px;
--slider-bar-border-radius: 24px;
}
.vertical-sliders {
height: 300px;
display: flex;
flex-direction: row;
justify-content: space-between;
}
p.title {
margin-bottom: 12px;
}
.vertical-sliders > *:not(:last-child) {
margin-right: 4px;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"demo-components-ha-bar-slider": DemoHaBarSlider;
}
}

View File

@@ -0,0 +1,3 @@
---
title: Bar Switch
---

View File

@@ -0,0 +1,145 @@
import {
mdiGarage,
mdiGarageOpen,
mdiLightbulb,
mdiLightbulbOff,
} from "@mdi/js";
import { css, html, LitElement, TemplateResult } from "lit";
import { customElement, state } from "lit/decorators";
import { ifDefined } from "lit/directives/if-defined";
import { repeat } from "lit/directives/repeat";
import "../../../../src/components/ha-bar-switch";
import "../../../../src/components/ha-card";
const switches: {
id: string;
label: string;
class?: string;
reversed?: boolean;
disabled?: boolean;
}[] = [
{
id: "switch",
label: "Switch",
},
{
id: "switch-reversed",
label: "Switch Reversed",
reversed: true,
},
{
id: "switch-custom",
label: "Switch and custom style",
class: "custom",
},
{
id: "switch-disabled",
label: "Disabled Switch",
disabled: true,
},
];
@customElement("demo-components-ha-bar-switch")
export class DemoHaBarSwitch extends LitElement {
@state() private checked = false;
handleValueChanged(e: any) {
this.checked = e.target.checked as boolean;
}
protected render(): TemplateResult {
return html`
${repeat(switches, (sw) => {
const { id, label, ...config } = sw;
return html`
<ha-card>
<div class="card-content">
<label id=${id}>${label}</label>
<pre>Config: ${JSON.stringify(config)}</pre>
<ha-bar-switch
.checked=${this.checked}
class=${ifDefined(config.class)}
@change=${this.handleValueChanged}
.pathOn=${mdiLightbulb}
.pathOff=${mdiLightbulbOff}
aria-labelledby=${id}
disabled=${ifDefined(config.disabled)}
reversed=${ifDefined(config.reversed)}
>
</ha-bar-switch>
</div>
</ha-card>
`;
})}
<ha-card>
<div class="card-content">
<p class="title"><b>Vertical</b></p>
<div class="vertical-switches">
${repeat(switches, (sw) => {
const { id, label, ...config } = sw;
return html`
<ha-bar-switch
.checked=${this.checked}
vertical
class=${ifDefined(config.class)}
@change=${this.handleValueChanged}
aria-label=${label}
.pathOn=${mdiGarageOpen}
.pathOff=${mdiGarage}
disabled=${ifDefined(config.disabled)}
reversed=${ifDefined(config.reversed)}
>
</ha-bar-switch>
`;
})}
</div>
</div>
</ha-card>
`;
}
static get styles() {
return css`
ha-card {
max-width: 600px;
margin: 24px auto;
}
pre {
margin-top: 0;
margin-bottom: 8px;
}
p {
margin: 0;
}
label {
font-weight: 600;
}
.custom {
--switch-bar-color-on: var(--rgb-green-color);
--switch-bar-color-off: var(--rgb-red-color);
--switch-bar-thickness: 100px;
--switch-bar-border-radius: 24px;
--switch-bar-padding: 6px;
--mdc-icon-size: 24px;
}
.vertical-switches {
height: 300px;
display: flex;
flex-direction: row;
justify-content: space-between;
}
p.title {
margin-bottom: 12px;
}
.vertical-switches > *:not(:last-child) {
margin-right: 4px;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"demo-components-ha-bar-switch": DemoHaBarSwitch;
}
}

View File

@@ -1,3 +1,4 @@
---
title: Progress Bars
title: Bar
subtitle: Can be used to communicate progress of a task.
---

View File

@@ -1,3 +1,3 @@
---
title: Chips
title: Chip
---

View File

@@ -1,11 +1,11 @@
---
title: Dialgos
title: Dialog
subtitle: Dialogs provide important prompts in a user flow.
---
# Material Desing 3
# Material Design 3
Our dialogs are based on the latest version of Material Design. Specs and guidelines can be found on it's [website](https://m3.material.io/components/dialogs/overview).
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).
# Highlighted guidelines

View File

@@ -0,0 +1,61 @@
---
title: Gauge
---
<style>
ha-gauge {
display: block;
width: 200px;
margin-top: 15px;
margin-bottom: 50px;
}
</style>
# Gauge `<ha-gauge>`
A gauge that can be used to represent sensor data and provide visual feedback about the value and the corresponding severity (success, warning, error).
## Examples
Info color gauge
<ha-gauge value="75" style="--gauge-color: var(--info-color)"></ha-gauge>
Success color gauge
<ha-gauge value="25" style="--gauge-color: var(--success-color)" label="°C"></ha-gauge>
Warning color gauge
<ha-gauge value="50" style="--gauge-color: var(--warning-color)" label="°C"></ha-gauge>
Error color gauge
<ha-gauge value="75" style="--gauge-color: var(--error-color)" label="°C"></ha-gauge>
Gauge with background color
<ha-gauge value="75" style="--gauge-color: var(--info-color); --primary-background-color: lightgray"></ha-gauge>
## CSS variables
### Gauge
`primary-background-color`
Background color of the dial (rounded arch)
`primary-text-color`
Text color below dial (value and unit of measurement) plus needle color (if gauge is in needle mode)
#### Dial colors
`gauge-color`
Used in the coding to control what color the gauge value is rendered with, but cannot be set via theme since its value will dynamically be set (either to `info-color` or to the matching severity variable if the severity color mode is used). To control the used colors, adjust the following variables.
`success-color`
Dial color for the "green" severity level
`warning-color`
Dial color for the "yellow" severity level
`error-color`
Dial color for the "red" severity level
`info-color`
Static dial color if not in severity color mode

View File

@@ -0,0 +1 @@
import "../../../../src/components/ha-gauge";

View File

@@ -1,5 +1,5 @@
---
title: Selectors
title: Selector
---
See the website for [list of available selectors](https://www.home-assistant.io/docs/blueprint/selectors/).

View File

@@ -195,6 +195,48 @@ const SCHEMAS: {
},
},
},
select_disabled_list: {
name: "Select disabled option",
selector: {
select: {
options: [
{ label: "Option 1", value: "Option 1" },
{ label: "Option 2", value: "Option 2" },
{ label: "Option 3", value: "Option 3", disabled: true },
],
mode: "list",
},
},
},
select_disabled_multiple: {
name: "Select disabled option",
selector: {
select: {
multiple: true,
options: [
{ label: "Option 1", value: "Option 1" },
{ label: "Option 2", value: "Option 2" },
{ label: "Option 3", value: "Option 3", disabled: true },
],
mode: "list",
},
},
},
select_disabled: {
name: "Select disabled option",
selector: {
select: {
options: [
{ label: "Option 1", value: "Option 1" },
{ label: "Option 2", value: "Option 2" },
{ label: "Option 3", value: "Option 3", disabled: true },
{ label: "Option 4", value: "Option 4", disabled: true },
{ label: "Option 5", value: "Option 5", disabled: true },
{ label: "Option 6", value: "Option 6" },
],
},
},
},
select_custom: {
name: "Select (Custom)",
selector: {

View File

@@ -0,0 +1,39 @@
---
title: Switch / Toggle
---
<style>
ha-switch {
display: block;
}
</style>
# Switch `<ha-switch>`
A toggle switch can represent two states: on and off.
## Examples
Switch in on state
<ha-switch checked></ha-switch>
Switch in off state
<ha-switch></ha-switch>
Disabled switch
<ha-switch disabled></ha-switch>
## CSS variables
For the switch / toggle there are always two variables, one for the on / checked state and one for the off / unchecked state.
The track element (background rounded rectangle that the round circular handle travels on) is set to being half transparent, so the final color will also be impacted by the color behind the track.
`switch-checked-color` / `switch-unchecked-color`
Set both the color of the round handle and the track behind it. If you want to control them separately, use the variables below instead.
`switch-checked-button-color` / `switch-unchecked-button-color`
Color of the round handle
`switch-checked-track-color` / `switch-unchecked-track-color`
Color of the track behind the round handle

View File

@@ -0,0 +1 @@
import "../../../../src/components/ha-switch";

View File

@@ -1,3 +1,3 @@
---
title: Tips
title: Tip
---

View File

@@ -98,6 +98,9 @@ const ENTITIES = [
minimum: 0,
maximum: 10,
}),
getEntity("text", "message", "Hello!", {
friendly_name: "Message",
}),
getEntity("light", "unavailable", "unavailable", {
friendly_name: "Bed Light",
@@ -129,6 +132,9 @@ const ENTITIES = [
friendly_name: "Who cooks",
icon: "mdi:cheff",
}),
getEntity("text", "unavailable", "unavailable", {
friendly_name: "Message",
}),
];
const CONFIGS = [
@@ -147,6 +153,26 @@ const CONFIGS = [
- climate.ecobee
- input_number.number
- sensor.humidity
- text.message
`,
},
{
heading: "With enabled state color",
config: `
- type: entities
state_color: true
entities:
- scene.romantic_lights
- device_tracker.demo_paulus
- cover.kitchen_window
- group.kitchen
- lock.kitchen_door
- light.bed_light
- light.non_existing
- climate.ecobee
- input_number.number
- sensor.humidity
- text.message
`,
},
{
@@ -219,6 +245,7 @@ const CONFIGS = [
- climate.unavailable
- input_number.unavailable
- input_select.unavailable
- text.unavailable
`,
},
{

View File

@@ -35,11 +35,11 @@ const CONFIGS = [
`,
},
{
heading: "Without State",
heading: "With State",
config: `
- type: button
entity: light.bed_light
show_state: false
show_state: true
`,
},
{

View File

@@ -23,13 +23,12 @@ const CONFIGS = [
heading: "Basic example",
config: `
- type: gauge
title: Humidity
entity: sensor.outside_humidity
name: Outside Humidity
`,
},
{
heading: "Custom Unit of Measurement",
heading: "Custom unit of measurement",
config: `
- type: gauge
entity: sensor.outside_temperature
@@ -38,7 +37,16 @@ const CONFIGS = [
`,
},
{
heading: "Setting Severity Levels",
heading: "Rendering needle",
config: `
- type: gauge
entity: sensor.outside_humidity
name: Outside Humidity
needle: true
`,
},
{
heading: "Setting severity levels",
config: `
- type: gauge
entity: sensor.brightness
@@ -50,7 +58,7 @@ const CONFIGS = [
`,
},
{
heading: "Setting Severity Levels",
heading: "Setting severity levels",
config: `
- type: gauge
entity: sensor.brightness_medium
@@ -62,7 +70,7 @@ const CONFIGS = [
`,
},
{
heading: "Setting Severity Levels",
heading: "Setting severity levels",
config: `
- type: gauge
entity: sensor.brightness_high
@@ -74,7 +82,7 @@ const CONFIGS = [
`,
},
{
heading: "Setting Min (0) and Max (15) Values",
heading: "Setting min (0) and mx (15) values",
config: `
- type: gauge
entity: sensor.brightness
@@ -84,14 +92,14 @@ const CONFIGS = [
`,
},
{
heading: "Invalid Entity",
heading: "Invalid entity",
config: `
- type: gauge
entity: sensor.invalid_entity
`,
},
{
heading: "Non-Numeric Value",
heading: "Non-numeric value",
config: `
- type: gauge
entity: plant.bonsai

View File

@@ -62,6 +62,21 @@ const CONFIGS = [
heading: "Basic example",
config: `
- type: glance
entities:
- device_tracker.demo_paulus
- media_player.living_room
- sun.sun
- cover.kitchen_window
- light.kitchen_lights
- lock.kitchen_door
- light.ceiling_lights
`,
},
{
heading: "No state colors",
config: `
- type: glance
state_color: false
entities:
- device_tracker.demo_paulus
- media_player.living_room

View File

@@ -1,3 +1,3 @@
---
title: Grid And Stack Card
title: Grid and Stack Card
---

View File

@@ -0,0 +1,3 @@
---
title: Entity State
---

View File

@@ -0,0 +1,405 @@
import {
HassEntity,
HassEntityAttributeBase,
} from "home-assistant-js-websocket";
import { css, html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators";
import memoizeOne from "memoize-one";
import { computeDomain } from "../../../../src/common/entity/compute_domain";
import { computeStateDisplay } from "../../../../src/common/entity/compute_state_display";
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";
const SENSOR_DEVICE_CLASSES = [
"apparent_power",
"aqi",
// "battery"
"carbon_dioxide",
"carbon_monoxide",
"current",
"date",
"distance",
"duration",
"energy",
"frequency",
"gas",
"humidity",
"illuminance",
"moisture",
"monetary",
"nitrogen_dioxide",
"nitrogen_monoxide",
"nitrous_oxide",
"ozone",
"pm1",
"pm10",
"pm25",
"power_factor",
"power",
"precipitation",
"precipitation_intensity",
"pressure",
"reactive_power",
"signal_strength",
"speed",
"sulphur_dioxide",
"temperature",
"timestamp",
"volatile_organic_compounds",
"voltage",
"volume",
"water",
"weight",
"wind_speed",
];
const BINARY_SENSOR_DEVICE_CLASSES = [
"battery",
"battery_charging",
"carbon_monoxide",
"cold",
"connectivity",
"door",
"garage_door",
"gas",
"heat",
"light",
"lock",
"moisture",
"motion",
"moving",
"occupancy",
"opening",
"plug",
"power",
"presence",
"problem",
"running",
"safety",
"smoke",
"sound",
"tamper",
"update",
"vibration",
"window",
];
const ENTITIES: HassEntity[] = [
// Alarm control panel
createEntity("alarm_control_panel.disarmed", "disarmed"),
createEntity("alarm_control_panel.armed_home", "armed_home"),
createEntity("alarm_control_panel.armed_away", "armed_away"),
createEntity("alarm_control_panel.armed_night", "armed_night"),
createEntity("alarm_control_panel.armed_vacation", "armed_vacation"),
createEntity(
"alarm_control_panel.armed_custom_bypass",
"armed_custom_bypass"
),
createEntity("alarm_control_panel.pending", "pending"),
createEntity("alarm_control_panel.arming", "arming"),
createEntity("alarm_control_panel.disarming", "disarming"),
createEntity("alarm_control_panel.triggered", "triggered"),
// Alert
createEntity("alert.off", "off"),
createEntity("alert.on", "on"),
// Automation
createEntity("automation.off", "off"),
createEntity("automation.on", "on"),
// Binary Sensor
...BINARY_SENSOR_DEVICE_CLASSES.map((dc) =>
createEntity(`binary_sensor.${dc}`, "on", dc)
),
// Button
createEntity("button.restart", "unknown", "restart"),
createEntity("button.update", "unknown", "update"),
// Calendar
createEntity("calendar.off", "off"),
createEntity("calendar.on", "on"),
// Camera
createEntity("camera.idle", "idle"),
createEntity("camera.streaming", "streaming"),
// Climate
createEntity("climate.off", "off"),
createEntity("climate.heat", "heat"),
createEntity("climate.cool", "cool"),
createEntity("climate.heat_cool", "heat_cool"),
createEntity("climate.auto", "auto"),
createEntity("climate.dry", "dry"),
createEntity("climate.fan_only", "fan_only"),
createEntity("climate.auto_idle", "auto", undefined, { hvac_action: "idle" }),
createEntity("climate.auto_off", "auto", undefined, { hvac_action: "off" }),
createEntity("climate.auto_heating", "auto", undefined, {
hvac_action: "heating",
}),
createEntity("climate.auto_cooling", "auto", undefined, {
hvac_action: "cooling",
}),
createEntity("climate.auto_dry", "auto", undefined, {
hvac_action: "drying",
}),
// Cover
createEntity("cover.closing", "closing"),
createEntity("cover.closed", "closed"),
createEntity("cover.opening", "opening"),
createEntity("cover.open", "open"),
createEntity("cover.awning", "open", "awning"),
createEntity("cover.blind", "open", "blind"),
createEntity("cover.curtain", "open", "curtain"),
createEntity("cover.damper", "open", "damper"),
createEntity("cover.door", "open", "door"),
createEntity("cover.garage", "open", "garage"),
createEntity("cover.gate", "open", "gate"),
createEntity("cover.shade", "open", "shade"),
createEntity("cover.shutter", "open", "shutter"),
createEntity("cover.window", "open", "window"),
// Device tracker/person
createEntity("device_tracker.not_home", "not_home"),
createEntity("device_tracker.home", "home"),
createEntity("device_tracker.work", "work"),
createEntity("person.home", "home"),
createEntity("person.not_home", "not_home"),
createEntity("person.work", "work"),
// Fan
createEntity("fan.off", "off"),
createEntity("fan.on", "on"),
// Camera
createEntity("group.off", "off"),
createEntity("group.on", "on"),
// Humidifier
createEntity("humidifier.off", "off"),
createEntity("humidifier.on", "on"),
// Helpers
createEntity("input_boolean.off", "off"),
createEntity("input_boolean.on", "on"),
// Light
createEntity("light.off", "off"),
createEntity("light.on", "on"),
// Locks
createEntity("lock.unlocked", "unlocked"),
createEntity("lock.locked", "locked"),
createEntity("lock.locking", "locking"),
createEntity("lock.unlocking", "unlocking"),
createEntity("lock.jammed", "jammed"),
// Media Player
createEntity("media_player.off", "off"),
createEntity("media_player.on", "on"),
createEntity("media_player.idle", "idle"),
createEntity("media_player.playing", "playing"),
createEntity("media_player.paused", "paused"),
createEntity("media_player.standby", "standby"),
createEntity("media_player.buffering", "buffering"),
createEntity("media_player.tv_off", "off", "tv"),
createEntity("media_player.tv_playing", "playing", "tv"),
createEntity("media_player.tv_paused", "paused", "tv"),
createEntity("media_player.tv_standby", "standby", "tv"),
createEntity("media_player.receiver_off", "off", "receiver"),
createEntity("media_player.receiver_playing", "playing", "receiver"),
createEntity("media_player.receiver_paused", "paused", "receiver"),
createEntity("media_player.receiver_standby", "standby", "receiver"),
createEntity("media_player.speaker_off", "off", "speaker"),
createEntity("media_player.speaker_playing", "playing", "speaker"),
createEntity("media_player.speaker_paused", "paused", "speaker"),
createEntity("media_player.speaker_standby", "standby", "speaker"),
// Remote
createEntity("remote.off", "off"),
createEntity("remote.on", "on"),
// Script
createEntity("script.off", "off"),
createEntity("script.on", "on"),
// Sensor
...SENSOR_DEVICE_CLASSES.map((dc) => createEntity(`sensor.${dc}`, "10", dc)),
// Battery sensor
...[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100].map((value) =>
createEntity(`sensor.battery_${value}`, value.toString(), "battery")
),
// Siren
createEntity("siren.off", "off"),
createEntity("siren.on", "on"),
// Switch
createEntity("switch.off", "off"),
createEntity("switch.on", "on"),
createEntity("switch.outlet_off", "off", "outlet"),
createEntity("switch.outlet_on", "on", "outlet"),
createEntity("switch.switch_off", "off", "switch"),
createEntity("switch.switch_on", "on", "switch"),
// Timer
createEntity("timer.idle", "idle"),
createEntity("timer.active", "active"),
createEntity("timer.paused", "paused"),
// Vacuum
createEntity("vacuum.docked", "docked"),
createEntity("vacuum.cleaning", "cleaning"),
createEntity("vacuum.paused", "paused"),
createEntity("vacuum.idle", "idle"),
createEntity("vacuum.returning", "returning"),
createEntity("vacuum.error", "error"),
createEntity("vacuum.cleaning", "cleaning"),
createEntity("vacuum.off", "off"),
createEntity("vacuum.on", "on"),
// Update
createEntity("update.off", "off", undefined, {
installed_version: "1.0.0",
latest_version: "2.0.0",
}),
createEntity("update.on", "on", undefined, {
installed_version: "1.0.0",
latest_version: "2.0.0",
}),
createEntity("update.installing", "on", undefined, {
installed_version: "1.0.0",
latest_version: "2.0.0",
in_progress: true,
}),
createEntity("update.off", "off", "firmware", {
installed_version: "1.0.0",
latest_version: "2.0.0",
}),
createEntity("update.on", "on", "firmware", {
installed_version: "1.0.0",
latest_version: "2.0.0",
}),
];
function createEntity(
entity_id: string,
state: string,
device_class?: string,
attributes?: HassEntityAttributeBase | HassEntity["attributes"]
): HassEntity {
return {
entity_id,
state,
attributes: {
...attributes,
device_class: device_class,
},
last_changed: new Date().toString(),
last_updated: new Date().toString(),
context: {
id: "1",
parent_id: null,
user_id: null,
},
};
}
type EntityRowData = {
stateObj: HassEntity;
entity_id: string;
state: string;
device_class?: string;
domain: string;
};
function createRowData(stateObj: HassEntity): EntityRowData {
return {
stateObj,
entity_id: stateObj.entity_id,
state: stateObj.state,
device_class: stateObj.attributes.device_class,
domain: computeDomain(stateObj.entity_id),
};
}
@customElement("demo-misc-entity-state")
export class DemoEntityState extends LitElement {
@property({ attribute: false }) hass?: HomeAssistant;
private _columns = memoizeOne(
(hass: HomeAssistant): DataTableColumnContainer => {
const columns: DataTableColumnContainer<EntityRowData> = {
icon: {
title: "Icon",
template: (_, entry) => html`
<state-badge
.stateObj=${entry.stateObj}
.stateColor=${true}
></state-badge>
`,
},
entity_id: {
title: "Entity id",
width: "30%",
filterable: true,
sortable: true,
},
state: {
title: "State",
width: "20%",
sortable: true,
template: (_, entry) =>
html`${computeStateDisplay(
hass.localize,
entry.stateObj,
hass.locale,
hass.entities
)}`,
},
device_class: {
title: "Device class",
template: (dc) => html`${dc ?? "-"}`,
width: "20%",
filterable: true,
sortable: true,
},
domain: {
title: "Domain",
template: (_, entry) => html`${computeDomain(entry.entity_id)}`,
width: "20%",
filterable: true,
sortable: true,
},
};
return columns;
}
);
private _rows = memoizeOne((): EntityRowData[] =>
ENTITIES.map(createRowData)
);
protected firstUpdated(changedProps) {
super.firstUpdated(changedProps);
const hass = provideHass(this);
hass.updateTranslations(null, "en");
hass.updateTranslations("config", "en");
}
protected render(): TemplateResult {
if (!this.hass) {
return html``;
}
return html`
<ha-data-table
.hass=${this.hass}
.columns=${this._columns(this.hass)}
.data=${this._rows()}
auto-height
></ha-data-table>
`;
}
static get styles() {
return css`
.color {
display: block;
height: 20px;
width: 20px;
border-radius: 10px;
background-color: rgb(--color);
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"demo-misc-entity-state": DemoEntityState;
}
}

View File

@@ -191,10 +191,12 @@ const createEntityRegistryEntries = (
hidden_by: null,
entity_category: null,
entity_id: "binary_sensor.updater",
id: "binary_sensor.updater",
name: null,
icon: null,
platform: "updater",
has_entity_name: false,
unique_id: "updater",
},
];
@@ -281,7 +283,7 @@ export class DemoIntegrationCard extends LitElement {
.deviceRegistryEntries=${createDeviceRegistryEntries(
info.items[0]
)}
?disabled=${info.disabled}
?entryDisabled=${info.disabled}
.selectedConfigEntryId=${info.highlight}
></ha-integration-card>
`

View File

@@ -1,16 +1,7 @@
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
import { customElement, property, query } from "lit/decorators";
import "../../../../src/components/ha-card";
import {
SUPPORT_OPEN,
SUPPORT_STOP,
SUPPORT_CLOSE,
SUPPORT_SET_POSITION,
SUPPORT_OPEN_TILT,
SUPPORT_STOP_TILT,
SUPPORT_CLOSE_TILT,
SUPPORT_SET_TILT_POSITION,
} from "../../../../src/data/cover";
import { CoverEntityFeature } from "../../../../src/data/cover";
import "../../../../src/dialogs/more-info/more-info-content";
import { getEntity } from "../../../../src/fake_data/entity";
import {
@@ -22,113 +13,127 @@ import "../../components/demo-more-infos";
const ENTITIES = [
getEntity("cover", "position_buttons", "on", {
friendly_name: "Position Buttons",
supported_features: SUPPORT_OPEN + SUPPORT_STOP + SUPPORT_CLOSE,
supported_features:
CoverEntityFeature.OPEN +
CoverEntityFeature.STOP +
CoverEntityFeature.CLOSE,
}),
getEntity("cover", "position_slider_half", "on", {
friendly_name: "Position Half-Open",
supported_features:
SUPPORT_OPEN + SUPPORT_STOP + SUPPORT_CLOSE + SUPPORT_SET_POSITION,
CoverEntityFeature.OPEN +
CoverEntityFeature.STOP +
CoverEntityFeature.CLOSE +
CoverEntityFeature.SET_POSITION,
current_position: 50,
}),
getEntity("cover", "position_slider_open", "on", {
friendly_name: "Position Open",
supported_features:
SUPPORT_OPEN + SUPPORT_STOP + SUPPORT_CLOSE + SUPPORT_SET_POSITION,
CoverEntityFeature.OPEN +
CoverEntityFeature.STOP +
CoverEntityFeature.CLOSE +
CoverEntityFeature.SET_POSITION,
current_position: 100,
}),
getEntity("cover", "position_slider_closed", "on", {
friendly_name: "Position Closed",
supported_features:
SUPPORT_OPEN + SUPPORT_STOP + SUPPORT_CLOSE + SUPPORT_SET_POSITION,
CoverEntityFeature.OPEN +
CoverEntityFeature.STOP +
CoverEntityFeature.CLOSE +
CoverEntityFeature.SET_POSITION,
current_position: 0,
}),
getEntity("cover", "tilt_buttons", "on", {
friendly_name: "Tilt Buttons",
supported_features:
SUPPORT_OPEN_TILT + SUPPORT_STOP_TILT + SUPPORT_CLOSE_TILT,
CoverEntityFeature.OPEN_TILT +
CoverEntityFeature.STOP_TILT +
CoverEntityFeature.CLOSE_TILT,
}),
getEntity("cover", "tilt_slider_half", "on", {
friendly_name: "Tilt Half-Open",
supported_features:
SUPPORT_OPEN_TILT +
SUPPORT_STOP_TILT +
SUPPORT_CLOSE_TILT +
SUPPORT_SET_TILT_POSITION,
CoverEntityFeature.OPEN_TILT +
CoverEntityFeature.STOP_TILT +
CoverEntityFeature.CLOSE_TILT +
CoverEntityFeature.SET_TILT_POSITION,
current_tilt_position: 50,
}),
getEntity("cover", "tilt_slider_open", "on", {
friendly_name: "Tilt Open",
supported_features:
SUPPORT_OPEN_TILT +
SUPPORT_STOP_TILT +
SUPPORT_CLOSE_TILT +
SUPPORT_SET_TILT_POSITION,
CoverEntityFeature.OPEN_TILT +
CoverEntityFeature.STOP_TILT +
CoverEntityFeature.CLOSE_TILT +
CoverEntityFeature.SET_TILT_POSITION,
current_tilt_position: 100,
}),
getEntity("cover", "tilt_slider_closed", "on", {
friendly_name: "Tilt Closed",
supported_features:
SUPPORT_OPEN_TILT +
SUPPORT_STOP_TILT +
SUPPORT_CLOSE_TILT +
SUPPORT_SET_TILT_POSITION,
CoverEntityFeature.OPEN_TILT +
CoverEntityFeature.STOP_TILT +
CoverEntityFeature.CLOSE_TILT +
CoverEntityFeature.SET_TILT_POSITION,
current_tilt_position: 0,
}),
getEntity("cover", "position_slider_tilt_slider", "on", {
friendly_name: "Both Sliders",
supported_features:
SUPPORT_OPEN +
SUPPORT_STOP +
SUPPORT_CLOSE +
SUPPORT_SET_POSITION +
SUPPORT_OPEN_TILT +
SUPPORT_STOP_TILT +
SUPPORT_CLOSE_TILT +
SUPPORT_SET_TILT_POSITION,
CoverEntityFeature.OPEN +
CoverEntityFeature.STOP +
CoverEntityFeature.CLOSE +
CoverEntityFeature.SET_POSITION +
CoverEntityFeature.OPEN_TILT +
CoverEntityFeature.STOP_TILT +
CoverEntityFeature.CLOSE_TILT +
CoverEntityFeature.SET_TILT_POSITION,
current_position: 30,
current_tilt_position: 70,
}),
getEntity("cover", "position_tilt_slider", "on", {
friendly_name: "Position & Tilt Slider",
supported_features:
SUPPORT_OPEN +
SUPPORT_STOP +
SUPPORT_CLOSE +
SUPPORT_OPEN_TILT +
SUPPORT_STOP_TILT +
SUPPORT_CLOSE_TILT +
SUPPORT_SET_TILT_POSITION,
CoverEntityFeature.OPEN +
CoverEntityFeature.STOP +
CoverEntityFeature.CLOSE +
CoverEntityFeature.OPEN_TILT +
CoverEntityFeature.STOP_TILT +
CoverEntityFeature.CLOSE_TILT +
CoverEntityFeature.SET_TILT_POSITION,
current_tilt_position: 70,
}),
getEntity("cover", "position_slider_tilt", "on", {
friendly_name: "Position Slider & Tilt",
supported_features:
SUPPORT_OPEN +
SUPPORT_STOP +
SUPPORT_CLOSE +
SUPPORT_SET_POSITION +
SUPPORT_OPEN_TILT +
SUPPORT_STOP_TILT +
SUPPORT_CLOSE_TILT,
CoverEntityFeature.OPEN +
CoverEntityFeature.STOP +
CoverEntityFeature.CLOSE +
CoverEntityFeature.SET_POSITION +
CoverEntityFeature.OPEN_TILT +
CoverEntityFeature.STOP_TILT +
CoverEntityFeature.CLOSE_TILT,
current_position: 30,
}),
getEntity("cover", "position_slider_only_tilt_slider", "on", {
friendly_name: "Position Slider Only & Tilt Buttons",
supported_features:
SUPPORT_SET_POSITION +
SUPPORT_OPEN_TILT +
SUPPORT_STOP_TILT +
SUPPORT_CLOSE_TILT,
CoverEntityFeature.SET_POSITION +
CoverEntityFeature.OPEN_TILT +
CoverEntityFeature.STOP_TILT +
CoverEntityFeature.CLOSE_TILT,
current_position: 30,
}),
getEntity("cover", "position_slider_only_tilt", "on", {
friendly_name: "Position Slider Only & Tilt",
supported_features:
SUPPORT_SET_POSITION +
SUPPORT_OPEN_TILT +
SUPPORT_STOP_TILT +
SUPPORT_CLOSE_TILT +
SUPPORT_SET_TILT_POSITION,
CoverEntityFeature.SET_POSITION +
CoverEntityFeature.OPEN_TILT +
CoverEntityFeature.STOP_TILT +
CoverEntityFeature.CLOSE_TILT +
CoverEntityFeature.SET_TILT_POSITION,
current_position: 30,
current_tilt_position: 70,
}),

View File

@@ -0,0 +1,3 @@
---
title: Input Number
---

View File

@@ -0,0 +1,60 @@
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
import { customElement, property, query } from "lit/decorators";
import "../../../../src/components/ha-card";
import "../../../../src/dialogs/more-info/more-info-content";
import { getEntity } from "../../../../src/fake_data/entity";
import {
MockHomeAssistant,
provideHass,
} from "../../../../src/fake_data/provide_hass";
import "../../components/demo-more-infos";
const ENTITIES = [
getEntity("input_number", "box1", 0, {
friendly_name: "Box1",
min: 0,
max: 100,
step: 1,
initial: 0,
mode: "box",
unit_of_measurement: "items",
}),
getEntity("input_number", "slider1", 0, {
friendly_name: "Slider1",
min: 0,
max: 100,
step: 1,
initial: 0,
mode: "slider",
unit_of_measurement: "items",
}),
];
@customElement("demo-more-info-input-number")
class DemoMoreInfoInputNumber extends LitElement {
@property() public hass!: MockHomeAssistant;
@query("demo-more-infos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`
<demo-more-infos
.hass=${this.hass}
.entities=${ENTITIES.map((ent) => ent.entityId)}
></demo-more-infos>
`;
}
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.addEntities(ENTITIES);
}
}
declare global {
interface HTMLElementTagNameMap {
"demo-more-info-input-number": DemoMoreInfoInputNumber;
}
}

View File

@@ -1,12 +1,7 @@
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
import { customElement, property, query } from "lit/decorators";
import "../../../../src/components/ha-card";
import {
LightColorModes,
SUPPORT_EFFECT,
SUPPORT_FLASH,
SUPPORT_TRANSITION,
} from "../../../../src/data/light";
import { LightColorMode, LightEntityFeature } from "../../../../src/data/light";
import "../../../../src/dialogs/more-info/more-info-content";
import { getEntity } from "../../../../src/fake_data/entity";
import {
@@ -22,8 +17,8 @@ const ENTITIES = [
getEntity("light", "kitchen_light", "on", {
friendly_name: "Brightness Light",
brightness: 200,
supported_color_modes: [LightColorModes.BRIGHTNESS],
color_mode: LightColorModes.BRIGHTNESS,
supported_color_modes: [LightColorMode.BRIGHTNESS],
color_mode: LightColorMode.BRIGHTNESS,
}),
getEntity("light", "color_temperature_light", "on", {
friendly_name: "White Color Temperature Light",
@@ -32,10 +27,10 @@ const ENTITIES = [
min_mireds: 30,
max_mireds: 150,
supported_color_modes: [
LightColorModes.BRIGHTNESS,
LightColorModes.COLOR_TEMP,
LightColorMode.BRIGHTNESS,
LightColorMode.COLOR_TEMP,
],
color_mode: LightColorModes.COLOR_TEMP,
color_mode: LightColorMode.COLOR_TEMP,
}),
getEntity("light", "color_hs_light", "on", {
friendly_name: "Color HS Light",
@@ -44,13 +39,16 @@ const ENTITIES = [
rgb_color: [30, 100, 255],
min_mireds: 30,
max_mireds: 150,
supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION,
supported_features:
LightEntityFeature.EFFECT +
LightEntityFeature.FLASH +
LightEntityFeature.TRANSITION,
supported_color_modes: [
LightColorModes.BRIGHTNESS,
LightColorModes.COLOR_TEMP,
LightColorModes.HS,
LightColorMode.BRIGHTNESS,
LightColorMode.COLOR_TEMP,
LightColorMode.HS,
],
color_mode: LightColorModes.HS,
color_mode: LightColorMode.HS,
effect_list: ["random", "colorloop"],
}),
getEntity("light", "color_rgb_ct_light", "on", {
@@ -59,22 +57,28 @@ const ENTITIES = [
color_temp: 75,
min_mireds: 30,
max_mireds: 150,
supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION,
supported_features:
LightEntityFeature.EFFECT +
LightEntityFeature.FLASH +
LightEntityFeature.TRANSITION,
supported_color_modes: [
LightColorModes.BRIGHTNESS,
LightColorModes.COLOR_TEMP,
LightColorModes.RGB,
LightColorMode.BRIGHTNESS,
LightColorMode.COLOR_TEMP,
LightColorMode.RGB,
],
color_mode: LightColorModes.COLOR_TEMP,
color_mode: LightColorMode.COLOR_TEMP,
effect_list: ["random", "colorloop"],
}),
getEntity("light", "color_RGB_light", "on", {
friendly_name: "Color Effects Light",
brightness: 255,
rgb_color: [30, 100, 255],
supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION,
supported_color_modes: [LightColorModes.BRIGHTNESS, LightColorModes.RGB],
color_mode: LightColorModes.RGB,
supported_features:
LightEntityFeature.EFFECT +
LightEntityFeature.FLASH +
LightEntityFeature.TRANSITION,
supported_color_modes: [LightColorMode.BRIGHTNESS, LightColorMode.RGB],
color_mode: LightColorMode.RGB,
effect_list: ["random", "colorloop"],
}),
getEntity("light", "color_rgbw_light", "on", {
@@ -83,13 +87,16 @@ const ENTITIES = [
rgbw_color: [30, 100, 255, 125],
min_mireds: 30,
max_mireds: 150,
supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION,
supported_features:
LightEntityFeature.EFFECT +
LightEntityFeature.FLASH +
LightEntityFeature.TRANSITION,
supported_color_modes: [
LightColorModes.BRIGHTNESS,
LightColorModes.COLOR_TEMP,
LightColorModes.RGBW,
LightColorMode.BRIGHTNESS,
LightColorMode.COLOR_TEMP,
LightColorMode.RGBW,
],
color_mode: LightColorModes.RGBW,
color_mode: LightColorMode.RGBW,
effect_list: ["random", "colorloop"],
}),
getEntity("light", "color_rgbww_light", "on", {
@@ -98,13 +105,16 @@ const ENTITIES = [
rgbww_color: [30, 100, 255, 125, 10],
min_mireds: 30,
max_mireds: 150,
supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION,
supported_features:
LightEntityFeature.EFFECT +
LightEntityFeature.FLASH +
LightEntityFeature.TRANSITION,
supported_color_modes: [
LightColorModes.BRIGHTNESS,
LightColorModes.COLOR_TEMP,
LightColorModes.RGBWW,
LightColorMode.BRIGHTNESS,
LightColorMode.COLOR_TEMP,
LightColorMode.RGBWW,
],
color_mode: LightColorModes.RGBWW,
color_mode: LightColorMode.RGBWW,
effect_list: ["random", "colorloop"],
}),
getEntity("light", "color_xy_light", "on", {
@@ -114,13 +124,16 @@ const ENTITIES = [
rgb_color: [30, 100, 255],
min_mireds: 30,
max_mireds: 150,
supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION,
supported_features:
LightEntityFeature.EFFECT +
LightEntityFeature.FLASH +
LightEntityFeature.TRANSITION,
supported_color_modes: [
LightColorModes.BRIGHTNESS,
LightColorModes.COLOR_TEMP,
LightColorModes.XY,
LightColorMode.BRIGHTNESS,
LightColorMode.COLOR_TEMP,
LightColorMode.XY,
],
color_mode: LightColorModes.XY,
color_mode: LightColorMode.XY,
effect_list: ["random", "colorloop"],
}),
];

View File

@@ -139,6 +139,13 @@ const ENTITIES = [
title: undefined,
friendly_name: "Installing without title",
}),
getEntity("update", "update21", "on", {
...base_attributes,
in_progress: true,
friendly_name: "Update with in_progress true and UPDATE_SUPPORT_PROGRESS",
supported_features:
base_attributes.supported_features + UPDATE_SUPPORT_PROGRESS,
}),
];
@customElement("demo-more-info-update")

0
hassio/.gitignore vendored
View File

View File

@@ -118,7 +118,7 @@ class HassioAddonRepositoryEl extends LitElement {
}
private _addonTapped(ev) {
navigate(`/hassio/addon/${ev.currentTarget.addon.slug}`);
navigate(`/hassio/addon/${ev.currentTarget.addon.slug}?store=true`);
}
static get styles(): CSSResultGroup {

View File

@@ -53,7 +53,13 @@ class HassioAddonDashboard extends LitElement {
@property({ type: Boolean }) public narrow!: boolean;
@state() _error?: string;
@state() private _error?: string;
private _backPath = new URLSearchParams(window.parent.location.search).get(
"store"
)
? "/hassio/store"
: "/hassio/dashboard";
private _computeTail = memoizeOne((route: Route) => {
const dividerPos = route.path.indexOf("/", 1);
@@ -119,6 +125,7 @@ class HassioAddonDashboard extends LitElement {
.narrow=${this.narrow}
.route=${route}
.tabs=${addonTabs}
.backPath=${this._backPath}
supervisor
>
<span slot="header">${this.addon.name}</span>

View File

@@ -1024,10 +1024,13 @@ class HassioAddonInfo extends LitElement {
button.progress = true;
const confirmed = await showConfirmationDialog(this, {
title: this.addon.name,
text: "Are you sure you want to uninstall this add-on?",
confirmText: "uninstall add-on",
dismissText: "no",
title: this.supervisor.localize("dialog.uninstall_addon.title", {
name: this.addon.name,
}),
text: this.supervisor.localize("dialog.uninstall_addon.text"),
confirmText: this.supervisor.localize("dialog.uninstall_addon.uninstall"),
dismissText: this.supervisor.localize("common.cancel"),
destructive: true,
});
if (!confirmed) {

View File

@@ -119,6 +119,7 @@ export class HassioBackups extends LitElement {
(narrow: boolean): DataTableColumnContainer => ({
name: {
title: this.supervisor.localize("backup.name"),
main: true,
sortable: true,
filterable: true,
grows: true,

View File

@@ -28,6 +28,7 @@ class HassioDashboard extends LitElement {
.hass=${this.hass}
.narrow=${this.narrow}
.route=${this.route}
back-path="/config"
.header=${this.supervisor.localize("panel.addons")}
>
<hassio-addons

View File

@@ -18,9 +18,11 @@ export const suggestAddonRestart = async (
addon: HassioAddonDetails
): Promise<void> => {
const confirmed = await showConfirmationDialog(element, {
title: supervisor.localize("common.restart_name", "name", addon.name),
title: supervisor.localize("dialog.restart_addon.title", {
name: addon.name,
}),
text: supervisor.localize("dialog.restart_addon.text"),
confirmText: supervisor.localize("dialog.restart_addon.confirm_text"),
confirmText: supervisor.localize("dialog.restart_addon.restart"),
dismissText: supervisor.localize("common.cancel"),
});
if (confirmed) {
@@ -28,11 +30,9 @@ export const suggestAddonRestart = async (
await restartHassioAddon(hass, addon.slug);
} catch (err: any) {
showAlertDialog(element, {
title: supervisor.localize(
"common.failed_to_restart_name",
"name",
addon.name
),
title: supervisor.localize("common.failed_to_restart_name", {
name: addon.name,
}),
text: extractApiErrorMessage(err),
});
}

View File

@@ -23,6 +23,7 @@ import {
showAlertDialog,
showConfirmationDialog,
} from "../../../src/dialogs/generic/show-dialog-box";
import { showJoinBetaDialog } from "../../../src/panels/config/core/updates/show-dialog-join-beta";
import {
UNHEALTHY_REASON_URL,
UNSUPPORTED_REASON_URL,
@@ -230,36 +231,27 @@ class HassioSupervisorInfo extends LitElement {
button.progress = true;
if (this.supervisor.supervisor.channel === "stable") {
const confirmed = await showConfirmationDialog(this, {
title: this.supervisor.localize("system.supervisor.warning"),
text: html`${this.supervisor.localize("system.supervisor.beta_warning")}
<br />
<b> ${this.supervisor.localize("system.supervisor.beta_backup")} </b>
<br /><br />
${this.supervisor.localize("system.supervisor.beta_release_items")}
<ul>
<li>Home Assistant Core</li>
<li>Home Assistant Supervisor</li>
<li>Home Assistant Operating System</li>
</ul>
<br />
${this.supervisor.localize("system.supervisor.beta_join_confirm")}`,
confirmText: this.supervisor.localize(
"system.supervisor.join_beta_action"
),
dismissText: this.supervisor.localize("common.cancel"),
showJoinBetaDialog(this, {
join: async () => {
await this._setChannel("beta");
button.progress = false;
},
cancel: () => {
button.progress = false;
},
});
if (!confirmed) {
button.progress = false;
return;
}
} else {
await this._setChannel("stable");
button.progress = false;
}
}
private async _setChannel(
channel: SupervisorOptions["channel"]
): Promise<void> {
try {
const data: Partial<SupervisorOptions> = {
channel:
this.supervisor.supervisor.channel === "stable" ? "beta" : "stable",
channel,
};
await setSupervisorOption(this.hass, data);
await this._reloadSupervisor();
@@ -270,8 +262,6 @@ class HassioSupervisorInfo extends LitElement {
),
text: extractApiErrorMessage(err),
});
} finally {
button.progress = false;
}
}

View File

@@ -1,11 +1,8 @@
module.exports = {
"*.{js,ts}": [
"prettier --write",
'eslint --ignore-pattern "**/build-scripts/**/*.js" --fix',
],
"*.{js,ts}": ["prettier --write", "eslint --fix"],
"!(/translations)*.{json,css,md,html}": "prettier --write",
"translations/*/*.json": (files) =>
'printf "%s\n" "These files should not be modified. Instead, make the necessary modifications in src/translations/en.json. Please see translations/README.md for details." ' +
'printf "%s\n" "Translation files should not be added or modified here. Instead, make the necessary modifications in src/translations/en.json. Other languages are managed externally. Please see https://developers.home-assistant.io/docs/translations/ for details." ' +
files.join(" ") +
" >&2 && exit 1",
};

View File

@@ -24,7 +24,7 @@
"author": "Paulus Schoutsen <Paulus@PaulusSchoutsen.nl> (http://paulusschoutsen.nl)",
"license": "Apache-2.0",
"dependencies": {
"@braintree/sanitize-url": "^5.0.2",
"@braintree/sanitize-url": "^6.0.0",
"@codemirror/autocomplete": "^0.19.12",
"@codemirror/commands": "^0.19.8",
"@codemirror/gutter": "^0.19.9",
@@ -43,7 +43,6 @@
"@formatjs/intl-numberformat": "^7.2.5",
"@formatjs/intl-pluralrules": "^4.1.5",
"@formatjs/intl-relativetimeformat": "^9.3.2",
"@formatjs/intl-utils": "^3.8.4",
"@fullcalendar/common": "5.9.0",
"@fullcalendar/core": "5.9.0",
"@fullcalendar/daygrid": "5.9.0",
@@ -93,15 +92,15 @@
"@polymer/paper-tooltip": "^3.0.1",
"@polymer/polymer": "3.4.1",
"@thomasloven/round-slider": "0.5.4",
"@vaadin/combo-box": "^23.1.5",
"@vaadin/vaadin-themable-mixin": "^23.1.5",
"@vaadin/combo-box": "^23.2.9",
"@vaadin/vaadin-themable-mixin": "^23.2.9",
"@vibrant/color": "^3.2.1-alpha.1",
"@vibrant/core": "^3.2.1-alpha.1",
"@vibrant/quantizer-mmcq": "^3.2.1-alpha.1",
"@vue/web-component-wrapper": "^1.2.0",
"@webcomponents/scoped-custom-element-registry": "^0.0.5",
"@webcomponents/webcomponentsjs": "^2.2.10",
"app-datepicker": "^5.0.1",
"app-datepicker": "^5.1.0",
"chart.js": "^3.3.2",
"comlink": "^4.3.1",
"core-js": "^3.15.2",
@@ -111,8 +110,9 @@
"deep-freeze": "^0.0.1",
"fuse.js": "^6.0.0",
"google-timezones-json": "^1.0.2",
"hls.js": "^1.2.1",
"home-assistant-js-websocket": "^8.0.0",
"hammerjs": "^2.0.8",
"hls.js": "^1.2.5",
"home-assistant-js-websocket": "^8.0.1",
"idb-keyval": "^5.1.3",
"intl-messageformat": "^9.9.1",
"js-yaml": "^4.1.0",
@@ -129,6 +129,7 @@
"regenerator-runtime": "^0.13.8",
"resize-observer-polyfill": "^1.5.1",
"roboto-fontface": "^0.10.0",
"rrule": "^2.7.1",
"sortablejs": "^1.14.0",
"superstruct": "^0.15.2",
"tinykeys": "^1.1.3",
@@ -138,6 +139,7 @@
"vis-network": "^8.5.4",
"vue": "^2.6.12",
"vue2-daterange-picker": "^0.5.1",
"weekstart": "^1.1.0",
"workbox-cacheable-response": "^6.4.2",
"workbox-core": "^6.4.2",
"workbox-expiration": "^6.4.2",
@@ -147,19 +149,21 @@
"xss": "^1.0.9"
},
"devDependencies": {
"@babel/core": "^7.15.5",
"@babel/plugin-external-helpers": "^7.14.5",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-proposal-decorators": "^7.15.4",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5",
"@babel/plugin-proposal-object-rest-spread": "^7.15.6",
"@babel/plugin-proposal-optional-chaining": "^7.14.5",
"@babel/core": "^7.20.2",
"@babel/plugin-external-helpers": "^7.18.6",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-proposal-decorators": "^7.20.2",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
"@babel/plugin-proposal-object-rest-spread": "^7.20.2",
"@babel/plugin-proposal-optional-chaining": "^7.18.9",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-import-meta": "^7.10.4",
"@babel/plugin-syntax-top-level-await": "^7.14.5",
"@babel/preset-env": "^7.15.6",
"@babel/preset-typescript": "^7.15.0",
"@babel/preset-env": "^7.20.2",
"@babel/preset-typescript": "^7.18.6",
"@koa/cors": "^3.1.0",
"@octokit/auth-oauth-device": "^4.0.2",
"@octokit/rest": "^19.0.4",
"@open-wc/dev-server-hmr": "^0.0.2",
"@rollup/plugin-babel": "^5.2.1",
"@rollup/plugin-commonjs": "^11.1.0",
@@ -169,6 +173,7 @@
"@types/chromecast-caf-receiver": "5.0.12",
"@types/chromecast-caf-sender": "^1.0.3",
"@types/glob": "^7",
"@types/hammerjs": "^2.0.41",
"@types/js-yaml": "^4",
"@types/leaflet": "^1",
"@types/leaflet-draw": "^1",
@@ -176,23 +181,23 @@
"@types/mocha": "^8",
"@types/qrcode": "^1.4.2",
"@types/sortablejs": "^1",
"@types/tar": "^6",
"@types/webspeechapi": "^0.0.29",
"@typescript-eslint/eslint-plugin": "^4.32.0",
"@typescript-eslint/parser": "^4.32.0",
"@typescript-eslint/eslint-plugin": "^5.44.0",
"@typescript-eslint/parser": "^5.44.0",
"@web/dev-server": "^0.0.24",
"@web/dev-server-rollup": "^0.2.11",
"babel-loader": "^8.2.2",
"babel-loader": "^9.1.0",
"chai": "^4.3.4",
"del": "^4.0.0",
"eslint": "^7.32.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-config-airbnb-typescript": "^14.0.0",
"eslint-config-prettier": "^8.3.0",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-webpack": "^0.13.1",
"eslint-plugin-disable": "^2.0.1",
"eslint-plugin-import": "^2.24.2",
"eslint-plugin-lit": "^1.6.1",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-unused-imports": "^1.1.5",
"eslint-plugin-wc": "^1.3.2",
"fancy-log": "^1.3.3",
@@ -207,6 +212,7 @@
"html-minifier": "^4.0.0",
"husky": "^8.0.1",
"instant-mocha": "^1.3.1",
"jszip": "^3.10.1",
"lint-staged": "^13.0.3",
"lit-analyzer": "^1.2.1",
"lodash.template": "^4.5.0",
@@ -217,7 +223,7 @@
"object-hash": "^2.0.3",
"open": "^7.0.4",
"pinst": "^3.0.0",
"prettier": "^2.4.1",
"prettier": "^2.8.1",
"require-dir": "^1.2.0",
"rollup": "^2.8.2",
"rollup-plugin-string": "^3.0.0",
@@ -227,9 +233,10 @@
"sinon": "^11.0.0",
"source-map-url": "^0.4.0",
"systemjs": "^6.3.2",
"tar": "^6.1.11",
"terser-webpack-plugin": "^5.2.4",
"ts-lit-plugin": "^1.2.1",
"typescript": "^4.4.3",
"typescript": "^4.9.3",
"vinyl-buffer": "^1.0.1",
"vinyl-source-stream": "^2.0.0",
"webpack": "^5.55.1",
@@ -253,5 +260,5 @@
"trailingComma": "es5",
"arrowParens": "always"
},
"packageManager": "yarn@3.2.0"
"packageManager": "yarn@3.2.3"
}

View File

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

View File

@@ -7,4 +7,4 @@ set -e
cd "$(dirname "$0")/.."
# Install node modules
yarn install
yarn install

View File

@@ -46,6 +46,14 @@ frontend:
# development_repo: ${WD}" >> "${WD}/config/configuration.yaml"
fi
if [ ! -z "${CODESPACES}" ]; then
echo "
http:
use_x_forwarded_for: true
trusted_proxies:
- 127.0.0.1
" >> "${WD}/config/configuration.yaml"
fi
fi
hass -c "${WD}/config"

9
script/setup_translations Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/sh
# Setup translation fetching during development
# Stop on errors
set -e
cd "$(dirname "$0")/.."
./node_modules/.bin/gulp setup-and-fetch-nightly-translations

View File

@@ -20,24 +20,28 @@ fi
# Load token from file if not already in the environment
[ -z "${LOKALISE_TOKEN-}" ] && LOKALISE_TOKEN="$(<.lokalise_token)"
PROJECT_ID="3420425759f6d6d241f598.13594006"
LOCAL_DIR="$(pwd)/translations/downloads"
FILE_FORMAT=json
declare -A PROJECT_ID=( \
[frontend]="3420425759f6d6d241f598.13594006" \
[backend]="130246255a974bd3b5e8a1.51616605" \
)
mkdir -p ${LOCAL_DIR}
docker run \
-v ${LOCAL_DIR}:/opt/dest/locale \
--rm \
lokalise/lokalise-cli-2@sha256:f1860b26be22fa73b8c93bc5f8690f2afc867610a42de6fc27adc790e5d4425d lokalise2 \
--token ${LOKALISE_TOKEN} \
--project-id ${PROJECT_ID} \
file download \
--export-empty-as skip \
--format json \
--json-unescaped-slashes=true \
--replace-breaks=false \
--original-filenames=false \
--unzip-to /opt/dest
for project in ${!PROJECT_ID[*]}; do
LOCAL_DIR=`pwd`/translations/${project}
rm -f ${LOCAL_DIR}/* || mkdir -p ${LOCAL_DIR}
docker run \
-v ${LOCAL_DIR}:/opt/dest/locale \
--rm \
lokalise/lokalise-cli-2@sha256:f1860b26be22fa73b8c93bc5f8690f2afc867610a42de6fc27adc790e5d4425d \
lokalise2 \
--token ${LOKALISE_TOKEN} \
--project-id ${PROJECT_ID[${project}]} \
file download \
--export-empty-as skip \
--format json \
--json-unescaped-slashes=true \
--replace-breaks=false \
--original-filenames=false \
--unzip-to /opt/dest
done
./node_modules/.bin/gulp check-downloaded-translations

View File

@@ -15,7 +15,7 @@ import { computeInitialHaFormData } from "../components/ha-form/compute-initial-
import "../components/ha-form/ha-form";
import "../components/ha-formfield";
import "../components/ha-markdown";
import { AuthProvider } from "../data/auth";
import { AuthProvider, autocompleteLoginFields } from "../data/auth";
import {
DataEntryFlowStep,
DataEntryFlowStepForm,
@@ -204,7 +204,7 @@ class HaAuthFlow extends litLocalizeLiteMixin(LitElement) {
: html``}
<ha-form
.data=${this._stepData}
.schema=${step.data_schema}
.schema=${autocompleteLoginFields(step.data_schema)}
.error=${step.errors}
.disabled=${this._submitting}
.computeLabel=${this._computeLabelCallback(step)}

View File

@@ -3,6 +3,7 @@ import { html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators";
import { fireEvent } from "../common/dom/fire_event";
import type { HaFormSchema } from "../components/ha-form/types";
import { autocompleteLoginFields } from "../data/auth";
import type { DataEntryFlowStep } from "../data/data_entry_flow";
declare global {
@@ -69,7 +70,9 @@ export class HaPasswordManagerPolyfill extends LitElement {
aria-hidden="true"
@submit=${this._handleSubmit}
>
${this.step.data_schema.map((input) => this.render_input(input))}
${autocompleteLoginFields(this.step.data_schema).map((input) =>
this.render_input(input)
)}
<input type="submit" />
<style>
${this.styles}
@@ -89,8 +92,10 @@ export class HaPasswordManagerPolyfill extends LitElement {
<input
tabindex="-1"
.id=${schema.name}
.name=${schema.name}
.type=${inputType}
.value=${this.stepData[schema.name] || ""}
.autocomplete=${schema.autocomplete}
@input=${this._valueChanged}
/>
`;

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