Compare commits

...
Author SHA1 Message Date
Charles GarwoodandGitHub a5c6ffd1b9 Fix Z-Wave JS Node Config Panel handling null values (#8710)
* attempt fix for null values

* cleanup
2021-03-24 14:02:45 -04:00
Thomas LovénandGitHub 9aaaaae175 Fix race condition in map card (#8697) 2021-03-24 09:49:28 +01:00
Philip AllgaierandGitHub 7d39b69540 Ensure dev-tool-states is consistently case-insensitive (#8696) 2021-03-24 09:48:04 +01:00
GitHub Action 09bad14c3d Translation update 2021-03-24 01:30:48 +00:00
Paulus Schoutsen 369c9dc6e2 Bumped version to 20210324.0 2021-03-24 00:22:11 +00:00
Paulus SchoutsenandGitHub 9676d2cee7 Add compatibility with latest trace API (#8700) 2021-03-23 17:21:57 -07:00
5156c67226 Refactor trace rendering (#8693)
Co-authored-by: Bram Kragten <[email protected]>
2021-03-23 17:06:59 +01:00
GitHub Action 4d48fc3d85 Translation update 2021-03-23 01:28:19 +00:00
Paulus Schoutsen 20da329a21 Fix types 2021-03-22 22:43:08 +00:00
Charles GarwoodandGitHub 4b664cc142 Add node config panel for Z-Wave JS (#8440) 2021-03-22 23:25:42 +01:00
Paulus Schoutsen c9b620fdb2 Update basic trace in gallery 2021-03-22 19:26:59 +00:00
25c886d401 Add an absolute height to cast receiver to fix height inheritance (#8667)
Co-authored-by: Bram Kragten <[email protected]>
2021-03-22 13:11:01 +01:00
Joakim SørensenandGitHub 740805356f Add content trust reasons (#8674) 2021-03-22 12:25:59 +01:00
Philip AllgaierandGitHub ce5fb57577 Add missing extra-fields translations (#8681) 2021-03-22 12:24:38 +01:00
GitHub Action 3e20d2b454 Translation update 2021-03-22 01:28:57 +00:00
GitHub Action a9e8186491 Translation update 2021-03-21 01:30:26 +00:00
GitHub Action 3bb909b026 Translation update 2021-03-20 01:26:31 +00:00
GitHub Action b921d91aeb Translation update 2021-03-19 01:27:47 +00:00
GitHub Action 05790954c6 Translation update 2021-03-18 01:26:33 +00:00
Marc MuellerandGitHub 13014c1351 Update metadata license string (#8431) 2021-03-17 14:25:58 +01:00
Mick VleeshouwerandGitHub e34c63b830 Add word wrap (#8654) 2021-03-17 12:22:14 +01:00
GitHub Action 943100d758 Translation update 2021-03-17 01:27:02 +00:00
Paulus Schoutsen 55f40d66f2 Bumped version to 20210316.0 2021-03-16 23:07:01 +00:00
593e5ac79c Link to traces from logbook entries (#8659)
Co-authored-by: Joakim Sørensen <[email protected]>
2021-03-16 16:03:54 -07:00
Paulus SchoutsenandGitHub ef31bce5ee Allow linking to trace (#8658) 2021-03-16 13:26:48 -07:00
Paulus SchoutsenandGitHub 3c75eb96f1 Adjust traces to latest API (#8656) 2021-03-16 10:43:30 -07:00
Paulus SchoutsenandGitHub f34dfde925 Fix spaces in changelog link (#8652) 2021-03-16 12:39:16 +01:00
Erik MontnemeryandGitHub e3b72fe0aa Use execute_script call in services developer tool (#8657) 2021-03-16 12:38:49 +01:00
GitHub Action 60de74a375 Translation update 2021-03-16 01:24:49 +00:00
Paulus SchoutsenandGitHub 55e58f8d35 Make time a label without icon (#8649) 2021-03-15 09:39:29 +01:00
Paulus SchoutsenandGitHub a465254418 Add new trace (#8633) 2021-03-15 09:38:23 +01:00
GitHub Action 5d27a138cf Translation update 2021-03-15 01:26:05 +00:00
Paulus Schoutsen 22f4b036df Bumped version to 20210314.0 2021-03-14 23:46:14 +00:00
Paulus SchoutsenandGitHub 03f694922d Add timeline entry when a long period of time passes (#8638) 2021-03-14 16:45:49 -07:00
Paulus SchoutsenandGitHub a841e287e5 Add basic action descriptions in traces (#8639) 2021-03-14 15:05:13 +01:00
Paulus SchoutsenandGitHub 5d2afdd825 Add motion light trace (#8637) 2021-03-14 15:03:50 +01:00
Paulus SchoutsenandGitHub 67240e2339 Group multiple logbook entries in traces (#8634) 2021-03-14 15:03:09 +01:00
Bram KragtenandGitHub f84a8eccfa FIx accessibility of data tables (#8611)
According to #6487
2021-03-14 14:54:46 +01:00
GitHub Action 68a058e4f1 Translation update 2021-03-14 01:28:21 +00:00
Paulus Schoutsen d678b42ece Bumped version to 20210313.0 2021-03-13 04:40:35 +00:00
Paulus Schoutsen 2cf63cda08 Add download button 2021-03-13 04:35:47 +00:00
Paulus SchoutsenandGitHub 7bd4eeb0df Trace foundation (#8608) 2021-03-12 20:13:06 -08:00
GitHub Action dc3ee7c779 Translation update 2021-03-13 01:24:27 +00:00
Thomas LovénandGitHub e8cc97a8e5 Enable turning off edit mode in panel views (#8625) 2021-03-12 16:26:18 +01:00
Philip AllgaierandGitHub 3b837e1d54 Consistent spelling of "PIN" (#8618) 2021-03-12 09:43:00 +01:00
GitHub Action bb6c2050bc Translation update 2021-03-12 01:25:56 +00:00
GitHub Action 082d4f9691 Translation update 2021-03-11 01:25:12 +00:00
Joakim SørensenandGitHub 153d68a9cd Custom error page when failing to load Supervisor panel (#8465) 2021-03-10 14:11:03 +01:00
Bram KragtenandGitHub 0404faa856 Update serviceworker with catch handler (#8601) 2021-03-09 20:33:11 -08:00
GitHub Action afbc2d6b8f Translation update 2021-03-10 01:24:36 +00:00
Bram KragtenandGitHub 89ecc8bd2f Change preload to modulepreload (#8600) 2021-03-09 11:39:08 -08:00
Philip AllgaierandGitHub 7f21a2b319 Properly align date time input fields around suffix separator (#8462) 2021-03-09 20:38:26 +01:00
Mick VleeshouwerandGitHub e2f07f6723 Add support for DEVICE_CLASS_CO and CO2 (#8602) 2021-03-09 19:32:06 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
a475e143b7 Bump elliptic from 6.5.3 to 6.5.4 (#8603)
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.3 to 6.5.4.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.3...v6.5.4)

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-03-09 19:31:27 +01:00
Paulus SchoutsenandGitHub e50fd80b2e Add particles to onboarding (#8567) 2021-03-09 15:30:29 +01:00
Bram KragtenandGitHub 68ea1abc05 Fallback to yaml for service data if unknown key is in data (#8595) 2021-03-09 15:26:26 +01:00
Bram KragtenandGitHub 2e76b306c4 Add guard for when default url is not available (#8593) 2021-03-09 11:56:26 +01:00
Bram KragtenandGitHub ca3cac4ed3 Fix missing areas in area picker (#8594) 2021-03-09 11:23:31 +01:00
Bram KragtenandGitHub 41852460e1 Improve code mirror comments check (#8585) 2021-03-09 11:23:02 +01:00
Bram KragtenandGitHub 9ec4e083d9 Change layout of automation yaml editor (#8560) 2021-03-09 11:21:59 +01:00
GitHub Action 9560a1c4a7 Translation update 2021-03-09 01:24:35 +00:00
Milan MeulemansandGitHub 4f5a47ace7 Fix typo (#8587) 2021-03-08 13:23:30 +01:00
01c4d662f2 ZHA UI enhancements (#8573)
Co-authored-by: Bram Kragten <[email protected]>
2021-03-08 13:23:14 +01:00
Bram KragtenandGitHub 194024edb9 Fix demo states translation (#8586) 2021-03-08 13:02:28 +01:00
ĢirtsandGitHub bef0d3a6a1 Remove margin from button card icon if icon is all that is set (#8584) 2021-03-08 12:47:19 +01:00
Bram Kragten 47a024b795 Update translations 2021-03-08 09:46:13 +01:00
GitHub Action 39847f9c9d Translation update 2021-03-08 01:25:07 +00:00
f24f21ca91 Handle delay templates properly + error handling tweaks (#8578)
Co-authored-by: Bram Kragten <[email protected]>
2021-03-07 23:15:53 +01:00
Philip AllgaierandGitHub c8ea37eec0 Consistent blank before "%" (#8366) 2021-03-07 23:05:20 +01:00
tkdrobandGitHub b71f452795 Fix spelling (#8582) 2021-03-07 22:33:02 +01:00
Bram KragtenandGitHub 7ea1ece169 Don't allow UI editor for service calls with templates (#8581) 2021-03-07 21:02:44 +01:00
Philip AllgaierandGitHub aece3a37c0 Ensure dev-tools state attribute checkbox state gets stored (#8579) 2021-03-07 16:40:54 +01:00
GitHub Action 705871f8dc Translation update 2021-03-07 01:26:43 +00:00
Bram KragtenandGitHub 4a11975349 Fix codemirror cursor color (#8571) 2021-03-06 23:11:57 +01:00
Philip AllgaierandGitHub 4d3d27f2c4 Move log item level position + color in detail popup header (#8270) 2021-03-06 18:58:29 +01:00
Paulus SchoutsenandGitHub d784a30d42 Allow sharing blueprints (#8565) 2021-03-06 14:19:56 +01:00
Paulus SchoutsenandGitHub 35f776284b Better place where device edit button is on desktop (#8566) 2021-03-06 14:18:42 +01:00
f659a6fe37 Grammar and spelling fixes (#8568)
Co-authored-by: Bram Kragten <[email protected]>
2021-03-06 14:17:30 +01:00
GitHub Action ad53c99fc4 Translation update 2021-03-06 01:22:48 +00:00
Philip AllgaierandGitHub fa0172d00c Fix a few translation typos (#8563) 2021-03-05 22:24:44 +01:00
Bram KragtenandGitHub 845411b48c Fix codemirror active line (#8558)
fixes #8556
2021-03-05 15:01:22 +01:00
Joakim SørensenandGitHub d715867b09 More consistant ignoring errors (#8553) 2021-03-05 10:40:49 +01:00
GitHub Action 0ca2cdfbed Translation update 2021-03-05 01:23:51 +00:00
Bram KragtenandGitHub 0d1c72386e Bump codemirror to 0.18 (#8546) 2021-03-04 16:43:34 +01:00
Joakim SørensenandGitHub c91779dffe Add supervisor_add_addon_repository redirect (#8545) 2021-03-04 16:31:32 +01:00
3853cc9214 Check if addon is valid before navigating (#8538)
Co-authored-by: Bram Kragten <[email protected]>
2021-03-04 11:51:35 +01:00
Joakim SørensenandGitHub a66b3f6b80 Fix managing custom addon repositories (#8536) 2021-03-04 10:29:00 +01:00
Joakim SørensenandGitHub c97ec32343 Fix missing name in full snapshot (#8535) 2021-03-04 10:25:51 +01:00
Josh McCartyandGitHub 2abba7e445 Alarm numeric inputmode (#8521) 2021-03-04 10:08:16 +01:00
Tierney CyrenandGitHub f887c27ad1 fix: move @types modules from deps to devDeps (#8539) 2021-03-04 10:05:28 +01:00
Joakim SørensenandGitHub 6ee8d74899 Remove duplicate save (#8532) 2021-03-04 10:03:09 +01:00
GitHub Action f196c72563 Translation update 2021-03-04 01:22:38 +00:00
Joakim SørensenandGitHub 419e564441 Use correct version (#8530) 2021-03-03 16:09:57 +01:00
Joakim SørensenandGitHub de97b54c95 Fix localize keys for supervisor update dialog (#8529) 2021-03-03 16:01:30 +01:00
Philip AllgaierandGitHub 07001f7b5c Fix add-on toggles description translation keys (#8528) 2021-03-03 15:33:52 +01:00
Joakim SørensenandGitHub bee17fce64 Fix second load in firefox and localize init (#8525) 2021-03-03 15:06:36 +01:00
Bram KragtenandGitHub 718904a853 Add max height to yaml editor (#8527) 2021-03-03 14:31:39 +01:00
Bram KragtenandGitHub 72af4a69d6 Bump codemirror (#8524) 2021-03-03 12:25:51 +01:00
Joakim SørensenandGitHub fe50f4229c Fix missing localize on old core versions (#8522) 2021-03-03 11:05:04 +01:00
ca4de877c1 Add remote more info card (#8506)
Co-authored-by: Philip Allgaier <[email protected]>
2021-03-02 17:57:49 -10:00
GitHub Action 1dfecf9618 Translation update 2021-03-03 01:23:10 +00:00
Bram KragtenandGitHub 0a3505ed89 Dont show config changes when user saved it (#8520) 2021-03-02 21:43:45 +01:00
Joakim SørensenandGitHub 33cbf7eabe Fix localize action (#8519) 2021-03-02 20:45:35 +01:00
Joakim SørensenandGitHub 935d97ce1a Fix reload of addon after update (#8518) 2021-03-02 17:05:11 +01:00
Joakim SørensenandGitHub 9f73f0ca8d Merge update dialogs (#8516) 2021-03-02 16:39:54 +01:00
Bram Kragten d8cdbac15e Bumped version to 20210302.0 2021-03-02 15:49:51 +01:00
Joakim SørensenandGitHub 03b8c1348c Use localize in the Supervisor panel (#8515) 2021-03-02 14:46:30 +01:00
Bram KragtenandGitHub 25a0be7672 Bump codemirror view (#8512)
Fixes search bug in Chrome
2021-03-02 10:05:16 +01:00
GitHub Action 08f1ce2d54 Translation update 2021-03-02 01:09:30 +00:00
bea20d0495 🌐 Add MVP for translation in the Supervisor panel (#8425)
Co-authored-by: Bram Kragten <[email protected]>
2021-03-02 00:37:39 +01:00
Bram Kragten 5ae10e8516 Bumped version to 20210301.0 2021-03-01 23:17:24 +01:00
Philip AllgaierandGitHub e3f4a9ce5b Bump MDI icons to 5.9.55 (#8508) 2021-03-01 23:08:04 +01:00
Bram KragtenandGitHub cf1fb606fb Bump codemirror + add more styling (#8503) 2021-03-01 22:55:02 +01:00
Bram KragtenandGitHub 54ec81b67d Fix en-gb translations (#8502)
Renamed lang key in lokalise
2021-03-01 22:48:36 +01:00
Philip AllgaierandGitHub f2a9725572 Make spelling more consistent (#8507) 2021-03-01 22:41:52 +01:00
Bram KragtenandGitHub 4765114e80 Allow decimal slider steps (#8501) 2021-03-01 18:41:36 +01:00
Bram KragtenandGitHub 5ff757ad65 Handle reconnect while in raw edit (#8500) 2021-03-01 16:55:39 +01:00
David F. MulcaheyandGitHub 1642c68493 Add view in visualization button to the device page for ZHA devices (#8090) 2021-03-01 15:54:49 +01:00
Philip AllgaierandGitHub f31f10cea9 Take cover "opening" and "closing" into account (#8490) 2021-03-01 12:58:12 +01:00
Philip AllgaierandGitHub 76e0bbb55d Make section row text color themeable (#8488) 2021-03-01 12:56:56 +01:00
Joakim SørensenandGitHub f43af9c0a5 Show config if options or schema (#8487) 2021-03-01 12:55:14 +01:00
Paulus SchoutsenandGitHub f7a3d2705c Preserve url params in redirect uri (#8495) 2021-03-01 12:54:39 +01:00
Joakim SørensenandGitHub 22c8af0cc5 Fix add-on store search (#8479) 2021-03-01 12:41:55 +01:00
Joakim SørensenandGitHub f263a5221d Adjust header and wording in update dialogs (#8476) 2021-03-01 12:40:52 +01:00
Bram KragtenandGitHub 3834ab8ede Service dev tools: Add service picker to YAML mode (#8482) 2021-03-01 11:09:15 +01:00
GitHub Action e2e167630d Translation update 2021-03-01 01:25:12 +00:00
GitHub Action 01dd44300b Translation update 2021-02-28 01:24:14 +00:00
Bram KragtenandGitHub b30160d671 Fix device picker (#8481) 2021-02-27 21:20:28 +01:00
GitHub Action f44d505b41 Translation update 2021-02-27 01:20:54 +00:00
Bram Kragten b58c17e75e make setup.py quite 2021-02-26 22:03:32 +01:00
Bram Kragten ae590d42dc Bumped version to 20210226.0 2021-02-26 21:39:43 +01:00
Bram Kragten d7917160c0 Update translations 2021-02-26 21:39:28 +01:00
Joakim SørensenandGitHub 01e4414d17 Ignore error if we are not connected (#8472) 2021-02-26 21:37:06 +01:00
Joakim SørensenandGitHub 0bc2eb530d Remove closing event from dialog (#8470) 2021-02-26 18:14:55 +01:00
Bram KragtenandGitHub 12b124e5a3 Add search, history to codemirror (#8469)
And prevent jump on focus
2021-02-26 18:01:48 +01:00
Joakim SørensenandGitHub 478a4b2593 Add snapshot to core update dialogs (#8468) 2021-02-26 15:07:29 +01:00
Joakim SørensenandGitHub 9752e30eb4 Add snapshot to add-on update dialog. (#8463) 2021-02-26 14:44:27 +01:00
Joakim SørensenandGitHub af6e87ba31 Fix messaging when addon is not available (#8454) 2021-02-26 14:15:36 +01:00
Bram KragtenandGitHub 64d390ad0f Fix wrong tag component (#8451)
Will rename the keys in Lokalise after merge
2021-02-26 14:01:16 +01:00
Joakim SørensenandGitHub c94bcb6896 Subscribe to message instead of event (#8443) 2021-02-26 13:47:48 +01:00
Joakim SørensenandGitHub 97f9df2f2d Add toggle to show_hide optional fields in add-on config (#8430) 2021-02-26 13:47:08 +01:00
GitHub Action 4e7f68a86c Translation update 2021-02-26 01:21:07 +00:00
Philip AllgaierandGitHub 2f7f677549 Restore previous codemirror tab behavior (#8461)
* Restore previous tab behavior

* Handle via ondemand logic

* Combine imports
2021-02-25 22:24:07 +01:00
Bram Kragten f44d867d3a Bumped version to 20210225.0 2021-02-25 18:40:34 +01:00
Bram KragtenandGitHub 6f636187f7 Clean translations (#8458) 2021-02-25 17:18:38 +01:00
Marc RandolphandGitHub 9414f89e50 Add theme variables for text of picture cards (#8022) 2021-02-25 16:47:33 +01:00
Bram KragtenandGitHub 60bf1a5451 Fix integrations page (#8457) 2021-02-25 15:59:04 +01:00
Philip AllgaierandGitHub 32ba8f4731 Make clear that automation run button skips conditions + remove word "execute" from UI (#8259)
* Do not skip conditions when triggering an automation

* Remove usage of word "execute"

* More concise function names
2021-02-25 14:17:31 +01:00
Philip AllgaierandGitHub 81f96de2bd Fix codemirror caret color (#8452) 2021-02-25 13:49:42 +01:00
Jesse HillsandGitHub 0c417755ed Fix my redirect for tags (#8450) 2021-02-25 12:03:03 +01:00
GitHub Action 93e5bde797 Translation update 2021-02-25 01:20:40 +00:00
Bram Kragten b6eaf0a7c5 Fix setting service data on load when in yaml mode 2021-02-24 20:17:31 +01:00
Bram Kragten 5f1851bade Bumped version to 20210224.0 2021-02-24 20:06:20 +01:00
Bram KragtenandGitHub 5c66a02711 My redirects tweaks (#8447) 2021-02-24 20:05:40 +01:00
Bram KragtenandGitHub bde925a0e3 Migrate to codemirror 6 (#8382) 2021-02-24 19:16:54 +01:00
0f574a765b Fix excessive rerendering of history charts (#8340)
Co-authored-by: Bram Kragten <[email protected]>
2021-02-24 17:48:50 +01:00
Kendell RandGitHub 782b941531 Save attribute checkbox state (#8010) 2021-02-24 17:44:37 +01:00
Kendell RandGitHub f42c0a0717 Add clipboard button (#8411) 2021-02-24 17:36:18 +01:00
Marc MuellerandGitHub 13ac14d449 Add additional weblink attributes (#8295) 2021-02-24 17:34:44 +01:00
Philip AllgaierandGitHub db9cea81db Correctly color script state icon + handle "single" mode for cancel buttons (#8383) 2021-02-24 17:18:38 +01:00
Bram KragtenandGitHub 7c1fd542da Allow to disable config entry (#8442) 2021-02-24 17:10:59 +01:00
Joakim SørensenandGitHub 54a2b2534a Add add-on selector/picker (#8422) 2021-02-24 17:05:42 +01:00
Álvaro Fernández RojasandGitHub f5fb6c1e03 Support binary sensor batteries (#8367) 2021-02-24 17:00:07 +01:00
Bram KragtenandGitHub 781c0701fc Show correct fields in UI mode (#8445) 2021-02-24 14:27:00 +01:00
GitHub Action 742f1f85dc Translation update 2021-02-24 01:20:56 +00:00
a648e9be49 Fix atLeastVersion (#8437)
Co-authored-by: Bram Kragten <[email protected]>
2021-02-23 22:17:22 +01:00
Joakim SørensenandGitHub fd9441dde2 Fix blank page in ingress when resizing window (#8439) 2021-02-23 16:16:24 +01:00
Philip AllgaierandGitHub b5ec59c396 Dev-tools service: Tweak to target description (#8434) 2021-02-23 16:10:15 +01:00
Bram KragtenandGitHub 60e4594abd Fix area picker with both entity and device filter (#8438) 2021-02-23 15:07:45 +01:00
GitHub Action 79692ef58a Translation update 2021-02-23 01:19:57 +00:00
J. Nick KostonandGitHub ace7ee5622 Add support for percentage step size to fans (#8393) 2021-02-22 15:59:59 -06:00
Philip AllgaierandGitHub 741ac679a0 Ensure we have all mandatory action keys present in action editor (#8424) 2021-02-22 21:10:06 +01:00
Bram Kragten d76af2cb61 Bumped version to 20210222.0 2021-02-22 20:06:30 +01:00
Bram KragtenandGitHub b7d4c40736 Show flows in progress when picking a handler (#8368) 2021-02-22 20:06:18 +01:00
Bram KragtenandGitHub 6092af8de6 Re-do developer tools service (#8410) 2021-02-22 19:53:52 +01:00
627424b8b9 Migrate mfa to Lit (#8276)
Co-authored-by: Joakim Sørensen <[email protected]>
2021-02-22 19:53:37 +01:00
Joakim SørensenandGitHub e33aff7cf3 Fix mouseevent in blueprint import popup (#8432) 2021-02-22 17:56:43 +01:00
Joakim SørensenandGitHub ef0bfb237a bump webpack-manifest-plugin to 3.0.0 (#8426) 2021-02-22 10:30:02 +01:00
Joakim SørensenandGitHub c042c5568b Fix WS command for validating ingress session (#8427) 2021-02-22 10:28:18 +01:00
GitHub Action d84a7ee358 Translation update 2021-02-22 01:20:19 +00:00
GitHub Action 8bfc8ece9d Translation update 2021-02-21 01:21:30 +00:00
GitHub Action 2d3cf7d84d Translation update 2021-02-20 01:18:25 +00:00
Franck NijhofandGitHub 520ef8f1df Update GitHub Issue Form template (#8423) 2021-02-19 22:13:27 +01:00
Bram KragtenandGitHub f251d4267f Revert "Allow viewport scaling (zooming) of frontend" (#8353)
This reverts commit da9faccada.
2021-02-19 18:06:36 +01:00
Bram KragtenandGitHub 2052a5351c Ha-form: Don't change data (#8277) 2021-02-19 18:03:31 +01:00
Bram KragtenandGitHub 9807d0aede Move localizing to render (#8419) 2021-02-19 18:02:25 +01:00
Bram KragtenandGitHub a41afcd714 Update lovelace call service action (#8421) 2021-02-19 17:58:14 +01:00
Bram KragtenandGitHub d93d2b5945 Fix password field in ha-form (#8400) 2021-02-19 17:47:51 +01:00
Bram KragtenandGitHub d54a129605 Bump marked (#8420) 2021-02-19 17:46:33 +01:00
77911980cb Correctly handle seconds in top "delay" key (#8415)
Co-authored-by: Bram Kragten <[email protected]>
2021-02-19 11:03:25 +01:00
Bram KragtenandGitHub d51fd1e2f9 Add supervisor_logs and supervisor_info redirects (#8417) 2021-02-19 10:01:21 +01:00
GitHub Action fe54f8eb16 Translation update 2021-02-19 01:18:52 +00:00
Bram KragtenandGitHub fc7c4af27a Add more redirects (#8413) 2021-02-18 20:35:16 +01:00
09e7600d86 Use websockets (#8403)
Co-authored-by: Bram Kragten <[email protected]>
2021-02-18 18:18:05 +01:00
GitHub Action 17410874e3 Translation update 2021-02-18 01:18:34 +00:00
GitHub Action 03d4174163 Translation update 2021-02-17 01:18:01 +00:00
Bram KragtenandGitHub 99eff73b0d Add support for target to automation call service action (#8372) 2021-02-16 21:46:47 +01:00
Joakim SørensenandGitHub acefa39796 Update supervisor info on addon action (#8404) 2021-02-16 21:38:23 +01:00
Joakim SørensenandGitHub c01c0528a6 Show options if no options and schema (#8408) 2021-02-16 21:25:59 +01:00
Bram KragtenandGitHub 0ec58007c9 Add my support to supervisor (#8405)
* Add my support to supervisor

* Remove localize

* Comments

* Update ha-panel-my.ts
2021-02-16 19:50:35 +01:00
GitHub Action e8daf88729 Translation update 2021-02-16 01:18:09 +00:00
Matteo AgnolettoandGitHub ab74c7f7eb Add select selector for blueprints (#8297) 2021-02-15 10:22:00 +01:00
GitHub Action 6b673c7f44 Translation update 2021-02-15 01:18:50 +00:00
GitHub Action 53510a3cb9 Translation update 2021-02-14 01:19:47 +00:00
GitHub Action d4d38a880d Translation update 2021-02-13 01:17:10 +00:00
GitHub Action 18783d5e3b Translation update 2021-02-12 01:17:41 +00:00
Philip AllgaierandGitHub eb235cb552 Add bottom margin to button card icon (#8362) 2021-02-11 13:39:31 +01:00
GitHub Action 435a6b6d53 Translation update 2021-02-11 01:17:07 +00:00
GitHub Action 8d13745c6b Translation update 2021-02-10 01:16:43 +00:00
Franck NijhofandGitHub 14c7cfc64c Add GitHub Issue Form (#8363) 2021-02-09 18:15:57 +01:00
Joakim SørensenandGitHub c7821b9cee Don't show add-on config if no schema (#8361) 2021-02-09 11:51:46 +01:00
GitHub Action a1d66aef0c Translation update 2021-02-09 01:17:05 +00:00
Jaroslav HanslíkandGitHub e275f1f4b9 Fixed state card of number entity (#8325) 2021-02-08 16:28:28 +01:00
Joakim SørensenandGitHub 48de8b0739 Block snapshots when system is not running (#8350) 2021-02-08 16:18:33 +01:00
Joakim SørensenandGitHub b75dc0efe0 Fix issue with jumping config (#8355) 2021-02-08 16:18:01 +01:00
1d498349c5 Update container port (#8352)
* Update container port

* Update .devcontainer/devcontainer.json

Co-authored-by: Joakim Sørensen <[email protected]>
2021-02-08 16:09:40 +01:00
Bram KragtenandGitHub 5cdcec699b Merge branch 'master' into dev 2021-02-08 15:14:36 +01:00
Bram Kragten cd72287d99 Bumped version to 20210208.0 2021-02-08 15:12:42 +01:00
Bram KragtenandGitHub c8717bfa32 Add my panel (#8349) 2021-02-08 14:48:54 +01:00
GitHub Action 83de75b689 Translation update 2021-02-08 01:17:33 +00:00
Philip AllgaierandGitHub e5ea762cbc Resolve merge conflict from PR #8121 2021-02-07 16:36:25 +01:00
Philip AllgaierandGitHub 01df01cd66 Provide stub config for entity-filter (#8121)
* Provide stub config for entity-filter

* "card" option is optional since it has a default

* Search dynamically for stub config entities
2021-02-07 14:38:54 +01:00
Philip AllgaierandGitHub 2c07a2c825 Correct typo in "find-entities.ts" file name (#8343) 2021-02-07 14:37:35 +01:00
chriss158andGitHub c3f50ba0fb Fix no disconnect after 5 minute timeout (#8339) 2021-02-07 14:33:44 +01:00
GitHub Action c04419fd09 Translation update 2021-02-07 01:18:53 +00:00
Paulus SchoutsenandGitHub 9c7af0dfce Drop margin from cast header (#8331) 2021-02-06 23:00:06 +01:00
GitHub Action b66d14e980 Translation update 2021-02-06 01:15:59 +00:00
GitHub Action 6a553e9554 Translation update 2021-02-05 01:17:26 +00:00
4273b72d71 Fix issue where schema is null (#8322)
Co-authored-by: Paulus Schoutsen <[email protected]>
2021-02-04 14:01:53 +01:00
GitHub Action 9ccfa79199 Translation update 2021-02-04 01:16:30 +00:00
fe3d22d4f8 Only display current temp when not None (#8316)
Co-authored-by: Bram Kragten <[email protected]>
2021-02-03 20:51:28 +01:00
e06642e892 Show the reason why an add-on is not available (#8312)
Co-authored-by: Bram Kragten <[email protected]>
2021-02-03 17:35:55 +01:00
Joakim SørensenandGitHub 5199e946a1 Fix button layout for addon-info (#8315) 2021-02-03 16:08:29 +01:00
Joakim SørensenandGitHub 17aff2f9b8 Move save button to the right (#8314) 2021-02-03 15:58:17 +01:00
Joakim SørensenandGitHub f7c7ac44f7 Show eMMC lifetime (#8302) 2021-02-03 15:52:52 +01:00
Joakim SørensenandGitHub 62dd0a561e Fix display issue wtih addon-info grid (#8313) 2021-02-03 15:45:01 +01:00
GitHub Action 858eacddea Translation update 2021-02-03 01:23:54 +00:00
Bram Kragten 471bb5169c Bumped version to 20210127.7 2021-02-02 21:24:52 +01:00
Bram KragtenandJoakim Sørensen 9d89aa329c Revert "Add icon support to gauge" (#8303)
Co-authored-by: Joakim Sørensen <[email protected]>
2021-02-02 21:23:08 +01:00
4e4d8bdc5e Revert "Add icon support to gauge" (#8303)
Co-authored-by: Joakim Sørensen <[email protected]>
2021-02-02 21:17:38 +01:00
GitHub Action a30ec32ac1 Translation update 2021-02-02 01:31:33 +00:00
Joakim SørensenandGitHub a9192ae2e1 Force YAML if schema has multiple (#8298) 2021-02-01 13:00:38 +01:00
Mike MorrisonandGitHub 3d4a0b02e5 Fix gaps in history charts (#8293) 2021-02-01 11:52:12 +01:00
GitHub Action 3659cf7c87 Translation update 2021-02-01 01:37:09 +00:00
GitHub Action fbcf35414c Translation update 2021-01-31 01:36:47 +00:00
Bram Kragten d79e5dd8fb Bumped version to 20210127.6 2021-01-30 22:51:57 +01:00
Philip AllgaierandBram Kragten 92b116c0da More precise name handling for auto-generated dashboards (#8289)
Co-authored-by: Bram Kragten <[email protected]>
2021-01-30 22:51:46 +01:00
Bram Kragten da3f911deb Fix tts try on ios (#8292) 2021-01-30 22:51:32 +01:00
Philip AllgaierandBram Kragten 9d82ce8ab4 Add missing device_classes to sensor (#8288) 2021-01-30 22:51:13 +01:00
Bram Kragten db9597d2e7 Don't use badges in generated Lovelace + group entities by area (#8291) 2021-01-30 22:50:56 +01:00
1523558f4c More precise name handling for auto-generated dashboards (#8289)
Co-authored-by: Bram Kragten <[email protected]>
2021-01-30 22:49:48 +01:00
Bram KragtenandGitHub bd9f4fe41c Fix tts try on ios (#8292) 2021-01-30 22:42:01 +01:00
Philip AllgaierandGitHub 6b938b2597 Add missing device_classes to sensor (#8288) 2021-01-30 21:32:25 +01:00
Bram KragtenandGitHub 5a8009e46e Don't use badges in generated Lovelace + group entities by area (#8291) 2021-01-30 21:30:47 +01:00
GitHub Action c92eeb6bb7 Translation update 2021-01-30 01:33:03 +00:00
Bram Kragten 8ea6baaf5d Bumped version to 20210127.5 2021-01-29 18:38:36 +01:00
Bram Kragten 1ed03842c0 Fix grid + map editor (#8284) 2021-01-29 18:38:25 +01:00
Bram KragtenandGitHub 0e9984413c Fix grid + map editor (#8284) 2021-01-29 18:37:58 +01:00
Philip AllgaierandBram Kragten 362b419814 Add missing extra field translation for cover position (#8273)
* Ensure ha-form-integer passes "0" to form data

* Only keep the translation change
2021-01-29 18:14:07 +01:00
chriss158andBram Kragten bffcccc1fe Fix external auth reconnection loop if connection lost after refresh token expiration (#8279) 2021-01-29 18:13:48 +01:00
Bram Kragten b8e9a4ce9f Fix map editor (#8280) 2021-01-29 18:13:26 +01:00
Bram Kragten bdff3fd452 Z-wave migration tweaks (#8283) 2021-01-29 18:11:25 +01:00
Bram Kragten 1fc51f0087 Bumped version to 20210127.4 2021-01-29 18:10:58 +01:00
Bram KragtenandGitHub 226013d999 Z-wave migration tweaks (#8283) 2021-01-29 18:10:18 +01:00
Joakim SørensenandGitHub 86847263b8 Initial UI config for add-ons (#8271) 2021-01-29 18:06:38 +01:00
Bram KragtenandGitHub b798523d53 Fix map editor (#8280) 2021-01-29 17:19:01 +01:00
chriss158andGitHub bd59c4fccf Fix external auth reconnection loop if connection lost after refresh token expiration (#8279) 2021-01-29 13:40:09 +01:00
GitHub Action 566ffe24a4 Translation update 2021-01-29 01:33:55 +00:00
Philip AllgaierandGitHub 0e5c1b2041 Add missing extra field translation for cover position (#8273)
* Ensure ha-form-integer passes "0" to form data

* Only keep the translation change
2021-01-28 22:39:45 +01:00
Bram Kragten 9a088a21da Bumped version to 20210127.3 2021-01-28 22:35:49 +01:00
Bram Kragten 1160d27004 Revert "Bumped version to 20210127.2"
This reverts commit 3766f44787.
2021-01-28 22:34:31 +01:00
Bram Kragten b4e5740050 Fix race condition in zwave migration (#8268) 2021-01-28 20:59:54 +01:00
Bram Kragten 12bb3f5796 Use close dialog function to close device registry detail dialog (#8269) 2021-01-28 20:59:37 +01:00
Bram Kragten ff62fdb69d hide config links in demo (#8267) 2021-01-28 20:59:15 +01:00
Bram Kragten 4ebf32cb1f Move try tss button to bottom (#8266) 2021-01-28 20:58:59 +01:00
Thomas LovénandBram Kragten 5afb8a77a9 Make input_text entity row usable when value is "unknown" (#8258) 2021-01-28 20:58:43 +01:00
Jaroslav HanslíkandBram Kragten 48ed33af95 Typo in texts (#8265) 2021-01-28 20:58:26 +01:00
Jaroslav HanslíkandBram Kragten 4a64cd4464 Typo in texts (#8264) 2021-01-28 20:58:12 +01:00
Paulus SchoutsenandBram Kragten 8ae1a1b558 Fix tts (#8261) 2021-01-28 20:57:56 +01:00
Philip AllgaierandBram Kragten ef1dd8b761 Add check to prevent undefined access during action validation (#8257) 2021-01-28 20:57:41 +01:00
Bram Kragten 3766f44787 Bumped version to 20210127.2 2021-01-28 20:57:15 +01:00
Bram KragtenandGitHub 101067d018 Fix race condition in zwave migration (#8268) 2021-01-28 20:20:07 +01:00
Bram KragtenandGitHub 448d19bfbb Use close dialog function to close device registry detail dialog (#8269) 2021-01-28 20:18:13 +01:00
Bram KragtenandGitHub c1caad6d43 hide config links in demo (#8267) 2021-01-28 20:16:00 +01:00
Bram KragtenandGitHub a653bf5b0d Move try tss button to bottom (#8266) 2021-01-28 20:10:15 +01:00
J. Nick KostonandGitHub afdb369e04 Separate fan speeds into percentages and presets modes (#8216) 2021-01-28 09:24:18 -06:00
Thomas LovénandGitHub f02841409c Make input_text entity row usable when value is "unknown" (#8258) 2021-01-28 14:05:07 +01:00
d4000cf662 Allow theming of header edit background color (#8246)
Co-authored-by: Bram Kragten <[email protected]>
2021-01-28 12:00:40 +01:00
Jaroslav HanslíkandGitHub e1cf5919fa Typo in texts (#8265) 2021-01-28 11:55:00 +01:00
Jaroslav HanslíkandGitHub d33e8d77c2 Typo in texts (#8264) 2021-01-28 11:54:34 +01:00
GitHub Action 3a522215a9 Translation update 2021-01-28 01:34:39 +00:00
Paulus SchoutsenandGitHub 7de6ea0879 Fix tts (#8261) 2021-01-27 23:42:06 +01:00
Joakim SørensenandGitHub 5ee0250ba5 Add hostname and metrics to Add-ons (#8253) 2021-01-27 22:38:07 +01:00
Philip AllgaierandGitHub 69d0a22091 Add check to prevent undefined access during action validation (#8257) 2021-01-27 18:39:03 +01:00
Philip AllgaierandGitHub 4d6c11ce31 Enforce "good" states of binary_sensor as green in history timeline chart (#8145) 2021-01-27 17:22:01 +01:00
Bram Kragten 178605664e Bumped version to 20210127.1 2021-01-27 17:17:48 +01:00
Bram Kragten 12acb5473b Bumped version to 20210127.1 2021-01-27 17:17:20 +01:00
Joakim SørensenandBram Kragten 0cf8004b8d Add twine to release flow (#8254) 2021-01-27 17:14:00 +01:00
Joakim SørensenandGitHub 6b0a8eae74 Add twine to release flow (#8254) 2021-01-27 17:13:18 +01:00
Bram KragtenandGitHub 00412c7216 Merge pull request #8252 from home-assistant/dev 2021-01-27 16:24:07 +01:00
Bram KragtenandGitHub 6483f23558 Merge branch 'master' into dev 2021-01-27 16:10:48 +01:00
Bram Kragten 4234d51a29 Bumped version to 20210127.0 2021-01-27 16:09:35 +01:00
9243d300cc Zwave -> OZW migration (#7765)
Co-authored-by: Joakim Sørensen <[email protected]>
2021-01-27 16:01:18 +01:00
Thomas LovénandGitHub 2ce70206c6 Markdown format blueprint descriptions in import dialog (#8251) 2021-01-27 16:00:15 +01:00
Bram KragtenandGitHub b22455d2a5 Add simple try tts dialog (#8245) 2021-01-27 15:58:58 +01:00
Philip AllgaierandGitHub 4f0bb9f6c3 Add icon support to gauge (#8081) 2021-01-27 13:36:03 +01:00
7dfa1b0942 Convert state history chart to LitElement + add warning if history is disabled (#7994)
Co-authored-by: Ian Richardson <[email protected]>
Co-authored-by: Bram Kragten <[email protected]>
2021-01-27 13:13:40 +01:00
Philip AllgaierandGitHub 093e23c006 Auto capitalize first letter of entity row name (#7962) 2021-01-27 12:38:39 +01:00
Philip AllgaierandGitHub 5f003ccbe2 Add navigation to dashboard & resources to lovelace editor + icons (#8156) 2021-01-27 12:37:28 +01:00
Philip AllgaierandGitHub 8d0608610f Entity registry: Translate advanced section + direct link to entity customization (#8181) 2021-01-27 12:35:25 +01:00
8bfe583a20 Convert customize to LitElement + "real" entity picker + option to directly jump to entity (#8180)
Co-authored-by: Bram Kragten <[email protected]>
2021-01-27 12:34:31 +01:00
Philip AllgaierandGitHub 0a3172dfdb More comprehensive YAML config errors + dynamic checks for action configs (#8217) 2021-01-27 12:33:57 +01:00
Thomas LovénandGitHub 5c0e151bc2 Add selectors for text and arbitrary objects (#8152) 2021-01-27 11:45:51 +01:00
Ian RichardsonandGitHub e69f36047d add actions to weather-forecast-card (#7659) 2021-01-27 10:59:09 +01:00
ed368ddd9d Add support for delay values split into parts + millisecond time input (#7886)
Co-authored-by: Bram Kragten <[email protected]>
2021-01-27 10:46:15 +01:00
GitHub Action 8400e90e34 Translation update 2021-01-27 01:32:26 +00:00
4cd95b724b Use minified bundle of node vibrant (#7784)
Co-authored-by: Bram Kragten <[email protected]>
2021-01-26 23:24:23 +01:00
ShulyakaandGitHub 46b3836fbd Add number entity support (#7876) 2021-01-26 23:14:23 +01:00
Tim McCormickandGitHub 9988227d93 Don't assume position of items in array (#7927) 2021-01-26 22:59:58 +01:00
9d289bfa34 Add download dump button to zwave_js panel (#8232)
Co-authored-by: Philip Allgaier <[email protected]>
2021-01-26 22:20:16 +01:00
Bram KragtenandGitHub 048de6b388 Fix translation action (#8244) 2021-01-26 17:21:38 +01:00
9b7d8934da Correctly handle "hours to show" for footer graph (#8071)
Co-authored-by: Bram Kragten <[email protected]>
2021-01-26 16:15:32 +01:00
0dd9b21c2d Add minutes to hourly weather forecast time display (#8182)
Co-authored-by: Bram Kragten <[email protected]>
2021-01-26 16:14:34 +01:00
Philip AllgaierandGitHub 417184525f Adjust calendar translations to fix loading issue in calendar card (#8235) 2021-01-26 10:42:13 +01:00
Philip AllgaierandGitHub 0a09ec706f Visual alignment of automation and script more info dialogs (#8234) 2021-01-26 10:25:34 +01:00
cf43b26e14 Prevent automation action row issue if event name gets cleared (#8213)
Co-authored-by: Bram Kragten <[email protected]>
2021-01-25 20:01:30 +01:00
a8b27e224f Allow themeing of media control card (#8209)
Co-authored-by: Bram Kragten <[email protected]>
2021-01-25 20:00:50 +01:00
Philip AllgaierandGitHub dc5d14834d Added missing translations for some automation extra-fields (#8210) 2021-01-25 11:59:44 +01:00
Philip AllgaierandGitHub 12c935f647 Show entity_picture in logbook (#8118) 2021-01-25 11:48:16 +01:00
Philip AllgaierandGitHub 7710cb245c Use correct color for shopping list card section header (#8223) 2021-01-25 11:35:04 +01:00
b3nj1andGitHub a6b77c0457 entity-filter card allow state_filter.value == 0 (number 0) (#8225) 2021-01-25 10:54:22 +01:00
Philip AllgaierandGitHub 748a05f355 Use app header color as default selected tab color + allow styling (#8227) 2021-01-25 10:53:53 +01:00
Philip AllgaierandGitHub 831b9da0cf Various demo tweaks + cleanups (#8229) 2021-01-25 10:52:59 +01:00
Charles GarwoodandGitHub a3339c9d5f Add wizards for adding and removing Z-Wave JS nodes (#8174) 2021-01-25 10:46:50 +01:00
Philip AllgaierandGitHub d228f38471 Correct URL to automation run modes documentation (#8230) 2021-01-25 01:51:00 +01:00
Philip AllgaierandGitHub fe13853b8b Allow timestamp attribute formatting + central timestamp formats (#8162) 2021-01-22 20:24:31 +01:00
Philip AllgaierandGitHub 6f4dbdc959 Improve entity registry errors display (#8208) 2021-01-22 15:50:11 +01:00
870f0bcbb1 Fix some dialog close history issues (#8102)
Co-authored-by: Zack Barett <[email protected]>
Co-authored-by: Philip Allgaier <[email protected]>
2021-01-22 13:33:10 +01:00
Philip AllgaierandGitHub 599dd81e3c Make "button row" name optional to be consistent with "button card" and "buttons row" (#8189) 2021-01-21 20:03:53 +01:00
Philip AllgaierandGitHub 9e99d158fd Add error handling to action handling (#8187) 2021-01-21 19:38:19 +01:00
Philip AllgaierandGitHub 136ebb5a07 Set sensible default tap_action (same logic as button row) (#8186) 2021-01-21 16:44:17 +01:00
Charles GarwoodandGitHub 707338b1aa Add Z-Wave info to device page for zwave_js devices (#8195) 2021-01-21 16:16:24 +01:00
Bram KragtenandGitHub 7e06bd53b6 Change remote ui portal to account page (#8193) 2021-01-18 16:47:14 +01:00
Joakim SørensenandGitHub 08c1b864fc Fix missing addon list when creating partial snapshot (#8176) 2021-01-17 17:34:14 +01:00
Thomas LovénandGitHub 16e7a16d12 Fix date picker text color (#7776) 2021-01-16 20:48:18 +01:00
Thomas LovénandGitHub 45200da32f Helpful comment. See #8152 (#8160) 2021-01-16 16:40:59 +01:00
Philip AllgaierandGitHub 84a9ca59ef Add "columns" and "square" to grid card editor (#7888) 2021-01-16 16:25:13 +01:00
Charles GarwoodandGitHub 40f4c35b42 Initial Z-Wave JS Config Panel (#8166) 2021-01-16 16:22:27 +01:00
Philip AllgaierandGitHub bb77d34017 Tweaks to cloud integration page (#7878) 2021-01-16 16:19:57 +01:00
Philip AllgaierandGitHub 9659ebe59b Increase font size for alarm keypad number buttons (#8120) 2021-01-16 16:09:52 +01:00
Thomas LovénandGitHub 16c914b139 Show default value for selector-less blueprint inputs. (#8163) 2021-01-15 14:30:27 +01:00
Philip AllgaierandGitHub 142f26add1 Align entities card section header styling (#8113) 2021-01-14 13:05:37 +01:00
Philip AllgaierandGitHub ef7d2aea8d Fix config update handling for map card editor (#8115) 2021-01-14 12:52:58 +01:00
1aa40cb6df Convert state-card-display to LitElement and use timestamp display (#8150)
Co-authored-by: Bram Kragten <[email protected]>
2021-01-14 12:49:29 +01:00
Philip AllgaierandGitHub cd06b931a9 Allow empty/undefined for counter min & max (#8154) 2021-01-14 12:25:06 +01:00
Mick VleeshouwerandGitHub fd2df92000 Change supportsStop to supportsStopTilt (#8153) 2021-01-14 12:24:26 +01:00
Philip AllgaierandGitHub b565a8b8f7 Allow "idle" media players to be switched of in entity row (#8155) 2021-01-14 11:35:31 +01:00
Philip AllgaierandGitHub 1aab656705 Make entity-filter and glances demo a bit clearer & cleaner (#8157) 2021-01-14 11:20:18 +01:00
6919d0cde6 Ensure we always show backend error in automation and script editor (#8139)
Co-authored-by: Bram Kragten <[email protected]>
2021-01-13 20:45:40 +01:00
Philip AllgaierandGitHub 95fd8de1bc Adjust person / presence detection texts (#8117) 2021-01-13 20:13:37 +01:00
Philip AllgaierandGitHub 28ca1a5193 Adjust / theme entity marker background color (#8116) 2021-01-13 17:40:15 +01:00
Joakim SørensenandGitHub a1d07e5a00 Sort imports (#8104) 2021-01-13 17:17:12 +01:00
Philip AllgaierandGitHub 131a7f3782 Clear entity ID during automation duplication (#8140) 2021-01-13 17:12:51 +01:00
Philip AllgaierandGitHub c28a7d6c10 Center align content of date input (#8134) 2021-01-13 17:10:08 +01:00
J. Nick KostonandGitHub 6b20bb967b Add support for dhcp discovery (#8149) 2021-01-13 11:07:32 +01:00
Paulus SchoutsenandGitHub 75f228418d Allow configuring default TTS voice for cloud (#8148) 2021-01-13 11:07:03 +01:00
Joakim SørensenandGitHub 41f8b0d19b Add verify-version step to release (#8138) 2021-01-12 10:32:38 +01:00
Paulus SchoutsenandGitHub cea3b8b010 Show name on ignored entries (#8135) 2021-01-12 09:26:31 +01:00
Nikfinn99andGitHub aba0e1f026 Automation - State Condition display 'for:' in frontend (#8124)
* Automation - State Condition display 'for:' in frontend

* rename variable to better name
2021-01-11 17:24:39 +01:00
f42587af22 Format URL attribute as link (#8126)
Co-authored-by: Bram Kragten <[email protected]>
2021-01-11 15:59:26 +01:00
Joakim SørensenandGitHub edcb7e87bb Hide configuration card if the add-on does not expose options or schema (#8131) 2021-01-11 14:43:24 +01:00
Joakim SørensenandGitHub 96f0ceeb8c Update supervisor on add-on store refresh (#8132) 2021-01-11 14:42:58 +01:00
Joakim SørensenandGitHub a9baa7f1c1 Move netlify preview builds from Azure to Github (#8105)
* Move netlify preview builds from Azure  to Github

* Remove checkout

* Update secret names
2021-01-11 14:03:21 +01:00
Joakim SørensenandGitHub b1483287dc Add Core to supervisor/system (#8123) 2021-01-11 13:51:52 +01:00
Thomas LovénandGitHub a4657541fc Show location name in auth page, if available. (#8119) 2021-01-11 13:11:30 +01:00
PiklesandGitHub 56d88b4c56 Add CSS Variables for Menu (#7917) 2021-01-11 12:50:33 +01:00
Joakim SørensenandGitHub 02313e4be8 Move translations from Azure to Github (#8129)
* Move translations from Azure to Github

* remove [ci skip]
2021-01-11 12:27:10 +01:00
Joakim SørensenandGitHub 2a14a3a4dc Move release builds from Azure to Github (#8128)
* Move release builds from Azure to Github

* Fix syntax issue (YAML is hard)
2021-01-11 12:14:53 +01:00
Philip AllgaierandGitHub d02a2e8c2e Consistently use isComponentLoaded() helper (#7995) 2021-01-10 19:52:22 +01:00
Bram KragtenandGitHub 0d281f8437 Fix for undefined stateObj in media player row (#8114) 2021-01-08 09:39:55 -06:00
Thomas LovénandGitHub 2b0f43f334 Format blueprint descriptions with markdown (#8109) 2021-01-08 12:22:12 +01:00
Philip AllgaierandGitHub f9d28fc124 Add blank between temperature and unit in weather card (#8111) 2021-01-08 11:10:39 +01:00
Philip AllgaierandGitHub da07173471 Prevent YAML mode if no entity is set in card editor (#8110) 2021-01-08 11:07:04 +01:00
Joakim SørensenandGitHub 4deeff7029 Prefix supervisor version with supervisor- (#8107) 2021-01-08 10:54:12 +01:00
Bram KragtenandGitHub 1538fbb102 Bump material elements (#8093) 2021-01-07 10:09:03 +01:00
Philip AllgaierandGitHub b9259b87eb Beautify ha-attribute <pre> (#8101) 2021-01-06 20:46:39 +01:00
David F. MulcaheyandGitHub 30997dbc88 Add filtering and zoom to node to the ZHA network visualization (#7913) 2021-01-06 10:37:53 +01:00
Bram Kragten a9d926e80a Bumped version to 20201229.1 2021-01-05 20:38:52 +01:00
Philip AllgaierandBram Kragten c41369c89c Add EN fallback text for dismiss button (#8068) 2021-01-05 20:38:36 +01:00
Philip AllgaierandBram Kragten 656bef3da9 Prevent relative time text wrapping in more-info-sun (#8051) 2021-01-05 20:38:18 +01:00
Paulus SchoutsenandGitHub 607eb6d130 Prefer target over environment (#8092) 2021-01-05 16:03:55 +01:00
Philip AllgaierandGitHub f2e9b3577d Use proper styled confirmation dialog for handled actions (#8077) 2021-01-05 14:04:45 +01:00
Philip AllgaierandGitHub cb2c6d8560 Convert gallery elements to LitElement (#8088) 2021-01-05 13:29:21 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
bfe8346ced Bump ini from 1.3.5 to 1.3.7 (#7949)
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.7.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.7)

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-05 11:47:56 +01:00
Siemon GeeromsandGitHub 88da9bb91b Allow to show modal dialogs in iFrame panels (#7971) 2021-01-05 11:38:46 +01:00
Shane QiandGitHub 5e2ee1a16c Added Drag & Drop Reordering to Shopping List Card. (#7296) 2021-01-05 11:24:41 +01:00
Philip AllgaierandGitHub 2fdc746392 Add support for "all" as entity ID in action "service" (#7954) 2021-01-05 11:02:47 +01:00
Philip AllgaierandGitHub 1667973a66 Improve spacing in entity rows + secondary ellipsis (#8028) 2021-01-05 10:50:40 +01:00
Philip AllgaierandGitHub 42f0101440 Add gallery demo for plant card (#7989) 2021-01-04 22:10:58 +01:00
Philip AllgaierandGitHub 13b69bff1b Translate timestamp-display errors + tiny tweaks (#8086)
* Translate timestamp-display errors + tiny tweaks

* Adjust translation key
2021-01-04 20:55:43 +01:00
Philip AllgaierandGitHub 2c2226dfd6 Slightly increase max attribute value width (#8085) 2021-01-04 19:51:30 +01:00
Philip AllgaierandGitHub a3fdfe0e15 Add additional entities to gallery more-info-light (#7930) 2021-01-04 18:06:47 +01:00
Philip AllgaierandGitHub a0de209a55 Aligned gallery more-info with hui-cards (#7931) 2021-01-04 18:05:30 +01:00
Philip AllgaierandGitHub 0208b50ac7 Disable counter buttons if entity is unavailable (#8084) 2021-01-04 18:02:01 +01:00
4a61779aba Ensure YAML editor gets updated during action change / deletion (#8024)
Co-authored-by: Bram Kragten <[email protected]>
2021-01-04 15:01:25 +01:00
05057ade05 Catch navigator.clipboard errors (#7942)
Co-authored-by: Bram Kragten <[email protected]>
2021-01-04 14:04:54 +01:00
Abílio CostaandGitHub 6fb206853c Switch header sizes for ZHA pairing status card (#8078)
Since the top title shows the result of the previous step ("Interview
Complete", "Configuration Complete", etc), while the second title shows
the current step ("Configuring", "Initializing", etc), having the top
title bigger would draw attention to it. So a user could see
"Configuration Complete" and assume pairing is done.

This change makes the second title bigger than the top one, so that the
user focus on the step that is in progress.
2021-01-04 14:03:12 +01:00
Charles GarwoodandGitHub fab68055bf OZW Panel: Don't show an empty wakeup card (#8064) 2021-01-04 10:57:25 +01:00
Philip AllgaierandGitHub d5a77ef3cd Treat zero as String in number selector (#8070) 2021-01-04 10:53:40 +01:00
Philip AllgaierandGitHub dcb2605de4 Add Bengali language (#8014) 2021-01-04 10:28:25 +01:00
Philip AllgaierandGitHub e6d38f4539 Fix incorrect date selection ranges for history and logbook (#8045) 2021-01-04 10:04:14 +01:00
Philip AllgaierandGitHub 293b56cfa6 Show actual error path/key in YAML card editor (#8076) 2021-01-04 09:58:07 +01:00
Philip AllgaierandGitHub 775e93d54b Ensure consistent number display for gauge (#8080) 2021-01-04 09:24:51 +01:00
Philip AllgaierandGitHub 7f840e75df Add EN fallback text for dismiss button (#8068) 2021-01-04 09:18:08 +01:00
Philip AllgaierandGitHub 2113ea675e Prevent relative time text wrapping in more-info-sun (#8051) 2021-01-04 09:17:17 +01:00
Philip AllgaierandGitHub 916a5c1a6b Make it clearer that we are looking for the YAML card config 2021-01-04 00:31:42 +01:00
HomeAssistant Azure f684531315 [ci skip] Translation update 2021-01-02 00:41:18 +00:00
HomeAssistant Azure fe8dda8996 [ci skip] Translation update 2020-12-31 00:32:48 +00:00
HomeAssistant Azure 4cd4b328c8 [ci skip] Translation update 2020-12-30 00:32:31 +00:00
Bram KragtenandGitHub 3d7ee6a4df Merge pull request #8048 from home-assistant/dev 2020-12-29 23:23:58 +01:00
Bram KragtenandGitHub d844c89b94 Merge branch 'master' into dev 2020-12-29 23:12:14 +01:00
Bram Kragten 177ea2b85a Bumped version to 20201229.0 2020-12-29 23:09:00 +01:00
50c5c15f49 Update group reload string (#7938)
* Update group reload string

* Update src/translations/en.json

Co-authored-by: Philip Allgaier <[email protected]>

* Update rest reload string

Co-authored-by: Philip Allgaier <[email protected]>
2020-12-29 23:03:44 +01:00
Philip AllgaierandGitHub 1810760dc7 Mark entity ID as optional for button card (#7967) 2020-12-29 23:02:47 +01:00
Joakim SørensenandGitHub 4635b92e3f Fix add-on stage icon rendering (#7981) 2020-12-29 22:59:07 +01:00
Jochen MehlhornandGitHub 1c652626eb Fix typo in hassio-supervisor-info.ts (#7907)
Fix typo in "unhealthy state" warning
2020-12-29 22:58:29 +01:00
Philip AllgaierandGitHub 2000cfb1db Correct tabs for customizations page (#7990) 2020-12-29 22:52:58 +01:00
Philip AllgaierandGitHub f4d07828e7 Minor follow-up tweaks for PR 7947 (#7955) 2020-12-29 22:52:20 +01:00
Philip AllgaierandGitHub 95b552671c Fix border radius for labeled slider (#7929) 2020-12-29 22:50:09 +01:00
Philip AllgaierandGitHub ef3bc3efe1 Do not render "No Area" in device table to reduce clutter (#7986) 2020-12-29 22:46:47 +01:00
Philip AllgaierandGitHub 371ad899f5 Handle sorting with "undefined" (move always to bottom) (#7985) 2020-12-29 22:45:39 +01:00
plafüandGitHub 2c54158d84 Fixes typo: 'bring to live'>'bring to life' (#8000) 2020-12-29 22:44:21 +01:00
quthlaandGitHub 5d9e30bbdc Fix translation of home state (#8015) 2020-12-29 22:43:41 +01:00
Marc RandolphandGitHub e477fd567d Button text is swapped on Lovelace raw YAML exit window (#8038)
Button text is swapped compared to the same thing elsewhere: https://github.com/home-assistant/frontend/blob/d23165d06ae57cddef2529481d1c4d857f3e20b6/src/panels/lovelace/editor/card-editor/hui-dialog-edit-card.ts#L311
2020-12-29 22:38:31 +01:00
Philip AllgaierandGitHub 6a6c2937fe Ensure consistent spelling of "ID" (#8042) 2020-12-29 22:36:28 +01:00
HomeAssistant Azure 09e17c4da8 [ci skip] Translation update 2020-12-29 00:32:26 +00:00
HomeAssistant Azure fd00469d11 [ci skip] Translation update 2020-12-28 00:32:37 +00:00
HomeAssistant Azure cbbeb795f3 [ci skip] Translation update 2020-12-27 00:32:32 +00:00
HomeAssistant Azure bba40e0da8 [ci skip] Translation update 2020-12-25 00:32:32 +00:00
HomeAssistant Azure d23165d06a [ci skip] Translation update 2020-12-24 00:33:07 +00:00
HomeAssistant Azure 405fef6f03 [ci skip] Translation update 2020-12-23 00:32:49 +00:00
HomeAssistant Azure 588f217826 [ci skip] Translation update 2020-12-22 00:32:27 +00:00
HomeAssistant Azure 3d8b7cf80e [ci skip] Translation update 2020-12-21 00:32:26 +00:00
HomeAssistant Azure c0ef923ad3 [ci skip] Translation update 2020-12-20 00:32:26 +00:00
HomeAssistant Azure 3df44fc71e [ci skip] Translation update 2020-12-19 00:33:33 +00:00
HomeAssistant Azure c1965492d9 [ci skip] Translation update 2020-12-18 00:32:38 +00:00
HomeAssistant Azure 1f56ffde80 [ci skip] Translation update 2020-12-17 00:33:13 +00:00
Georgi KirichkovandGitHub f335fdc002 Fixes a typo in hassio-supervisor-info.ts (#7987)
An "a" was missing in installtion
2020-12-16 10:28:21 +01:00
HomeAssistant Azure 0c914b5ec8 [ci skip] Translation update 2020-12-16 00:32:25 +00:00
Philip AllgaierandGitHub d767b06858 Fix spelling error (#7961)
Fixes https://github.com/home-assistant/frontend/issues/7958
2020-12-15 07:22:06 -06:00
Fabian AffolterandGitHub d4e49f3944 Update entry (#7978) 2020-12-15 09:49:26 +01:00
HomeAssistant Azure 7dfc5b3faf [ci skip] Translation update 2020-12-15 00:32:22 +00:00
HomeAssistant Azure 8a88033ab9 [ci skip] Translation update 2020-12-14 00:32:42 +00:00
HomeAssistant Azure 7b06b38c94 [ci skip] Translation update 2020-12-13 00:32:43 +00:00
5409752817 20201212.0 (#7952)
* [ci skip] Translation update

* Add link to the community forums to find more blueprints (#7947)

* Add link to the community forums to find more blueprints

* Apply suggestions from code review

Co-authored-by: Paulus Schoutsen <[email protected]>

Co-authored-by: Paulus Schoutsen <[email protected]>

* Fix `ha-relative-time` usage for tags and sun (#7944)

* Bumped version to 20201212.0

Co-authored-by: HomeAssistant Azure <[email protected]>
Co-authored-by: Paulus Schoutsen <[email protected]>
Co-authored-by: Philip Allgaier <[email protected]>
2020-12-12 20:57:28 +01:00
Bram Kragten 909f3a3005 Bumped version to 20201212.0 2020-12-12 20:48:44 +01:00
Philip AllgaierandGitHub 4930532c7b Fix ha-relative-time usage for tags and sun (#7944) 2020-12-12 20:46:56 +01:00
8a42e65c6a Add link to the community forums to find more blueprints (#7947)
* Add link to the community forums to find more blueprints

* Apply suggestions from code review

Co-authored-by: Paulus Schoutsen <[email protected]>

Co-authored-by: Paulus Schoutsen <[email protected]>
2020-12-12 20:38:10 +01:00
HomeAssistant Azure 5d4121a9b4 [ci skip] Translation update 2020-12-11 00:32:17 +00:00
Bram KragtenandGitHub a70e6c49a1 Merge pull request #7940 from home-assistant/dev
20201210.0
2020-12-10 16:56:08 +01:00
Bram Kragten 3d83d5f4b5 Bumped version to 20201210.0 2020-12-10 15:57:13 +01:00
Philip AllgaierandGitHub f9dece0743 Add copy YAML (automation & script) fallback without navigator.clipboard (#7900) 2020-12-10 15:55:57 +01:00
Bram KragtenandGitHub ac0871d0e8 Use correct device name in target picker (#7939) 2020-12-10 15:12:33 +01:00
HomeAssistant Azure ffc19e591d [ci skip] Translation update 2020-12-10 00:32:24 +00:00
HomeAssistant Azure c53380ca3d [ci skip] Translation update 2020-12-09 00:32:38 +00:00
Bram KragtenandGitHub 7c74a2026a Correct tabs helpers page (#7928)
Fixes https://github.com/home-assistant/frontend/issues/7926
2020-12-08 11:47:30 +01:00
HomeAssistant Azure adaed438d9 [ci skip] Translation update 2020-12-08 00:32:29 +00:00
uvjustinandGitHub baf38305cb Remove use of named groups in regexp (#7921) 2020-12-07 15:18:27 +01:00
HomeAssistant Azure 8254712521 [ci skip] Translation update 2020-12-07 00:33:14 +00:00
HomeAssistant Azure 53214781e3 [ci skip] Translation update 2020-12-06 00:32:39 +00:00
HomeAssistant Azure 88cbbbdf65 [ci skip] Translation update 2020-12-05 00:33:30 +00:00
Bram KragtenandGitHub c10dca9c7b Merge pull request #7910 from home-assistant/dev 2020-12-04 21:46:54 +01:00
Bram Kragten 7f2ebb4bde Bumped version to 20201204.0 2020-12-04 21:33:37 +01:00
Bram KragtenandGitHub f1abb60e4a Add message when no matches for selectors, clear config when deleted (#7906) 2020-12-04 20:49:24 +01:00
Bram KragtenandGitHub e014c7aff6 Entity is not required for button card (#7909)
Fixes https://github.com/home-assistant/frontend/issues/7908
2020-12-04 12:02:58 -06:00
Bram KragtenandGitHub b79c03433e Don't update device picker while open (#7903) 2020-12-04 12:05:01 +01:00
HomeAssistant Azure 34eb4d974d [ci skip] Translation update 2020-12-04 00:32:26 +00:00
Zack BarettandGitHub 3264be3c5e Move main function to events on hui-view for custom views to use (#7861) 2020-12-03 18:16:55 -06:00
Bram KragtenandGitHub 655f4f75fb Change import blueprint fab icon (#7894) 2020-12-03 22:41:13 +01:00
Bram KragtenandGitHub 4383f31696 Translation logic tweaks (#7901)
* Translation logic tweaks

* Comments
2020-12-03 22:29:52 +01:00
Paulus SchoutsenandGitHub 99eb15d15e Improve blueprint translations (#7892) 2020-12-03 18:08:14 +01:00
Bram KragtenandGitHub 2682c6e150 Merge pull request #7891 from home-assistant/dev 2020-12-03 17:22:08 +01:00
Bram Kragten 3a5d854e6d Bumped version to 20201203.0 2020-12-03 17:00:56 +01:00
Bram KragtenandGitHub 1e90c6387c More BP tweaks (#7884) 2020-12-03 09:59:43 -06:00
Philip AllgaierandGitHub 2cca25f4d0 Navigate back to area overview after area deletion (#7890) 2020-12-03 16:52:44 +01:00
Bram KragtenandGitHub 565724d201 Fix translation race condition? (#7885) 2020-12-03 16:52:09 +01:00
3e4955becd UI tweaks for BP (#7883)
Co-authored-by: Paulus Schoutsen <[email protected]>
2020-12-03 14:18:17 +01:00
Philip AllgaierandGitHub 7b560c727f Adjust text since entities can now be in areas too (#7880) 2020-12-03 14:05:16 +01:00
HomeAssistant Azure 35abd9dfdb [ci skip] Translation update 2020-12-03 00:32:38 +00:00
Bram KragtenandGitHub b7ccf3e0e5 Merge pull request #7875 from home-assistant/dev 2020-12-02 19:51:36 +01:00
Bram Kragten 0d9ab8fdd0 Bumped version to 20201202.0 2020-12-02 19:31:43 +01:00
Bram KragtenandGitHub 303f9290a8 Add more device disabled ui (#7874) 2020-12-02 19:31:06 +01:00
Bram KragtenandGitHub e0c4dc08a1 Tooltip tweak target picker (#7870) 2020-12-02 11:21:51 -06:00
Bram KragtenandGitHub 8c655883fe Add device disabled reason (#7873) 2020-12-02 18:20:29 +01:00
Bram KragtenandGitHub ba90785115 Fix card picker cards (#7871) 2020-12-02 17:46:30 +01:00
Bram KragtenandGitHub 7b392b626b Hardcode history card stub entity to sun.sun (#7760) 2020-12-02 10:16:46 -06:00
Zack BarettandGitHub 8e4ceb7d48 Fix View Background Colors (#7823) 2020-12-02 17:08:18 +01:00
Philip AllgaierandGitHub 2ab1c6e9a9 Make media player card work as square + add to gallery + icon pos tweaks (#7727) 2020-12-02 16:57:19 +01:00
Adam ErnstandGitHub dbdced0971 Improve descriptions for Configuration entries (#7606) 2020-12-02 16:36:21 +01:00
Philip AllgaierandGitHub 5e481880bd Allow empty entities array with entity-filter (#7854) 2020-12-02 16:34:59 +01:00
Kendell RandGitHub faec063f34 Add --masonry-view-card-margin (#7395) 2020-12-02 16:22:20 +01:00
Zack BarettandGitHub bbea38d227 Lovelace Card Editor: Preview Background (#7678) 2020-12-02 16:19:01 +01:00
Kendell RandGitHub a0ef60de49 Make card picker border follow standards (#7162) 2020-12-02 16:14:46 +01:00
3313572606 Improve password change card (#7756)
Co-authored-by: Bram Kragten <[email protected]>
2020-12-02 16:00:49 +01:00
Philip AllgaierandGitHub c4f850cb14 Cleanup created user if person creation is cancelled (#7865) 2020-12-02 15:45:24 +01:00
3bdab738c6 Support disabling devices (#7715)
Co-authored-by: Bram Kragten <[email protected]>
2020-12-02 15:40:35 +01:00
Philip AllgaierandGitHub faaef31b9f Show proper error message if username already used (#7866) 2020-12-02 15:35:38 +01:00
Philip AllgaierandGitHub ca7b8b8b4c Add option to deactivate a user (#7757) 2020-12-02 15:33:11 +01:00
Philip AllgaierandGitHub 9ca84e0694 Ensure "false" is set as default for "continue_on_timeout" (#7862) 2020-12-02 15:22:17 +01:00
Philip AllgaierandGitHub daaf2b1796 Ensure push notification description reacts to language change (#7856) 2020-12-02 12:11:47 +01:00
25f7cbea5a Add target selector (#7864)
Co-authored-by: Paulus Schoutsen <[email protected]>
2020-12-02 12:10:31 +01:00
Josh McCartyandGitHub c485ea9d7b Add number formatting to counter entity state display (#7868) 2020-12-02 11:51:56 +01:00
HomeAssistant Azure 295390c8e9 [ci skip] Translation update 2020-12-02 00:32:30 +00:00
Bram KragtenandGitHub 3ebf816ce2 Fix height of ha-icon-input (#7767) 2020-12-01 22:51:15 +01:00
HomeAssistant Azure 0e362b851b [ci skip] Translation update 2020-12-01 00:32:47 +00:00
David F. MulcaheyandGitHub 8d7ba19a08 Add ZHA fab for adding device when filtered by ZHA (#7848) 2020-11-30 11:05:54 +01:00
Paulus SchoutsenandGitHub 08f4aa9d10 Use balloons as default pic for header. (#7850) 2020-11-30 10:59:04 +01:00
HomeAssistant Azure 98175d5c72 [ci skip] Translation update 2020-11-30 00:32:50 +00:00
7d4cad90bc Show attribute value when 0 (#7842)
Co-authored-by: Bram Kragten <[email protected]>
2020-11-29 22:37:13 +01:00
335354d962 Enhance ZHA device pairing feedback (#7843)
Co-authored-by: Bram Kragten <[email protected]>
2020-11-29 22:33:46 +01:00
Bram KragtenandGitHub fe31d15d27 Add UI for setting an area on entity level (#7837) 2020-11-29 22:00:51 +01:00
Marc RandolphandGitHub 7ceb6eb50d Apply existing theme variables to unthemed items (#7844) 2020-11-29 16:13:55 +01:00
HomeAssistant Azure 4c4db46aa8 [ci skip] Translation update 2020-11-29 00:32:38 +00:00
Bram KragtenandGitHub b5724ed343 Make fab blue (#7839) 2020-11-28 17:22:42 +01:00
HomeAssistant Azure cae94175fe [ci skip] Translation update 2020-11-28 00:32:35 +00:00
0494a9d410 Update skeleton height for compact header (#7827)
Co-authored-by: Bram Kragten <[email protected]>
2020-11-27 19:23:41 +01:00
Philip AllgaierandGitHub c261b5c1ce Display HA username + flags in user config (#7705) 2020-11-27 09:41:47 +01:00
HomeAssistant Azure c89e17ac00 [ci skip] Translation update 2020-11-27 00:32:35 +00:00
Bram KragtenandGitHub 50e7410002 Merge pull request #7833 from home-assistant/dev 2020-11-27 00:16:56 +01:00
Bram KragtenandGitHub c5b0ebf76d Update ha-config-dashboard.ts 2020-11-27 00:01:34 +01:00
Bram KragtenandGitHub 1d08978d6c Merge branch 'master' into dev 2020-11-26 23:59:34 +01:00
Bram Kragten fc78b6c933 Bumped version to 20201126.0 2020-11-26 23:58:13 +01:00
Philip AllgaierandGitHub 480a5718fc Remove unusable Polymer mixin from LitElement (vacuum entity row) (#7831) 2020-11-26 23:57:37 +01:00
f093bd115c Add network visualization to the ZHA config panel (#7802)
Co-authored-by: Bram Kragten <[email protected]>
2020-11-26 23:56:50 +01:00
David F. MulcaheyandGitHub 8a86beff14 Remove unused ZHA translations and fix ZHA fab labels (#7832) 2020-11-26 23:56:22 +01:00
Philip AllgaierandGitHub 6020890384 Add state-info ellipsis + fix height (#7740) 2020-11-26 23:54:30 +01:00
Philip AllgaierandGitHub 124aa947e2 Show pointer cursor for input + scene entity rows (#7830) 2020-11-26 20:32:15 +01:00
Bram KragtenandGitHub e1add14453 Add UI for new selectors (#7822) 2020-11-26 18:38:01 +01:00
Philip AllgaierandGitHub e3293837a8 Blueprints: Added missing labels & tooltips, optimize input display + text tweaks (#7748) 2020-11-26 18:14:57 +01:00
HomeAssistant Azure 5cb2743780 [ci skip] Translation update 2020-11-26 00:32:25 +00:00
6f0c79ec25 Introduce supervisor object (#7800)
Co-authored-by: Bram Kragten <[email protected]>
2020-11-25 18:22:05 +01:00
7de7d1d926 Fix init page message color (#7780)
Co-authored-by: Bram Kragten <[email protected]>
2020-11-25 15:22:22 +01:00
Bram KragtenandGitHub 89175f8e85 Add description and device class (#7816)
https://github.com/home-assistant/core/pull/43321
2020-11-25 15:10:08 +01:00
fc48c59eb0 Clean up some types (#7801)
Co-authored-by: Zack Barett <[email protected]>
2020-11-25 12:31:51 +01:00
Paulus SchoutsenandGitHub 51332bc7e7 Add frontend url (#7797) 2020-11-25 12:26:11 +01:00
Josh McCartyandGitHub 7403405d12 Additional number formatting (#7763) 2020-11-25 11:37:58 +01:00
Paulus SchoutsenandGitHub 1d13947e71 Use Record type (#7798) 2020-11-25 10:40:32 +01:00
HomeAssistant Azure f6cb1ffe20 [ci skip] Translation update 2020-11-25 00:32:19 +00:00
Paulus SchoutsenandGitHub 6d92b5651a Bump @web/dev-server (#7792) 2020-11-24 12:04:22 +01:00
Bram KragtenandGitHub 3ea5bb2a6c Fix filtering hidden columns entity table (#7786) 2020-11-24 12:03:06 +01:00
Joakim SørensenandGitHub 1d367eca69 Add ignored job_conditions to list of unsupported reasons (#7790) 2020-11-24 11:48:19 +01:00
HomeAssistant Azure d4bf3a2ec3 [ci skip] Translation update 2020-11-24 00:32:27 +00:00
Joakim SørensenandGitHub 0ef8881660 Add unhealthy dialog and SU restart button (#7781) 2020-11-23 17:24:26 +01:00
Joakim SørensenandGitHub d7d1121f7d Force enable interface if configured (#7785) 2020-11-23 17:22:23 +01:00
7f089c309f Change order and wording snapshot actions (#7677)
Co-authored-by: Bram Kragten <[email protected]>
2020-11-23 17:08:10 +01:00
Philip AllgaierandGitHub 4dcc0bb66c Reduce "wasted" screen space (#7655) 2020-11-23 13:44:47 +01:00
Paulus SchoutsenandGitHub 0049be7feb Allow developing with @web/dev-server (#7782) 2020-11-23 13:05:18 +01:00
39ff641be9 Close webpack compiler on prod build (#7779)
Co-authored-by: Bram Kragten <[email protected]>
2020-11-23 12:48:21 +01:00
Paulus SchoutsenandGitHub e2fed24995 Clean up node-vibrant (#7777) 2020-11-23 12:47:47 +01:00
Philip AllgaierandGitHub c0aa353f83 Load missing component titles for ha-related-items (#7771) 2020-11-23 10:48:32 +01:00
d8521be63d use correct condition for display of tilt controls (#7769)
Co-authored-by: Philip Allgaier <[email protected]>
2020-11-23 10:45:53 +01:00
Paulus SchoutsenandGitHub 6d4569c89d Drop webpackChunkName (#7778) 2020-11-23 10:39:40 +01:00
Paulus SchoutsenandGitHub cd07553b59 Upgrade Rollup babel plugin (#7773) 2020-11-23 10:21:45 +01:00
HomeAssistant Azure 641bfcc9f7 [ci skip] Translation update 2020-11-23 00:32:47 +00:00
HomeAssistant Azure 6c01371958 [ci skip] Translation update 2020-11-22 00:33:21 +00:00
Paulus SchoutsenandGitHub 7b00260b1a Remove duplicate translation key (#7766) 2020-11-21 23:33:19 +01:00
Paulus SchoutsenandGitHub 875142373e Remove unused files and automate translation fragments (#7764) 2020-11-21 22:44:44 +01:00
Philip AllgaierandGitHub ba505b15ef Ensure new grid card options don't break editor (#7762) 2020-11-21 21:40:27 +01:00
DonnieandGitHub 17d227b142 Stop appending 'Configuration' to the end of every config page in navigation commands. Fix spinner regression (#7753) 2020-11-21 08:31:40 -08:00
Philip AllgaierandGitHub e7e192ffe3 Align gallery code + fix icon in entity-icon demo (#7754) 2020-11-21 14:28:25 +01:00
Philip AllgaierandGitHub c53ec6e12d Ensure more consistent lovelace config errors (#7755) 2020-11-21 14:08:43 +01:00
Philip AllgaierandGitHub aad6492a6a Show error if no entity specified for history card (#7752) 2020-11-21 13:50:56 +01:00
HomeAssistant Azure fd5b125c2d [ci skip] Translation update 2020-11-21 00:32:15 +00:00
Paulus SchoutsenandGitHub 5acee76c70 Show validation errors in UI (#7725) 2020-11-20 15:37:56 +01:00
10916fa82a Convert ha-relative-time to TypeScript/LitElement (#7709)
Co-authored-by: Bram Kragten <[email protected]>
2020-11-20 15:17:34 +01:00
Bram KragtenandGitHub f69951a523 Fix automation editor (#7746) 2020-11-20 15:16:27 +01:00
Philip AllgaierandGitHub 38ba85e89d Make gallery config visible in dark mode + fix config alignment (#7741) 2020-11-20 15:13:19 +01:00
Patrick DecatandGitHub 97023921b8 Add missing "gate" cover device_class (#7744) 2020-11-20 15:10:25 +01:00
Bram KragtenandGitHub f835810f0a Add entity and device selectors (#7735) 2020-11-20 13:26:03 +01:00
HomeAssistant Azure 46f5589530 [ci skip] Translation update 2020-11-20 00:32:27 +00:00
Thomas LovénandGitHub ff9840c8ef Use mwc-tabs in conditional card editor (#7716) 2020-11-19 23:06:06 +01:00
Philip AllgaierandGitHub 0c197558a1 Close notification drawer when last entry is dismissed (#7724) 2020-11-19 22:53:21 +01:00
Joakim SørensenandGitHub c409ba149d Supervisor network changes (#7676) 2020-11-19 22:51:29 +01:00
Joakim SørensenandGitHub 0b896ddfb1 Check snapshot size before upload (#7733) 2020-11-19 22:49:29 +01:00
Philip AllgaierandGitHub 45721eb4fe Adjust FAB for blueprint overview + align translations (#7730) 2020-11-19 22:48:34 +01:00
Bram KragtenandGitHub 1289bd03b2 Remove conference banner (#7731) 2020-11-19 10:46:52 +01:00
HomeAssistant Azure c1ba8ba6b8 [ci skip] Translation update 2020-11-19 00:32:32 +00:00
Bram KragtenandGitHub 4973d8f629 WIP initial Blueprint UI (#7695)
* WIP initial Blueprint UI

* Review comments

* localize
2020-11-18 12:19:59 +01:00
Philip AllgaierandGitHub 3aff4c96c4 Add Georgian language (Kartuli) (#7721) 2020-11-18 10:39:35 +01:00
Paulus Schoutsen 4005bc8985 Clarify title 2020-11-18 08:46:42 +00:00
Paulus Schoutsen 62e9792c39 Add note about building the frontend 2020-11-18 08:44:45 +00:00
HomeAssistant Azure 33183cc595 [ci skip] Translation update 2020-11-18 00:32:28 +00:00
Josh McCartyandGitHub 394d552856 Use ha-dialog for dialog-system-log-details, add close icon button (#7513) 2020-11-17 22:29:20 +01:00
Bram Kragten aa4f0929e0 Bumped version to 20201111.2 2020-11-17 22:24:30 +01:00
Thomas LovénandBram Kragten f99b9215e3 Fix date picker row alignment (#7704) 2020-11-17 22:23:21 +01:00
Paulus SchoutsenandBram Kragten c51d621fee Allow dismissing (#7712) 2020-11-17 22:22:39 +01:00
Paulus SchoutsenandGitHub 7499892bc2 Don't support safari 10 in minifaction for latest support (#7719) 2020-11-17 22:00:28 +01:00
Paulus SchoutsenandGitHub cbddebeaa8 Allow dismissing (#7712) 2020-11-17 16:14:37 +01:00
Philip AllgaierandGitHub bbe4c95109 Display entity ID for read-only entities (#7690) 2020-11-17 16:08:47 +01:00
Philip AllgaierandGitHub 4c6f9f0dd8 Fix empty entity pickers for "Time" trigger and condition (#7689) 2020-11-17 15:51:18 +01:00
Philip AllgaierandGitHub 90f7dba793 Use proper night time icon consistently for sun integration (#7681) 2020-11-17 15:48:54 +01:00
Philip AllgaierandGitHub 7c492338a2 Improve gallery hui-gauge-card (#7682) 2020-11-17 15:46:33 +01:00
Philip AllgaierandGitHub 530f494df8 Improve gallery hui-light-card (#7684) 2020-11-17 15:46:00 +01:00
Joakim SørensenandGitHub 8fd1f35c59 Move data_entry_flow_progressed event subscriber (#7700) 2020-11-17 15:12:45 +01:00
Joakim SørensenandGitHub af1518e924 Use stepid title if present for progress flow (#7710) 2020-11-17 14:33:13 +01:00
Thomas LovénandGitHub 473e381d75 Fix date picker row alignment (#7704) 2020-11-17 09:43:25 +01:00
Paulus SchoutsenandGitHub 7d3acc747d Guard passing invalid tag to customElements.whenDefined (#7696) 2020-11-17 09:40:35 +01:00
HomeAssistant Azure bf7424a67c [ci skip] Translation update 2020-11-17 00:32:25 +00:00
Bram Kragten 3fb35871c7 Bumped version to 20201111.1 2020-11-16 22:02:28 +01:00
DonnieandBram Kragten d6d20cd704 Quick Bar should only capitalize letters in Command Palette (#7671) 2020-11-16 22:02:02 +01:00
Bram Kragten 9cc6a6b885 Fix number format in state-card-display (#7703) 2020-11-16 22:01:48 +01:00
Philip AllgaierandBram Kragten ee0be7b6d0 Add missing 1px to prevent slider pin cutoff (#7657) 2020-11-16 22:01:32 +01:00
a856337eae Devcontainer (#7697)
Co-authored-by: Paulus Schoutsen <[email protected]>
2020-11-16 16:53:47 +01:00
Bram KragtenandGitHub 6cf47ba4eb Fix number format in state-card-display (#7703) 2020-11-16 12:45:52 +01:00
DonnieandGitHub 3b7a189708 Quick Bar should only capitalize letters in Command Palette (#7671) 2020-11-16 12:45:20 +01:00
Philip AllgaierandGitHub 79c542b76a Add missing 1px to prevent slider pin cutoff (#7657) 2020-11-16 12:44:58 +01:00
Bram KragtenandGitHub 7e6153ba7d Merge pull request #7654 from home-assistant/dev 2020-11-11 15:40:04 +01:00
864 changed files with 64916 additions and 31609 deletions
+13
View File
@@ -0,0 +1,13 @@
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.148.1/containers/python-3/.devcontainer/base.Dockerfile
FROM mcr.microsoft.com/vscode/devcontainers/python:0-3.9
ENV \
DEBIAN_FRONTEND=noninteractive \
DEVCONTAINER=true \
PATH=$PATH:./node_modules/.bin
# Install nvm
COPY .nvmrc /tmp/.nvmrc
RUN \
su vscode -c \
"source /usr/local/share/nvm/nvm.sh && nvm install $(cat /tmp/.nvmrc) 2>&1"
+34
View File
@@ -0,0 +1,34 @@
{
"name": "Home Assistant Frontend",
"build": {
"dockerfile": "Dockerfile",
"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"
],
"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
}
}
@@ -74,12 +74,12 @@ DO NOT DELETE ANY TEXT from this template! Otherwise, your issue may be closed w
```
## Problem-relevant configuration
## Problem-relevant frontend configuration
<!--
An example configuration that caused the problem for you. Fill this out even
if it seems unimportant to you. Please be sure to remove personal information
like passwords, private URLs and other credentials.
An example configuration that caused the problem for you, e.g. the YAML configuration
of the used cards. Fill this out even if it seems unimportant to you. Please be sure
to remove personal information like passwords, private URLs and other credentials.
-->
```yaml
@@ -89,7 +89,7 @@ DO NOT DELETE ANY TEXT from this template! Otherwise, your issue may be closed w
## Javascript errors shown in your browser console/inspector
<!--
If you come across any javascript or other error logs, e.g., in your browser
If you come across any Javascript or other error logs, e.g. in your browser
console/inspector please provide them.
-->
+138
View File
@@ -0,0 +1,138 @@
name: Report a bug with the UI, Frontend or Lovelace
about: Report an issue related to the Home Assistant frontend.
labels: bug
title: ""
issue_body: true
body:
- type: markdown
attributes:
value: |
Make sure you are running the [latest version of Home Assistant][releases] before reporting an issue.
If you have a feature or enhancement request for the frontend, please [start an discussion][fr] instead of creating an issue.
**Please not not report issues for custom Lovelace cards.**
[fr]: https://github.com/home-assistant/frontend/discussions
[releases]: https://github.com/home-assistant/home-assistant/releases
- type: checkboxes
attributes:
label: Checklist
description: Please verify that you've followed these steps
options:
- label: I have updated to the latest available Home Assistant version.
required: true
- label: I have cleared the cache of my browser.
required: true
- label: I have tried a different browser to see if it is related to my browser.
required: true
- type: markdown
attributes:
value: |
## The problem
- type: textarea
validations:
required: true
attributes:
label: Describe the issue you are experiencing
description: Provide a clear and concise description of what the bug is.
- type: textarea
validations:
required: true
attributes:
label: Describe the behavior you expected
description: Describe what you expected to happen or it should look/behave.
- type: textarea
validations:
required: true
attributes:
label: Steps to reproduce the issue
description: |
Please tell us exactly how to reproduce your issue.
Provide clear and concise step by step instructions and add code snippets if needed.
value: |
1.
2.
3.
...
- type: markdown
attributes:
value: |
## Environment
- type: input
validations:
required: true
attributes:
label: What version of Home Assistant Core has the issue?
placeholder: core-
description: >
Can be found in the Configuration panel -> Info.
- type: input
attributes:
label: What was the last working version of Home Assistant Core?
placeholder: core-
description: >
If known, otherwise leave blank.
- type: input
attributes:
label: In which browser are you experiencing the issue with?
placeholder: Google Chrome 88.0.4324.150
description: >
Provide the full name and don't forget to add the version!
- type: input
attributes:
label: Which operating system are you using to run this browser?
placeholder: macOS Big Sur (1.11)
description: >
Don't forget to add the version!
- type: markdown
attributes:
value: |
# Details
- type: textarea
attributes:
label: State of relevant entities
description: >
If your issue is about how an entity is shown in the UI, please add the
state and attributes for all situations. You can find this information
at Developer Tools -> States.
value: |
```yaml
# Paste your state here.
```
- type: textarea
attributes:
label: Problem-relevant frontend configuration
description: >
An example configuration that caused the problem for you, e.g., the YAML
configuration of the used cards. Fill this out even if it seems
unimportant to you. Please be sure to remove personal information like
passwords, private URLs and other credentials.
value: |
```yaml
# Paste your YAML here.
```
- type: textarea
attributes:
label: Javascript errors shown in your browser console/inspector
description: >
If you come across any Javascript or other error logs, e.g., in your
browser console/inspector please provide them.
value: |
```txt
# Paste your logs here.
```
- type: markdown
attributes:
value: |
## Additional information
- type: markdown
attributes:
value: |
If you have any additional information for us, use the field below.
Please note, you can attach screenshots or screen recordings here,
by dragging and dropping files in the field below.
+19
View File
@@ -0,0 +1,19 @@
name: Netlify
on:
schedule:
- cron: "0 0 * * *"
jobs:
trigger_builds:
name: Trigger netlify build preview
runs-on: "ubuntu-latest"
steps:
- name: Trigger Cast build
run: curl -X POST -d {} https://api.netlify.com/build_hooks/${{ secrets.NETLIFY_CAST_DEV_BUILD_HOOK }}
- name: Trigger Demo build
run: curl -X POST -d {} https://api.netlify.com/build_hooks/${{ secrets.NETLIFY_DEMO_DEV_BUILD_HOOK }}
- name: Trigger Gallery build
run: curl -X POST -d {} https://api.netlify.com/build_hooks/${{ secrets.NETLIFY_GALLERY_DEV_BUILD_HOOK }}
+81
View File
@@ -0,0 +1,81 @@
name: Release
on:
release:
types:
- published
env:
WHEELS_TAG: 3.7-alpine3.11
PYTHON_VERSION: 3.7
NODE_VERSION: 12.1
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v2
- name: Verify version
uses: home-assistant/actions/helpers/verify-version@master
- name: Set up Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v2
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Set up Node ${{ env.NODE_VERSION }}
uses: actions/setup-node@v2
with:
node-version: ${{ env.NODE_VERSION }}
- name: Build and release package
run: |
python3 -m pip install twine
export TWINE_USERNAME="__token__"
export TWINE_PASSWORD="${{ secrets.TWINE_TOKEN }}"
script/release
wheels-init:
name: Init wheels build
needs: release
runs-on: ubuntu-latest
steps:
- name: Generate requirements.txt
run: |
# Sleep to give pypi time to populate the new version across mirrors
sleep 240
version=$(echo "${{ github.ref }}" | awk -F"/" '{print $NF}' )
echo "home-assistant-frontend==$version" > ./requirements.txt
- name: Upload requirements.txt
uses: actions/upload-artifact@v2
with:
name: requirements
path: ./requirements.txt
build-wheels:
name: Build wheels for ${{ matrix.arch }}
needs: wheels-init
runs-on: ubuntu-latest
strategy:
matrix:
arch: ["aarch64", "armhf", "armv7", "amd64", "i386"]
steps:
- name: Download requirements.txt
uses: actions/download-artifact@v2
with:
name: requirements
- name: Build wheels
uses: home-assistant/wheels@master
with:
tag: ${{ env.WHEELS_TAG }}
arch: ${{ matrix.arch }}
wheels-host: ${{ secrets.WHEELS_HOST }}
wheels-key: ${{ secrets.WHEELS_KEY }}
wheels-user: wheels
requirements: "requirements.txt"
+65
View File
@@ -0,0 +1,65 @@
name: Translations
on:
schedule:
- cron: "30 0 * * *"
push:
branches:
- dev
paths:
- src/translations/en.json
env:
NODE_VERSION: 12
jobs:
upload:
name: Upload
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v2
- name: Set up Node ${{ env.NODE_VERSION }}
uses: actions/setup-node@v2
with:
node-version: ${{ env.NODE_VERSION }}
- name: Upload Translations
run: |
export LOKALISE_TOKEN="${{ secrets.LOKALISE_TOKEN }}"
./script/translations_upload_base
download:
name: Download
needs: upload
if: github.event_name == 'schedule'
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v2
- name: Set up Node ${{ env.NODE_VERSION }}
uses: actions/setup-node@v2
with:
node-version: ${{ env.NODE_VERSION }}
- name: Download Translations
run: |
export LOKALISE_TOKEN="${{ secrets.LOKALISE_TOKEN }}"
npm install
./script/translations_download
- name: Initialize git
uses: home-assistant/actions/helpers/git-init@master
with:
name: GitHub Action
email: [email protected]
- name: Update translation
run: |
git add translations
git commit -am "Translation update"
git push
+3
View File
@@ -35,3 +35,6 @@ yarn-error.log
#asdf
.tool-versions
# Home Assistant config
/config
-6
View File
@@ -1,6 +0,0 @@
jshint:
enabled: false
eslint:
enabled: true
config_file: .eslintrc-hound.json
+71
View File
@@ -37,6 +37,37 @@
"instanceLimit": 1
}
},
{
"label": "Develop Supervisor panel",
"type": "gulp",
"task": "develop-hassio",
"problemMatcher": {
"owner": "ha-build",
"source": "ha-build",
"fileLocation": "absolute",
"severity": "error",
"pattern": [
{
"regexp": "(SyntaxError): (.+): (.+) \\((\\d+):(\\d+)\\)",
"severity": 1,
"file": 2,
"message": 3,
"line": 4,
"column": 5
}
],
"background": {
"activeOnStart": true,
"beginsPattern": "Changes detected. Starting compilation",
"endsPattern": "Build done @"
}
},
"isBackground": true,
"group": "build",
"runOptions": {
"instanceLimit": 1
}
},
{
"label": "Develop Gallery",
"type": "gulp",
@@ -133,5 +164,45 @@
"instanceLimit": 1
}
},
{
"label": "Run HA Core in devcontainer",
"type": "shell",
"command": "script/core",
"isBackground": true,
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [],
"runOptions": {
"instanceLimit": 1
}
},
{
"label": "Run HA Core for Supervisor in devcontainer",
"type": "shell",
"command": "HASSIO=${input:supervisorHost} HASSIO_TOKEN=${input:supervisorToken} script/core",
"isBackground": true,
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [],
"runOptions": {
"instanceLimit": 1
}
}
],
"inputs": [
{
"id": "supervisorHost",
"type": "promptString",
"description": "The IP of the Supervisor host running the Remote API proxy add-on"
},
{
"id": "supervisorToken",
"type": "promptString",
"description": "The token for the Remote API proxy add-on"
}
]
}
+1 -1
View File
@@ -14,7 +14,7 @@ This is the repository for the official [Home Assistant](https://home-assistant.
- Development: [Instructions](https://developers.home-assistant.io/docs/frontend/development/)
- Production build: `script/build_frontend`
- Gallery: `cd gallery && script/develop_gallery`
- Hass.io: [Instructions](https://developers.home-assistant.io/docs/en/hassio_hass.html)
- Supervisor: [Instructions](https://developers.home-assistant.io/docs/supervisor/developing)
## Frontend development
-30
View File
@@ -1,30 +0,0 @@
# https://dev.azure.com/home-assistant
trigger: none
pr: none
schedules:
- cron: "0 0 * * *"
displayName: "build preview"
branches:
include:
- dev
always: true
variables:
- group: netlify
jobs:
- job: 'Netlify_preview'
pool:
vmImage: 'ubuntu-latest'
steps:
- script: |
# Cast
curl -X POST -d {} https://api.netlify.com/build_hooks/${NETLIFY_CAST}
# Demo
curl -X POST -d {} https://api.netlify.com/build_hooks/${NETLIFY_DEMO}
# Gallery
curl -X POST -d {} https://api.netlify.com/build_hooks/${NETLIFY_GALLERY}
displayName: 'Trigger netlify build preview'
-59
View File
@@ -1,59 +0,0 @@
# https://dev.azure.com/home-assistant
trigger:
batch: true
tags:
include:
- "*"
pr: none
variables:
- name: versionWheels
value: '1.10.1-3.7-alpine3.11'
- name: versionNode
value: '12.1'
- group: twine
resources:
repositories:
- repository: azure
type: github
name: 'home-assistant/ci-azure'
endpoint: 'home-assistant'
stages:
- stage: "Validate"
jobs:
- template: templates/azp-job-version.yaml@azure
- stage: "Build"
jobs:
- job: "ReleasePython"
pool:
vmImage: "ubuntu-latest"
steps:
- task: UsePythonVersion@0
displayName: "Use Python 3.7"
inputs:
versionSpec: "3.7"
- task: NodeTool@0
displayName: "Use Node $(versionNode)"
inputs:
versionSpec: "$(versionNode)"
- script: pip install twine wheel
displayName: "Install tools"
- script: |
export TWINE_USERNAME="$(twineUser)"
export TWINE_PASSWORD="$(twinePassword)"
script/release
displayName: "Build and release package"
- stage: "Wheels"
jobs:
- template: templates/azp-job-wheels.yaml@azure
parameters:
builderVersion: '$(versionWheels)'
wheelsRequirement: 'requirement.txt'
preBuild:
- script: |
sleep 240
echo "home-assistant-frontend==$(Build.SourceBranchName)" > requirement.txt
-70
View File
@@ -1,70 +0,0 @@
# https://dev.azure.com/home-assistant
trigger:
batch: true
branches:
include:
- dev
paths:
include:
- translations/en.json
pr: none
schedules:
- cron: "30 0 * * *"
displayName: "frontend translation update"
branches:
include:
- dev
always: true
variables:
- group: translation
resources:
repositories:
- repository: azure
type: github
name: 'home-assistant/ci-azure'
endpoint: 'home-assistant'
jobs:
- job: 'Upload'
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
displayName: 'Use Node 12.x'
inputs:
versionSpec: '12.x'
- script: |
export LOKALISE_TOKEN="$(lokaliseToken)"
export AZURE_BRANCH="$(Build.SourceBranchName)"
./script/translations_upload_base
displayName: 'Upload Translation'
- job: 'Download'
dependsOn:
- 'Upload'
condition: or(eq(variables['Build.Reason'], 'Schedule'), eq(variables['Build.Reason'], 'Manual'))
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
displayName: 'Use Node 12.x'
inputs:
versionSpec: '12.x'
- template: templates/azp-step-git-init.yaml@azure
- script: |
export LOKALISE_TOKEN="$(lokaliseToken)"
export AZURE_BRANCH="$(Build.SourceBranchName)"
npm install
./script/translations_download
displayName: 'Download Translation'
- script: |
git checkout dev
git add translation
git commit -am "[ci skip] Translation update"
git push
displayName: 'Update translation'
+39
View File
@@ -0,0 +1,39 @@
# Bundling Home Assistant Frontend
The Home Assistant build pipeline contains various steps to prepare a build.
- Generating icon files to be included
- Generating translation files to be included
- Converting TypeScript, CSS and JSON files to JavaScript
- Bundling
- Minifying the files
- Generating the HTML entrypoint files
- Generating the service worker
- Compressing the files
## Converting files
Currently in Home Assistant we use a bundler to convert TypeScript, CSS and JSON files to JavaScript files that the browser understands.
We currently rely on Webpack but also have experimental Rollup support. Both of these programs bundle the converted files in both production and development.
For development, bundling is optional. We just want to get the right files in the browser.
Responsibilities of the converter during development:
- Convert TypeScript to JavaScript
- Convert CSS to JavaScript that sets the content as the default export
- Convert JSON to JavaScript that sets the content as the default export
- Make sure import, dynamic import and web worker references work
- Add extensions where missing
- Resolve absolute package imports
- Filter out specific imports/packages
- Replace constants with values
In production, the following responsibilities are added:
- Minify HTML
- Bundle multiple imports so that the browser can fetch less files
- Generate a second version that is ES5 compatible
Configuration for all these steps are specified in [bundle.js](bundle.js).
+3 -2
View File
@@ -44,7 +44,7 @@ module.exports.definedVars = ({ isProdBuild, latestBuild, defineOverlay }) => ({
});
module.exports.terserOptions = (latestBuild) => ({
safari10: true,
safari10: !latestBuild,
ecma: latestBuild ? undefined : 5,
output: { comments: false },
});
@@ -117,7 +117,7 @@ BundleConfig {
*/
module.exports.config = {
app({ isProdBuild, latestBuild, isStatsBuild }) {
app({ isProdBuild, latestBuild, isStatsBuild, isWDS }) {
return {
entry: {
service_worker: "./src/entrypoints/service_worker.ts",
@@ -132,6 +132,7 @@ module.exports.config = {
isProdBuild,
latestBuild,
isStatsBuild,
isWDS,
};
},
+3
View File
@@ -6,6 +6,9 @@ module.exports = {
useRollup() {
return process.env.ROLLUP === "1";
},
useWDS() {
return process.env.WDS === "1";
},
isProdBuild() {
return (
process.env.NODE_ENV === "production" || module.exports.isStatsBuild()
+6 -1
View File
@@ -12,6 +12,7 @@ require("./webpack.js");
require("./service-worker.js");
require("./entry-html.js");
require("./rollup.js");
require("./wds.js");
gulp.task(
"develop-app",
@@ -28,7 +29,11 @@ gulp.task(
"build-translations"
),
"copy-static-app",
env.useRollup() ? "rollup-watch-app" : "webpack-watch-app"
env.useWDS()
? "wds-watch-app"
: env.useRollup()
? "rollup-watch-app"
: "webpack-watch-app"
)
);
+17 -3
View File
@@ -19,6 +19,7 @@ const renderTemplate = (pth, data = {}, pathFunc = templatePath) => {
return compiled({
...data,
useRollup: env.useRollup(),
useWDS: env.useWDS(),
renderTemplate,
});
};
@@ -90,10 +91,23 @@ gulp.task("gen-pages-prod", (done) => {
});
gulp.task("gen-index-app-dev", (done) => {
let latestAppJS, latestCoreJS, latestCustomPanelJS;
if (env.useWDS()) {
latestAppJS = "http://localhost:8000/src/entrypoints/app.ts";
latestCoreJS = "http://localhost:8000/src/entrypoints/core.ts";
latestCustomPanelJS =
"http://localhost:8000/src/entrypoints/custom-panel.ts";
} else {
latestAppJS = "/frontend_latest/app.js";
latestCoreJS = "/frontend_latest/core.js";
latestCustomPanelJS = "/frontend_latest/custom-panel.js";
}
const content = renderTemplate("index", {
latestAppJS: "/frontend_latest/app.js",
latestCoreJS: "/frontend_latest/core.js",
latestCustomPanelJS: "/frontend_latest/custom-panel.js",
latestAppJS,
latestCoreJS,
latestCustomPanelJS,
es5AppJS: "/frontend_es5/app.js",
es5CoreJS: "/frontend_es5/core.js",
+5
View File
@@ -85,6 +85,11 @@ gulp.task("copy-translations-app", async () => {
copyTranslations(staticDir);
});
gulp.task("copy-translations-supervisor", async () => {
const staticDir = paths.hassio_output_static;
copyTranslations(staticDir);
});
gulp.task("copy-static-app", async () => {
const staticDir = paths.app_output_static;
// Basic static files
+6
View File
@@ -10,6 +10,8 @@ require("./gen-icons-json.js");
require("./webpack.js");
require("./compress.js");
require("./rollup.js");
require("./gather-static.js");
require("./translations.js");
gulp.task(
"develop-hassio",
@@ -20,6 +22,8 @@ gulp.task(
"clean-hassio",
"gen-icons-json",
"gen-index-hassio-dev",
"build-supervisor-translations",
"copy-translations-supervisor",
env.useRollup() ? "rollup-watch-hassio" : "webpack-watch-hassio"
)
);
@@ -32,6 +36,8 @@ gulp.task(
},
"clean-hassio",
"gen-icons-json",
"build-supervisor-translations",
"copy-translations-supervisor",
env.useRollup() ? "rollup-prod-hassio" : "webpack-prod-hassio",
"gen-index-hassio-prod",
...// Don't compress running tests
+76 -52
View File
@@ -33,21 +33,10 @@ String.prototype.rsplit = function (sep, maxsplit) {
: split;
};
// Panel translations which should be split from the core translations. These
// should mirror the fragment definitions in polymer.json, so that we load
// additional resources at equivalent points.
const TRANSLATION_FRAGMENTS = [
"config",
"history",
"logbook",
"mailbox",
"profile",
"shopping-list",
"page-authorize",
"page-demo",
"page-onboarding",
"developer-tools",
];
// Panel translations which should be split from the core translations.
const TRANSLATION_FRAGMENTS = Object.keys(
require("../../src/translations/en.json").ui.panel
);
function recursiveFlatten(prefix, data) {
let output = {};
@@ -277,6 +266,7 @@ gulp.task(taskName, function () {
TRANSLATION_FRAGMENTS.forEach((fragment) => {
delete data.ui.panel[fragment];
});
delete data.supervisor;
return data;
})
)
@@ -353,6 +343,62 @@ gulp.task(
}
);
gulp.task("build-translation-fragment-supervisor", function () {
return gulp
.src(fullDir + "/*.json")
.pipe(transform((data) => data.supervisor))
.pipe(gulp.dest(workDir + "/supervisor"));
});
gulp.task("build-translation-flatten-supervisor", function () {
return gulp
.src(workDir + "/supervisor/*.json")
.pipe(
transform(function (data) {
// Polymer.AppLocalizeBehavior requires flattened json
return flatten(data);
})
)
.pipe(gulp.dest(outDir));
});
gulp.task("build-translation-write-metadata", function writeMetadata() {
return gulp
.src(
[
path.join(paths.translations_src, "translationMetadata.json"),
workDir + "/testMetadata.json",
workDir + "/translationFingerprints.json",
],
{ allowEmpty: true }
)
.pipe(merge({}))
.pipe(
transform(function (data) {
const newData = {};
Object.entries(data).forEach(([key, value]) => {
// Filter out translations without native name.
if (value.nativeName) {
newData[key] = value;
} else {
console.warn(
`Skipping language ${key}. Native name was not translated.`
);
}
});
return newData;
})
)
.pipe(
transform((data) => ({
fragments: TRANSLATION_FRAGMENTS,
translations: data,
}))
)
.pipe(rename("translationMetadata.json"))
.pipe(gulp.dest(workDir));
});
gulp.task(
"build-translations",
gulp.series(
@@ -364,42 +410,20 @@ gulp.task(
gulp.parallel(...splitTasks),
"build-flattened-translations",
"build-translation-fingerprints",
function writeMetadata() {
return gulp
.src(
[
path.join(paths.translations_src, "translationMetadata.json"),
workDir + "/testMetadata.json",
workDir + "/translationFingerprints.json",
],
{ allowEmpty: true }
)
.pipe(merge({}))
.pipe(
transform(function (data) {
const newData = {};
Object.entries(data).forEach(([key, value]) => {
// Filter out translations without native name.
if (data[key].nativeName) {
newData[key] = data[key];
} else {
console.warn(
`Skipping language ${key}. Native name was not translated.`
);
}
if (data[key]) newData[key] = value;
});
return newData;
})
)
.pipe(
transform((data) => ({
fragments: TRANSLATION_FRAGMENTS,
translations: data,
}))
)
.pipe(rename("translationMetadata.json"))
.pipe(gulp.dest(workDir));
}
"build-translation-write-metadata"
)
);
gulp.task(
"build-supervisor-translations",
gulp.series(
"clean-translations",
"ensure-translations-build-dir",
"build-master-translation",
"build-merged-translations",
"build-translation-fragment-supervisor",
"build-translation-flatten-supervisor",
"build-translation-fingerprints",
"build-translation-write-metadata"
)
);
+11
View File
@@ -0,0 +1,11 @@
// Tasks to run Rollup
const gulp = require("gulp");
const { startDevServer } = require("@web/dev-server");
gulp.task("wds-watch-app", () => {
startDevServer({
config: {
watch: true,
},
});
});
+50 -61
View File
@@ -47,7 +47,7 @@ const runDevServer = ({
);
});
const handler = (done) => (err, stats) => {
const doneHandler = (done) => (err, stats) => {
if (err) {
log.error(err.stack || err);
if (err.details) {
@@ -67,11 +67,20 @@ const handler = (done) => (err, stats) => {
}
};
const prodBuild = (conf) =>
new Promise((resolve) => {
webpack(
conf,
// Resolve promise when done. Because we pass a callback, webpack closes itself
doneHandler(resolve)
);
});
gulp.task("webpack-watch-app", () => {
// we are not calling done, so this command will run forever
// This command will run forever because we don't close compiler
webpack(createAppConfig({ isProdBuild: false, latestBuild: true })).watch(
{ ignored: /build-translations/ },
handler()
doneHandler()
);
gulp.watch(
path.join(paths.translations_src, "en.json"),
@@ -79,15 +88,12 @@ gulp.task("webpack-watch-app", () => {
);
});
gulp.task(
"webpack-prod-app",
() =>
new Promise((resolve) =>
webpack(
bothBuilds(createAppConfig, { isProdBuild: true }),
handler(resolve)
)
)
gulp.task("webpack-prod-app", () =>
prodBuild(
bothBuilds(createAppConfig, {
isProdBuild: true,
})
)
);
gulp.task("webpack-dev-server-demo", () => {
@@ -98,17 +104,12 @@ gulp.task("webpack-dev-server-demo", () => {
});
});
gulp.task(
"webpack-prod-demo",
() =>
new Promise((resolve) =>
webpack(
bothBuilds(createDemoConfig, {
isProdBuild: true,
}),
handler(resolve)
)
)
gulp.task("webpack-prod-demo", () =>
prodBuild(
bothBuilds(createDemoConfig, {
isProdBuild: true,
})
)
);
gulp.task("webpack-dev-server-cast", () => {
@@ -121,41 +122,35 @@ gulp.task("webpack-dev-server-cast", () => {
});
});
gulp.task(
"webpack-prod-cast",
() =>
new Promise((resolve) =>
webpack(
bothBuilds(createCastConfig, {
isProdBuild: true,
}),
handler(resolve)
)
)
gulp.task("webpack-prod-cast", () =>
prodBuild(
bothBuilds(createCastConfig, {
isProdBuild: true,
})
)
);
gulp.task("webpack-watch-hassio", () => {
// we are not calling done, so this command will run forever
// This command will run forever because we don't close compiler
webpack(
createHassioConfig({
isProdBuild: false,
latestBuild: true,
})
).watch({}, handler());
).watch({ ignored: /build-translations/ }, doneHandler());
gulp.watch(
path.join(paths.translations_src, "en.json"),
gulp.series("build-supervisor-translations", "copy-translations-supervisor")
);
});
gulp.task(
"webpack-prod-hassio",
() =>
new Promise((resolve) =>
webpack(
bothBuilds(createHassioConfig, {
isProdBuild: true,
}),
handler(resolve)
)
)
gulp.task("webpack-prod-hassio", () =>
prodBuild(
bothBuilds(createHassioConfig, {
isProdBuild: true,
})
)
);
gulp.task("webpack-dev-server-gallery", () => {
@@ -167,17 +162,11 @@ gulp.task("webpack-dev-server-gallery", () => {
});
});
gulp.task(
"webpack-prod-gallery",
() =>
new Promise((resolve) =>
webpack(
createGalleryConfig({
isProdBuild: true,
latestBuild: true,
}),
handler(resolve)
)
)
gulp.task("webpack-prod-gallery", () =>
prodBuild(
createGalleryConfig({
isProdBuild: true,
latestBuild: true,
})
)
);
+1
View File
@@ -34,6 +34,7 @@ module.exports = {
hassio_dir: path.resolve(__dirname, "../hassio"),
hassio_output_root: path.resolve(__dirname, "../hassio/build"),
hassio_output_static: path.resolve(__dirname, "../hassio/build/static"),
hassio_output_latest: path.resolve(
__dirname,
"../hassio/build/frontend_latest"
@@ -1,5 +1,3 @@
const path = require("path");
module.exports = function (userOptions = {}) {
// Files need to be absolute paths.
// This only works if the file has no exports
+15 -10
View File
@@ -3,7 +3,7 @@ const path = require("path");
const commonjs = require("@rollup/plugin-commonjs");
const resolve = require("@rollup/plugin-node-resolve");
const json = require("@rollup/plugin-json");
const babel = require("rollup-plugin-babel");
const babel = require("@rollup/plugin-babel").babel;
const replace = require("@rollup/plugin-replace");
const visualizer = require("rollup-plugin-visualizer");
const { string } = require("rollup-plugin-string");
@@ -31,6 +31,7 @@ const createRollupConfig = ({
isStatsBuild,
publicPath,
dontHash,
isWDS,
}) => {
return {
/**
@@ -61,6 +62,7 @@ const createRollupConfig = ({
...bundle.babelOptions({ latestBuild }),
extensions,
exclude: bundle.babelExclude(),
babelHelpers: isWDS ? "inline" : "bundled",
}),
string({
// Import certain extensions as strings
@@ -69,19 +71,21 @@ const createRollupConfig = ({
replace(
bundle.definedVars({ isProdBuild, latestBuild, defineOverlay })
),
manifest({
publicPath,
}),
worker(),
dontHashPlugin({ dontHash }),
isProdBuild && terser(bundle.terserOptions(latestBuild)),
isStatsBuild &&
!isWDS &&
manifest({
publicPath,
}),
!isWDS && worker(),
!isWDS && dontHashPlugin({ dontHash }),
!isWDS && isProdBuild && terser(bundle.terserOptions(latestBuild)),
!isWDS &&
isStatsBuild &&
visualizer({
// https://github.com/btd/rollup-plugin-visualizer#options
open: true,
sourcemap: true,
}),
],
].filter(Boolean),
},
/**
* @type { import("rollup").OutputOptions }
@@ -108,12 +112,13 @@ const createRollupConfig = ({
};
};
const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => {
const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild, isWDS }) => {
return createRollupConfig(
bundle.config.app({
isProdBuild,
latestBuild,
isStatsBuild,
isWDS,
})
);
};
+3 -18
View File
@@ -1,7 +1,7 @@
const webpack = require("webpack");
const path = require("path");
const TerserPlugin = require("terser-webpack-plugin");
const ManifestPlugin = require("webpack-manifest-plugin");
const { WebpackManifestPlugin } = require("webpack-manifest-plugin");
const paths = require("./paths.js");
const bundle = require("./bundle");
const log = require("fancy-log");
@@ -36,6 +36,7 @@ const createWebpackConfig = ({
const ignorePackages = bundle.ignorePackages({ latestBuild });
return {
mode: isProdBuild ? "production" : "development",
target: ["web", latestBuild ? "es2017" : "es5"],
devtool: isProdBuild
? "cheap-module-source-map"
: "eval-cheap-module-source-map",
@@ -67,7 +68,7 @@ const createWebpackConfig = ({
],
},
plugins: [
new ManifestPlugin({
new WebpackManifestPlugin({
// Only include the JS of entrypoints
filter: (file) => file.isInitial && !file.name.endsWith(".map"),
}),
@@ -131,22 +132,6 @@ const createWebpackConfig = ({
}
return `${chunk.name}.${chunk.hash.substr(0, 8)}.js`;
},
environment: {
// The environment supports arrow functions ('() => { ... }').
arrowFunction: latestBuild,
// The environment supports BigInt as literal (123n).
bigIntLiteral: false,
// The environment supports const and let for variable declarations.
const: latestBuild,
// The environment supports destructuring ('{ a, b } = obj').
destructuring: latestBuild,
// The environment supports an async import() function to import EcmaScript modules.
dynamicImport: latestBuild,
// The environment supports 'for of' iteration ('for (const x of array) { ... }').
forOf: latestBuild,
// The environment supports ECMAScript Module syntax to import ECMAScript modules (import ... from '...').
module: latestBuild,
},
chunkFilename:
isProdBuild && !isStatsBuild
? "chunk.[chunkhash].js"
+1 -1
View File
@@ -48,7 +48,7 @@ class HcCast extends LitElement {
protected render(): TemplateResult {
if (this.lovelaceConfig === undefined) {
return html` <hass-loading-screen no-toolbar></hass-loading-screen>> `;
return html`<hass-loading-screen no-toolbar></hass-loading-screen>`;
}
const error =
+4
View File
@@ -98,8 +98,12 @@ class HcLayout extends LitElement {
line-height: 32px;
padding: 24px 16px 16px;
display: block;
margin: 0;
}
.hero {
border-radius: 4px 4px 0 0;
}
.subtitle {
font-size: 14px;
color: var(--secondary-text-color);
+1 -1
View File
@@ -1,8 +1,8 @@
import {
customElement,
html,
property,
internalProperty,
property,
TemplateResult,
} from "lit-element";
import { mockHistory } from "../../../../demo/src/stubs/history";
+1
View File
@@ -94,6 +94,7 @@ class HcLovelace extends LitElement {
return css`
:host {
min-height: 100vh;
height: 0;
display: flex;
flex-direction: column;
box-sizing: border-box;
+1 -1
View File
@@ -1,4 +1,4 @@
import "web-animations-js/web-animations-next-lite.min";
import "../../../src/resources/roboto";
import "../../../src/resources/ha-style";
import "../../../src/resources/roboto";
import "./layout/hc-lovelace";
+6 -2
View File
@@ -54,6 +54,8 @@ export const demoEntitiesArsaboo: DemoConfig["entities"] = (localize) =>
state: "21",
attributes: {
friendly_name: "Living room temperature",
device_class: "temperature",
unit_of_measurement: "°C",
},
},
"sensor.study_temp_rounded": {
@@ -61,6 +63,8 @@ export const demoEntitiesArsaboo: DemoConfig["entities"] = (localize) =>
state: "23",
attributes: {
friendly_name: "Study temperature",
device_class: "temperature",
unit_of_measurement: "°C",
},
},
"sensor.living_room": {
@@ -261,7 +265,7 @@ export const demoEntitiesArsaboo: DemoConfig["entities"] = (localize) =>
entity_id: "light.kitchen_lights",
state: "off",
attributes: {
friendly_name: "Kitchen lights",
friendly_name: "Kitchen Lights",
supported_features: 1,
},
},
@@ -484,7 +488,7 @@ export const demoEntitiesArsaboo: DemoConfig["entities"] = (localize) =>
attributes: {
min_mireds: 111,
max_mireds: 400,
friendly_name: "Garage lights",
friendly_name: "Garage Lights",
supported_features: 55,
},
},
+1
View File
@@ -12,6 +12,7 @@ export const demoLovelaceArsaboo: DemoConfig["lovelace"] = (localize) => ({
{
type: "entities",
title: localize("ui.panel.page-demo.config.arsaboo.labels.lights"),
state_color: true,
entities: [
{
entity: "light.kitchen_lights",
+4 -16
View File
@@ -3,22 +3,10 @@ import { Lovelace } from "../../../src/panels/lovelace/types";
import { DemoConfig } from "./types";
export const demoConfigs: Array<() => Promise<DemoConfig>> = [
() =>
import(/* webpackChunkName: "arsaboo" */ "./arsaboo").then(
(mod) => mod.demoArsaboo
),
() =>
import(/* webpackChunkName: "teachingbirds" */ "./teachingbirds").then(
(mod) => mod.demoTeachingbirds
),
() =>
import(/* webpackChunkName: "kernehed" */ "./kernehed").then(
(mod) => mod.demoKernehed
),
() =>
import(/* webpackChunkName: "jimpower" */ "./jimpower").then(
(mod) => mod.demoJimpower
),
() => import("./arsaboo").then((mod) => mod.demoArsaboo),
() => import("./teachingbirds").then((mod) => mod.demoTeachingbirds),
() => import("./kernehed").then((mod) => mod.demoKernehed),
() => import("./jimpower").then((mod) => mod.demoJimpower),
];
// eslint-disable-next-line import/no-mutable-exports
+2 -2
View File
@@ -653,7 +653,7 @@ export const demoEntitiesJimpower: DemoConfig["entities"] = () =>
entity_id: "binary_sensor.smoke_sensor_158d0001b8ddc7",
state: "off",
attributes: {
Density: 0,
density: 0,
battery_level: 59,
friendly_name: "Downstairs Smoke Detector",
device_class: "smoke",
@@ -663,7 +663,7 @@ export const demoEntitiesJimpower: DemoConfig["entities"] = () =>
entity_id: "binary_sensor.smoke_sensor_158d0001b8deba",
state: "off",
attributes: {
Density: 0,
density: 0,
battery_level: 65,
friendly_name: "Upstairs Smoke Detector",
device_class: "smoke",
+6 -181
View File
@@ -3,49 +3,7 @@ import { DemoConfig } from "../types";
export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
name: "Kingia Castle",
resources: [
// {
// url: "/local/custom_ui/dark-sky-weather-card.js?v=4",
// type: "js",
// },
// {
// url: "/local/custom_ui/mini-media-player-bundle.js?v=0.9.8",
// type: "module",
// },
// {
// url: "/local/custom_ui/tracker-card.js?v=0.1.5",
// type: "js",
// },
// {
// url: "/local/custom_ui/surveillance-card.js?v=0.0.1",
// type: "module",
// },
// {
// url: "/local/custom_ui/mini-graph-card-bundle.js?v=0.1.0",
// type: "module",
// },
// {
// url: "/local/custom_ui/slider-entity-row.js?v=d6da75",
// type: "js",
// },
// {
// url:
// "/local/custom_ui/compact-custom-header/compact-custom-header.js?v=0.2.7",
// type: "js",
// },
// {
// url: "/local/custom_ui/waze-card.js?v=1.1.1",
// type: "js",
// },
// {
// url: "/local/custom_ui/circle-sensor-card.js?v=1.2.0",
// type: "module",
// },
// {
// url: "/local/custom_ui/monster-card.js?v=0.2.3",
// type: "js",
// },
],
resources: [],
views: [
{
cards: [
@@ -603,89 +561,6 @@ export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
},
{
cards: [
// {
// style: {
// "background-image": 'url("/assets/jimpower/cardbackK.png")',
// "background-size": "100% 400px",
// "box-shadow": "3px 3px rgba(0,0,0,0.4)",
// "background-repeat": "no-repeat",
// color: "#999999",
// "border-radius": "20px",
// border: "solid 1px rgba(100,100,100,0.3)",
// "background-color": "rgba(50,50,50,0.3)",
// },
// type: "custom:card-modder",
// card: {
// entity_visibility: "sensor.dark_sky_visibility",
// entity_sun: "sun.sun",
// entity_daily_summary:
// "sensor.bom_gc_forecast_detailed_summary_0",
// entity_temperature: "sensor.bom_temp",
// entity_forecast_high_temp_3:
// "sensor.bom_gc_forecast_max_temp_c_3",
// entity_forecast_high_temp_2:
// "sensor.bom_gc_forecast_max_temp_c_2",
// entity_forecast_high_temp_5:
// "sensor.bom_gc_forecast_max_temp_c_5",
// entity_forecast_high_temp_4:
// "sensor.bom_gc_forecast_max_temp_c_4",
// entity_wind_speed: "sensor.bom_wind_sp",
// entity_forecast_icon_4: "sensor.dark_sky_icon_4",
// entity_forecast_icon_5: "sensor.dark_sky_icon_5",
// entity_forecast_icon_2: "sensor.dark_sky_icon_2",
// entity_forecast_icon_3: "sensor.dark_sky_icon_3",
// entity_forecast_icon_1: "sensor.dark_sky_icon_1",
// entity_forecast_high_temp_1:
// "sensor.bom_gc_forecast_max_temp_c_1",
// entity_wind_bearing: "sensor.bom_wind_bear",
// entity_forecast_low_temp_2:
// "sensor.bom_gc_forecast_min_temp_c_2",
// entity_forecast_low_temp_3:
// "sensor.bom_gc_forecast_min_temp_c_3",
// entity_pressure: "sensor.bom_pres",
// entity_forecast_low_temp_1:
// "sensor.bom_gc_forecast_min_temp_c_1",
// entity_forecast_low_temp_4:
// "sensor.bom_gc_forecast_min_temp_c_4",
// entity_forecast_low_temp_5:
// "sensor.bom_gc_forecast_min_temp_c_5",
// entity_humidity: "sensor.bom_humd",
// type: "custom:dark-sky-weather-card",
// entity_current_conditions: "sensor.dark_sky_icon",
// },
// },
// {
// style: {
// "background-image": 'url("/assets/jimpower/home/waze_5.png")',
// "background-size": "100% 400px",
// "box-shadow": "3px 3px rgba(0,0,0,0.4)",
// "background-repeat": "no-repeat",
// "border-radius": "20px",
// border: "solid 1px rgba(100,100,100,0.3)",
// "background-color": "rgba(50,50,50,0.3)",
// },
// type: "custom:card-modder",
// card: {
// entities: [
// {
// name: "James",
// zone: "zone.home",
// entity: "sensor.james_to_home",
// },
// {
// name: "Tina",
// zone: "zone.home",
// entity: "sensor.tina_to_home",
// },
// {
// name: "Work",
// zone: "zone.powertec",
// entity: "sensor.commute_to_work",
// },
// ],
// type: "custom:waze-card",
// },
// },
{
style: {
"border-radius": "20px",
@@ -722,46 +597,8 @@ export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
],
type: "vertical-stack",
},
// {
// cards: [
// {
// style: {
// "border-radius": "20px",
// color: "#999999",
// "box-shadow": "3px 3px rgba(0,0,0,0.4)",
// border: "solid 1px rgba(100,100,100,0.3)",
// },
// type: "custom:card-modder",
// card: {
// type: "picture-entity",
// entity: "camera.bom_radar",
// },
// },
// // {
// // style: {
// // "background-image": 'url("/assets/jimpower/cardbackK.png")',
// // "background-size": "100% 525px",
// // "box-shadow": "3px 3px rgba(0,0,0,0.4)",
// // "background-repeat": "no-repeat",
// // color: "#999999",
// // "border-radius": "20px",
// // border: "solid 1px rgba(100,100,100,0.3)",
// // "background-color": "rgba(50,50,50,0.3)",
// // },
// // type: "custom:card-modder",
// // card: {
// // title: null,
// // type: "custom:tracker-card",
// // trackers: [
// // "sensor.custom_card_tracker",
// // "sensor.custom_component_tracker",
// // ],
// // },
// // },
// ],
// type: "vertical-stack",
// },
],
path: "home",
icon: "mdi:castle",
name: "Home",
background:
@@ -881,26 +718,13 @@ export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
card: {
image: "/assets/jimpower/security/air_8.jpg",
elements: [
{
image:
"https://www.airvisual.com/assets/aqi/ic-face-1-green.svg",
type: "image",
style: {
width: "80px",
top: "30%",
left: "12%",
transform: "none",
height: "80px",
},
entity: "sensor.us_air_pollution_level_2",
},
{
style: {
color: "hsl(120, 41%, 39%)",
top: "50%",
"font-weight": 600,
"font-size": "20px",
left: "44%",
"font-size": "50px",
left: "30%",
},
type: "state-label",
entity: "sensor.us_air_pollution_level_2",
@@ -920,7 +744,7 @@ export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
style: {
color: "white",
top: "80%",
left: "52%",
left: "48%",
},
type: "state-icon",
entity: "sensor.us_main_pollutant_2",
@@ -1411,6 +1235,7 @@ export const demoLovelaceJimpower: DemoConfig["lovelace"] = () => ({
type: "vertical-stack",
},
],
path: "security",
icon: "hass:shield-home",
name: "Security",
background:
+10 -5
View File
@@ -101,7 +101,12 @@ export const demoEntitiesKernehed: DemoConfig["entities"] = () =>
"sensor.zwave_battery_front_door": {
entity_id: "sensor.zwave_battery_front_door",
state: "63",
attributes: { friendly_name: "Battery", icon: "mdi:battery-60" },
attributes: {
friendly_name: "Battery",
icon: "mdi:battery-60",
unit_of_measurement: "%",
device_class: "battery",
},
},
"sensor.oskar_devices": {
entity_id: "sensor.oskar_devices",
@@ -164,7 +169,7 @@ export const demoEntitiesKernehed: DemoConfig["entities"] = () =>
},
"input_select.christmas_pattern": {
entity_id: "input_select.christmas_pattern",
state: "None",
state: "Rainbow",
attributes: {
options: [
"None",
@@ -186,7 +191,7 @@ export const demoEntitiesKernehed: DemoConfig["entities"] = () =>
},
"input_select.christmas_palette": {
entity_id: "input_select.christmas_palette",
state: "None",
state: "Party",
attributes: {
options: [
"None",
@@ -457,7 +462,7 @@ export const demoEntitiesKernehed: DemoConfig["entities"] = () =>
state: "0.0",
attributes: {
unit_of_measurement: "kB/s",
friendly_name: "Nedladdning",
friendly_name: "Downloading",
icon: "mdi:file-download",
},
},
@@ -471,7 +476,7 @@ export const demoEntitiesKernehed: DemoConfig["entities"] = () =>
state: "0.0",
attributes: {
unit_of_measurement: "kB/s",
friendly_name: "Uppladdning",
friendly_name: "Uploading",
icon: "mdi:file-upload",
},
},
+9 -198
View File
@@ -2,44 +2,7 @@ import { DemoConfig } from "../types";
export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
name: "Hem",
resources: [
// {
// url: "/local/custom-lovelace/monster-card.js",
// type: "js",
// },
// {
// url: "/local/custom-lovelace/mini-media-player-bundle.js?v=0.9.8",
// type: "module",
// },
// {
// url: "/local/custom-lovelace/slideshow-card.js?=1.1.0",
// type: "js",
// },
// {
// url: "/local/custom-lovelace/fold-entity-row.js?v=3ae2c4",
// type: "js",
// },
// {
// url: "/local/custom-lovelace/swipe-card/swipe-card.js?v=2.0.0",
// type: "module",
// },
// {
// url: "/local/custom-lovelace/upcoming-media-card/upcoming-media-card.js",
// type: "js",
// },
// {
// url: "/local/custom-lovelace/tracker-card.js?v=0.1.5",
// type: "js",
// },
// {
// url: "/local/custom-lovelace/card-tools.js?v=6ce5d0",
// type: "js",
// },
// {
// url: "/local/custom-lovelace/krisinfo.js?=0.0.1",
// type: "js",
// },
],
resources: [],
views: [
{
cards: [
@@ -64,7 +27,7 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
style: {
color: "white",
top: "93%",
left: "90%",
left: "85%",
},
type: "state-label",
entity: "sensor.battery_oskar",
@@ -87,7 +50,7 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
{
style: {
color: "white",
top: "92%",
top: "93%",
left: "20%",
},
type: "state-label",
@@ -96,8 +59,8 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
{
style: {
color: "white",
top: "92%",
left: "90%",
top: "93%",
left: "85%",
},
type: "state-label",
entity: "sensor.battery_bella",
@@ -105,7 +68,7 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
{
style: {
color: "white",
top: "92%",
top: "93%",
left: "55%",
},
type: "state-label",
@@ -131,78 +94,6 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
type: "entities",
title: "Lock",
},
// {
// filter: {
// exclude: [
// {
// state: "not_home",
// },
// ],
// include: [
// {
// entity_id: "device_tracker.annasiphone",
// },
// {
// entity_id: "device_tracker.iphone_2",
// },
// ],
// },
// type: "custom:monster-card",
// card: {
// show_header_toggle: false,
// type: "entities",
// title: "G\u00e4ster",
// },
// show_empty: false,
// },
// {
// filter: {
// exclude: [
// {
// state: "Inget",
// },
// {
// state: "i.u.",
// },
// ],
// include: [
// {
// entity_id: "sensor.pollen_al",
// },
// {
// entity_id: "sensor.pollen_alm",
// },
// {
// entity_id: "sensor.pollen_salg_vide",
// },
// {
// entity_id: "sensor.pollen_bjork",
// },
// {
// entity_id: "sensor.pollen_bok",
// },
// {
// entity_id: "sensor.pollen_ek",
// },
// {
// entity_id: "sensor.pollen_grabo",
// },
// {
// entity_id: "sensor.pollen_gras",
// },
// {
// entity_id: "sensor.pollen_hassel",
// },
// ],
// },
// type: "custom:monster-card",
// card: {
// show_header_toggle: false,
// type: "entities",
// title: "Pollenniv\u00e5er",
// },
// show_empty: false,
// },
{
cards: [
{
@@ -226,10 +117,6 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
],
type: "vertical-stack",
},
// {
// url: "https://embed.windy.com/embed2.html",
// type: "iframe",
// },
{
entities: [
{
@@ -263,6 +150,7 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
],
type: "glance",
show_state: false,
columns: 4,
},
{
entities: ["sensor.oskar_bluetooth"],
@@ -270,32 +158,6 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
type: "entities",
title: "Occupancy",
},
// {
// filter: {
// exclude: [
// {
// state: false,
// },
// ],
// include: [
// {
// entity_id:
// "binary_sensor.fibaro_system_unknown_type0c02_id1003_sensor_2",
// },
// {
// entity_id:
// "binary_sensor.fibaro_system_unknown_type0c02_id1003_sensor_3",
// },
// ],
// },
// type: "custom:monster-card",
// card: {
// show_header_toggle: false,
// type: "entities",
// title: "Brandvarnare",
// },
// show_empty: false,
// },
{
type: "weather-forecast",
entity: "weather.smhi_vader",
@@ -378,41 +240,9 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
"binary_sensor.windows_server",
"binary_sensor.teamspeak",
"binary_sensor.harmony_hub",
// {
// style: {
// height: "1px",
// width: "85%",
// "margin-left": "auto",
// background: "#62717b",
// "margin-right": "auto",
// },
// type: "divider",
// },
// {
// items: ["sensor.uptime_router", "sensor.installerad_routeros"],
// head: {
// entity: "binary_sensor.router",
// },
// type: "custom:fold-entity-row",
// group_config: {
// icon: "mdi:router",
// },
// },
// {
// items: [
// "sensor.uptime_router_server",
// "sensor.installerad_routeros_server",
// ],
// head: {
// entity: "binary_sensor.router_server",
// },
// type: "custom:fold-entity-row",
// group_config: {
// icon: "mdi:router",
// },
// },
],
show_header_toggle: false,
state_color: true,
type: "entities",
title: "Network",
},
@@ -422,29 +252,10 @@ export const demoLovelaceKernehed: DemoConfig["lovelace"] = () => ({
"binary_sensor.ubiquiti_switch",
"binary_sensor.ubiquiti_nvr",
"binary_sensor.entre_kamera",
// {
// items: ["sensor.uptime_ap_1"],
// head: {
// entity: "binary_sensor.accesspunkt_1",
// },
// type: "custom:fold-entity-row",
// group_config: {
// icon: "router-wireless",
// },
// },
// {
// items: ["sensor.uptime_ap_2"],
// head: {
// entity: "binary_sensor.accesspunkt_2",
// },
// type: "custom:fold-entity-row",
// group_config: {
// icon: "router-wireless",
// },
// },
"sensor.total_clients_wireless",
],
show_header_toggle: false,
state_color: true,
type: "entities",
title: "Ubiquiti",
},
+2 -66
View File
@@ -215,6 +215,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
card: {
type: "glance",
show_state: false,
columns: 4,
},
state_filter: ["on"],
},
@@ -808,67 +809,6 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
],
type: "vertical-stack",
},
// {
// cards: [
// {
// entities: [
// {
// hide_when_off: true,
// toggle: true,
// type: "custom:slider-entity-row",
// name: "Bedside",
// entity: "light.bedside_lamp",
// },
// {
// hide_when_off: true,
// toggle: true,
// type: "custom:slider-entity-row",
// name: "Bedroom",
// entity: "light.bedroom_ceiling_light",
// },
// {
// hide_when_off: true,
// toggle: true,
// type: "custom:slider-entity-row",
// name: "Isa",
// entity: "light.isa_ceiling_light",
// },
// {
// hide_when_off: true,
// toggle: true,
// type: "custom:slider-entity-row",
// name: "Upstairs hallway",
// entity: "light.upstairs_hallway_ceiling_light_level",
// },
// {
// hide_when_off: true,
// toggle: true,
// type: "custom:slider-entity-row",
// name: "Nightlight",
// entity: "light.gateway_light_34ce008bfc4b",
// },
// {
// hide_when_off: true,
// toggle: true,
// type: "custom:slider-entity-row",
// name: "Walk in closet",
// entity: "light.walk_in_closet_lights",
// },
// {
// hide_when_off: true,
// toggle: false,
// type: "custom:slider-entity-row",
// name: "Stefan",
// entity: "light.stefan_lightstrip",
// },
// ],
// show_header_toggle: false,
// type: "entities",
// title: "Upstairs",
// },
// ],
// type: "vertical-stack",
// },
],
path: "lights",
title: "Lights",
@@ -918,10 +858,6 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
name: "Dafang",
icon: "mdi:webcam",
},
{
name: "IR Hallway",
entity: "sensor.system_ir_blaster",
},
{
name: "IR Bedroom",
entity: "sensor.system_ir_blaster_bedroom",
@@ -940,7 +876,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
"sensor.system_ring_chime",
],
type: "glance",
columns: 5,
columns: 4,
show_state: false,
},
{
+1 -1
View File
@@ -9,5 +9,5 @@ export interface DemoConfig {
authorUrl: string;
lovelace: (localize: LocalizeFunc) => LovelaceConfig;
entities: (localize: LocalizeFunc) => Entity[];
theme: () => { [key: string]: string } | null;
theme: () => Record<string, string> | null;
}
+1 -1
View File
@@ -3,8 +3,8 @@ import {
CSSResult,
customElement,
html,
LitElement,
internalProperty,
LitElement,
TemplateResult,
} from "lit-element";
import { CastManager } from "../../../src/cast/cast_manager";
+1 -1
View File
@@ -3,9 +3,9 @@ import {
css,
CSSResult,
html,
internalProperty,
LitElement,
property,
internalProperty,
TemplateResult,
} from "lit-element";
import { until } from "lit-html/directives/until";
+2 -4
View File
@@ -1,13 +1,11 @@
import "../../src/resources/safari-14-attachshadow-patch";
import "@polymer/polymer/lib/elements/dom-if";
import "@polymer/polymer/lib/elements/dom-repeat";
import "../../src/resources/ha-style";
import "../../src/resources/roboto";
import "../../src/resources/safari-14-attachshadow-patch";
import "./ha-demo";
/* polyfill for paper-dropdown */
setTimeout(() => {
import(
/* webpackChunkName: "polyfill-web-animations-next" */ "web-animations-js/web-animations-next-lite.min"
);
import("web-animations-js/web-animations-next-lite.min");
}, 1000);
+1
View File
@@ -1,3 +1,4 @@
// Compat needs to be first import
import "../../src/resources/compatibility";
import { isNavigationClick } from "../../src/common/dom/is-navigation-click";
import { navigate } from "../../src/common/navigate";
+3 -2
View File
@@ -21,15 +21,16 @@ class DemoCard extends PolymerElement {
}
pre {
width: 400px;
margin: 16px;
margin: 0 16px;
overflow: auto;
color: var(--primary-text-color);
}
@media only screen and (max-width: 800px) {
.root {
flex-direction: column;
}
pre {
margin-left: 0;
margin: 16px 0;
}
}
</style>
+3 -3
View File
@@ -2,10 +2,10 @@ import "@polymer/app-layout/app-toolbar/app-toolbar";
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import "../../../src/components/ha-switch";
import "../../../src/components/ha-formfield";
import "./demo-card";
import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element";
import "../../../src/components/ha-formfield";
import "../../../src/components/ha-switch";
import "./demo-card";
class DemoCards extends PolymerElement {
static get template() {
+29 -25
View File
@@ -2,58 +2,62 @@ import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import "../../../src/components/ha-card";
import "../../../src/state-summary/state-card-content";
import "../../../src/dialogs/more-info/more-info-content";
import "../../../src/state-summary/state-card-content";
class DemoMoreInfo extends PolymerElement {
static get template() {
return html`
<style>
:host {
.root {
display: flex;
align-items: start;
}
#card {
max-width: 400px;
width: 100vw;
}
ha-card {
width: 333px;
width: 352px;
padding: 20px 24px;
}
state-card-content {
display: block;
margin-bottom: 16px;
}
pre {
width: 400px;
margin: 16px;
margin: 0 16px;
overflow: auto;
color: var(--primary-text-color);
}
@media only screen and (max-width: 800px) {
:host {
.root {
flex-direction: column;
}
pre {
margin-left: 0;
margin: 16px 0;
}
}
</style>
<ha-card>
<state-card-content
state-obj="[[_stateObj]]"
hass="[[hass]]"
in-dialog
></state-card-content>
<div class="root">
<div id="card">
<ha-card>
<state-card-content
state-obj="[[_stateObj]]"
hass="[[hass]]"
in-dialog
></state-card-content>
<more-info-content
hass="[[hass]]"
state-obj="[[_stateObj]]"
></more-info-content>
</ha-card>
<template is="dom-if" if="[[showConfig]]">
<pre>[[_jsonEntity(_stateObj)]]</pre>
</template>
<more-info-content
hass="[[hass]]"
state-obj="[[_stateObj]]"
></more-info-content>
</ha-card>
</div>
<template is="dom-if" if="[[showConfig]]">
<pre>[[_jsonEntity(_stateObj)]]</pre>
</template>
</div>
`;
}
+36 -9
View File
@@ -2,6 +2,8 @@ import "@polymer/app-layout/app-toolbar/app-toolbar";
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element";
import "../../../src/components/ha-formfield";
import "../../../src/components/ha-switch";
import "./demo-more-info";
@@ -9,6 +11,10 @@ class DemoMoreInfos extends PolymerElement {
static get template() {
return html`
<style>
#container {
min-height: calc(100vh - 128px);
background: var(--primary-background-color);
}
.cards {
display: flex;
flex-wrap: wrap;
@@ -23,20 +29,31 @@ class DemoMoreInfos extends PolymerElement {
.filters {
margin-left: 60px;
}
ha-formfield {
margin-right: 16px;
}
</style>
<app-toolbar>
<div class="filters">
<ha-switch checked="{{_showConfig}}">Show entity</ha-switch>
<ha-formfield label="Show entities">
<ha-switch checked="[[_showConfig]]" on-change="_showConfigToggled">
</ha-switch>
</ha-formfield>
<ha-formfield label="Dark theme">
<ha-switch on-change="_darkThemeToggled"> </ha-switch>
</ha-formfield>
</div>
</app-toolbar>
<div class="cards">
<template is="dom-repeat" items="[[entities]]">
<demo-more-info
entity-id="[[item]]"
show-config="[[_showConfig]]"
hass="[[hass]]"
></demo-more-info>
</template>
<div id="container">
<div class="cards">
<template is="dom-repeat" items="[[entities]]">
<demo-more-info
entity-id="[[item]]"
show-config="[[_showConfig]]"
hass="[[hass]]"
></demo-more-info>
</template>
</div>
</div>
`;
}
@@ -51,6 +68,16 @@ class DemoMoreInfos extends PolymerElement {
},
};
}
_showConfigToggled(ev) {
this._showConfig = ev.target.checked;
}
_darkThemeToggled(ev) {
applyThemesOnElement(this.$.container, { themes: {} }, "default", {
dark: ev.target.checked,
});
}
}
customElements.define("demo-more-infos", DemoMoreInfos);
+4 -4
View File
@@ -7,8 +7,8 @@ export const createMediaPlayerEntities = () => [
media_title: "I Wanna Be A Hippy (Flamman & Abraxas Radio Mix)",
media_artist: "Technohead",
// Pause + Seek + Volume Set + Volume Mute + Previous Track + Next Track + Play Media +
// Select Source + Stop + Clear + Play + Shuffle Set + Browse Media
supported_features: 195135,
// Select Source + Stop + Clear + Play + Shuffle Set
supported_features: 64063,
entity_picture: "/images/album_cover_2.jpg",
media_duration: 300,
media_position: 50,
@@ -24,8 +24,8 @@ export const createMediaPlayerEntities = () => [
media_title: "I Wanna Be A Hippy (Flamman & Abraxas Radio Mix)",
media_artist: "Technohead",
// Pause + Seek + Volume Set + Volume Mute + Previous Track + Next Track + Play Media +
// Select Source + Stop + Clear + Play + Shuffle Set
supported_features: 64063,
// Select Source + Stop + Clear + Play + Shuffle Set + Browse Media
supported_features: 195135,
entity_picture: "/images/album_cover.jpg",
media_duration: 300,
media_position: 0,
+72
View File
@@ -0,0 +1,72 @@
import { getEntity } from "../../../src/fake_data/entity";
export const createPlantEntities = () => [
getEntity("plant", "lemon_tree", "ok", {
problem: "none",
sensors: {
moisture: "sensor.lemon_tree_moisture",
battery: "sensor.lemon_tree_battery",
temperature: "sensor.lemon_tree_temperature",
conductivity: "sensor.lemon_tree_conductivity",
brightness: "sensor.lemon_tree_brightness",
},
unit_of_measurement_dict: {
temperature: "°C",
moisture: "%",
brightness: "lx",
battery: "%",
conductivity: "μS/cm",
},
moisture: 54,
battery: 95,
temperature: 15.6,
conductivity: 1,
brightness: 12,
max_brightness: 20,
friendly_name: "Lemon Tree",
}),
getEntity("plant", "apple_tree", "ok", {
problem: "brightness",
sensors: {
moisture: "sensor.apple_tree_moisture",
battery: "sensor.apple_tree_battery",
temperature: "sensor.apple_tree_temperature",
conductivity: "sensor.apple_tree_conductivity",
brightness: "sensor.apple_tree_brightness",
},
unit_of_measurement_dict: {
temperature: "°C",
moisture: "%",
brightness: "lx",
battery: "%",
conductivity: "μS/cm",
},
moisture: 54,
battery: 2,
temperature: 15.6,
conductivity: 1,
brightness: 25,
max_brightness: 20,
friendly_name: "Apple Tree",
}),
getEntity("plant", "sunflowers", "ok", {
problem: "moisture, temperature, conductivity",
sensors: {
moisture: "sensor.sunflowers_moisture",
temperature: "sensor.sunflowers_temperature",
conductivity: "sensor.sunflowers_conductivity",
brightness: "sensor.sunflowers_brightness",
},
unit_of_measurement_dict: {
temperature: "°C",
moisture: "%",
brightness: "lx",
conductivity: "μS/cm",
},
moisture: 54,
temperature: 15.6,
conductivity: 1,
brightness: 25,
entity_picture: "/images/sunflowers.jpg",
}),
];
+271
View File
@@ -0,0 +1,271 @@
import { DemoTrace } from "./types";
export const basicTrace: DemoTrace = {
trace: {
last_action: "action/0/choose/0/sequence/0",
last_condition: "condition/0",
run_id: "0",
state: "stopped",
timestamp: {
start: "2021-03-22T19:17:09.519178+00:00",
finish: "2021-03-22T19:17:09.556129+00:00",
},
trigger: "state of input_boolean.toggle_1",
domain: "automation",
item_id: "1615419646544",
action_trace: {
"action/0": [
{
path: "action/0",
timestamp: "2021-03-22T19:17:09.526794+00:00",
changed_variables: {
trigger: {
platform: "state",
entity_id: "input_boolean.toggle_1",
from_state: {
entity_id: "input_boolean.toggle_1",
state: "on",
attributes: {
editable: true,
friendly_name: "Toggle 1",
},
last_changed: "2021-03-22T19:11:24.418709+00:00",
last_updated: "2021-03-22T19:11:24.418709+00:00",
context: {
id: "55daa6c47a7613b0800fe0ec81090a84",
parent_id: null,
user_id: null,
},
},
to_state: {
entity_id: "input_boolean.toggle_1",
state: "off",
attributes: {
editable: true,
friendly_name: "Toggle 1",
},
last_changed: "2021-03-22T19:17:09.516874+00:00",
last_updated: "2021-03-22T19:17:09.516874+00:00",
context: {
id: "116d7a6562d594b114f7efe728619a3f",
parent_id: null,
user_id: "d1b4e89da01445fa8bc98e39fac477ca",
},
},
for: null,
attribute: null,
description: "state of input_boolean.toggle_1",
},
context: {
id: "54a7371cff31be0f4010c9fde2317322",
parent_id: "116d7a6562d594b114f7efe728619a3f",
user_id: null,
},
},
result: {
choice: 0,
},
},
],
"action/0/choose/0": [
{
path: "action/0/choose/0",
timestamp: "2021-03-22T19:17:09.530176+00:00",
result: {
result: true,
},
},
],
"action/0/choose/0/conditions/0": [
{
path: "action/0/choose/0/conditions/0",
timestamp: "2021-03-22T19:17:09.539155+00:00",
result: {
result: true,
},
},
],
"action/0/choose/0/sequence/0": [
{
path: "action/0/choose/0/sequence/0",
timestamp: "2021-03-22T19:17:09.542769+00:00",
result: {
params: {
domain: "input_boolean",
service: "toggle",
service_data: {},
target: {
entity_id: ["input_boolean.toggle_2"],
},
},
running_script: false,
limit: 10,
},
},
],
},
condition_trace: {
"condition/0": [
{
path: "condition/0",
timestamp: "2021-03-22T19:17:09.520267+00:00",
changed_variables: {
trigger: {
platform: "state",
entity_id: "input_boolean.toggle_1",
from_state: {
entity_id: "input_boolean.toggle_1",
state: "on",
attributes: {
editable: true,
friendly_name: "Toggle 1",
},
last_changed: "2021-03-22T19:11:24.418709+00:00",
last_updated: "2021-03-22T19:11:24.418709+00:00",
context: {
id: "55daa6c47a7613b0800fe0ec81090a84",
parent_id: null,
user_id: null,
},
},
to_state: {
entity_id: "input_boolean.toggle_1",
state: "off",
attributes: {
editable: true,
friendly_name: "Toggle 1",
},
last_changed: "2021-03-22T19:17:09.516874+00:00",
last_updated: "2021-03-22T19:17:09.516874+00:00",
context: {
id: "116d7a6562d594b114f7efe728619a3f",
parent_id: null,
user_id: "d1b4e89da01445fa8bc98e39fac477ca",
},
},
for: null,
attribute: null,
description: "state of input_boolean.toggle_1",
},
},
result: {
result: true,
},
},
],
},
config: {
id: "1615419646544",
alias: "Ensure Party mode",
description: "",
trigger: [
{
platform: "state",
entity_id: "input_boolean.toggle_1",
},
],
condition: [
{
condition: "template",
alias: "Test if Paulus is home",
value_template: "{{ true }}",
},
],
action: [
{
choose: [
{
alias: "If toggle 3 is on",
conditions: "{{ is_state('input_boolean.toggle_3', 'on') }}",
sequence: [
{
service: "input_boolean.toggle",
alias: "Toggle 2 while 3 is on",
target: {
entity_id: "input_boolean.toggle_2",
},
},
],
},
],
default: [
{
service: "input_boolean.toggle",
alias: "Toggle 2",
target: {
entity_id: "input_boolean.toggle_2",
},
},
],
},
],
mode: "single",
},
context: {
id: "54a7371cff31be0f4010c9fde2317322",
parent_id: "116d7a6562d594b114f7efe728619a3f",
user_id: null,
},
variables: {
trigger: {
platform: "state",
entity_id: "input_boolean.toggle_1",
from_state: {
entity_id: "input_boolean.toggle_1",
state: "on",
attributes: {
editable: true,
friendly_name: "Toggle 1",
},
last_changed: "2021-03-22T19:11:24.418709+00:00",
last_updated: "2021-03-22T19:11:24.418709+00:00",
context: {
id: "55daa6c47a7613b0800fe0ec81090a84",
parent_id: null,
user_id: null,
},
},
to_state: {
entity_id: "input_boolean.toggle_1",
state: "off",
attributes: {
editable: true,
friendly_name: "Toggle 1",
},
last_changed: "2021-03-22T19:17:09.516874+00:00",
last_updated: "2021-03-22T19:17:09.516874+00:00",
context: {
id: "116d7a6562d594b114f7efe728619a3f",
parent_id: null,
user_id: "d1b4e89da01445fa8bc98e39fac477ca",
},
},
for: null,
attribute: null,
description: "state of input_boolean.toggle_1",
},
},
},
logbookEntries: [
{
name: "Ensure Party mode",
message: "has been triggered by state of input_boolean.toggle_1",
source: "state of input_boolean.toggle_1",
entity_id: "automation.toggle_toggles",
context_id: "54a7371cff31be0f4010c9fde2317322",
when: "2021-03-22T19:17:09.523041+00:00",
domain: "automation",
},
{
when: "2021-03-22T19:17:09.549346+00:00",
name: "Toggle 2",
state: "on",
entity_id: "input_boolean.toggle_2",
context_entity_id: "automation.toggle_toggles",
context_entity_id_name: "Ensure Party mode",
context_event_type: "automation_triggered",
context_domain: "automation",
context_name: "Ensure Party mode",
},
],
};
@@ -0,0 +1,248 @@
import { DemoTrace } from "./types";
export const motionLightTrace: DemoTrace = {
trace: {
last_action: "action/3",
last_condition: null,
run_id: "1",
state: "stopped",
timestamp: {
start: "2021-03-14T06:07:01.768006+00:00",
finish: "2021-03-14T06:07:53.287525+00:00",
},
trigger: "state of binary_sensor.pauluss_macbook_pro_camera_in_use",
domain: "automation",
item_id: "1614732497392",
action_trace: {
"action/0": [
{
path: "action/0",
timestamp: "2021-03-14T06:07:01.771038+00:00",
changed_variables: {
trigger: {
platform: "state",
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
from_state: {
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
state: "off",
attributes: {
friendly_name: "Pauluss MacBook Pro Camera In Use",
icon: "mdi:camera-off",
},
last_changed: "2021-03-14T06:06:29.235325+00:00",
last_updated: "2021-03-14T06:06:29.235325+00:00",
context: {
id: "ad4864c5ce957c38a07b50378eeb245d",
parent_id: null,
user_id: null,
},
},
to_state: {
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
state: "on",
attributes: {
friendly_name: "Pauluss MacBook Pro Camera In Use",
icon: "mdi:camera",
},
last_changed: "2021-03-14T06:07:01.762009+00:00",
last_updated: "2021-03-14T06:07:01.762009+00:00",
context: {
id: "e22ddfd5f11dc4aad9a52fc10dab613b",
parent_id: null,
user_id: null,
},
},
for: null,
attribute: null,
description:
"state of binary_sensor.pauluss_macbook_pro_camera_in_use",
},
context: {
id: "43b6ee9293a551c5cc14e8eb60af54ba",
parent_id: "e22ddfd5f11dc4aad9a52fc10dab613b",
user_id: null,
},
},
},
],
"action/1": [
{ path: "action/1", timestamp: "2021-03-14T06:07:01.875316+00:00" },
],
"action/2": [
{
path: "action/2",
timestamp: "2021-03-14T06:07:53.195013+00:00",
changed_variables: {
wait: {
remaining: null,
trigger: {
platform: "state",
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
from_state: {
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
state: "on",
attributes: {
friendly_name: "Pauluss MacBook Pro Camera In Use",
icon: "mdi:camera",
},
last_changed: "2021-03-14T06:07:01.762009+00:00",
last_updated: "2021-03-14T06:07:01.762009+00:00",
context: {
id: "e22ddfd5f11dc4aad9a52fc10dab613b",
parent_id: null,
user_id: null,
},
},
to_state: {
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
state: "off",
attributes: {
friendly_name: "Pauluss MacBook Pro Camera In Use",
icon: "mdi:camera-off",
},
last_changed: "2021-03-14T06:07:53.186755+00:00",
last_updated: "2021-03-14T06:07:53.186755+00:00",
context: {
id: "b2308cc91d509ea8e0c623331ab178d6",
parent_id: null,
user_id: null,
},
},
for: null,
attribute: null,
description:
"state of binary_sensor.pauluss_macbook_pro_camera_in_use",
},
},
},
},
],
"action/3": [
{
path: "action/3",
timestamp: "2021-03-14T06:07:53.196014+00:00",
},
],
},
condition_trace: {},
config: {
mode: "restart",
max_exceeded: "silent",
trigger: [
{
platform: "state",
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
from: "off",
to: "on",
},
],
action: [
{
service: "light.turn_on",
target: {
entity_id: "light.elgato_key_light_air",
},
},
{
wait_for_trigger: [
{
platform: "state",
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
from: "on",
to: "off",
},
],
},
{
delay: 0,
},
{
service: "light.turn_off",
target: {
entity_id: "light.elgato_key_light_air",
},
},
],
id: "1614732497392",
alias: "Auto Elgato",
description: "",
},
context: {
id: "43b6ee9293a551c5cc14e8eb60af54ba",
parent_id: "e22ddfd5f11dc4aad9a52fc10dab613b",
user_id: null,
},
variables: {
trigger: {
platform: "state",
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
from_state: {
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
state: "off",
attributes: {
friendly_name: "Pauluss MacBook Pro Camera In Use",
icon: "mdi:camera-off",
},
last_changed: "2021-03-14T06:06:29.235325+00:00",
last_updated: "2021-03-14T06:06:29.235325+00:00",
context: {
id: "ad4864c5ce957c38a07b50378eeb245d",
parent_id: null,
user_id: null,
},
},
to_state: {
entity_id: "binary_sensor.pauluss_macbook_pro_camera_in_use",
state: "on",
attributes: {
friendly_name: "Pauluss MacBook Pro Camera In Use",
icon: "mdi:camera",
},
last_changed: "2021-03-14T06:07:01.762009+00:00",
last_updated: "2021-03-14T06:07:01.762009+00:00",
context: {
id: "e22ddfd5f11dc4aad9a52fc10dab613b",
parent_id: null,
user_id: null,
},
},
for: null,
attribute: null,
description: "state of binary_sensor.pauluss_macbook_pro_camera_in_use",
},
},
},
logbookEntries: [
{
name: "Auto Elgato",
message:
"has been triggered by state of binary_sensor.pauluss_macbook_pro_camera_in_use",
source: "state of binary_sensor.pauluss_macbook_pro_camera_in_use",
entity_id: "automation.auto_elgato",
when: "2021-03-14T06:07:01.768492+00:00",
domain: "automation",
},
{
when: "2021-03-14T06:07:01.872187+00:00",
name: "Elgato Key Light Air",
state: "on",
entity_id: "light.elgato_key_light_air",
context_entity_id: "automation.auto_elgato",
context_entity_id_name: "Auto Elgato",
context_event_type: "automation_triggered",
context_domain: "automation",
context_name: "Auto Elgato",
},
{
when: "2021-03-14T06:07:53.284505+00:00",
name: "Elgato Key Light Air",
state: "off",
entity_id: "light.elgato_key_light_air",
context_entity_id: "automation.auto_elgato",
context_entity_id_name: "Auto Elgato",
context_event_type: "automation_triggered",
context_domain: "automation",
context_name: "Auto Elgato",
},
],
};
+7
View File
@@ -0,0 +1,7 @@
import { AutomationTraceExtended } from "../../../../src/data/trace";
import { LogbookEntry } from "../../../../src/data/logbook";
export interface DemoTrace {
trace: AutomationTraceExtended;
logbookEntries: LogbookEntry[];
}
@@ -0,0 +1,64 @@
import {
customElement,
html,
css,
LitElement,
TemplateResult,
property,
} from "lit-element";
import "../../../src/components/ha-card";
import "../../../src/components/trace/hat-trace";
import { provideHass } from "../../../src/fake_data/provide_hass";
import { HomeAssistant } from "../../../src/types";
import { DemoTrace } from "../data/traces/types";
import { basicTrace } from "../data/traces/basic_trace";
import { motionLightTrace } from "../data/traces/motion-light-trace";
const traces: DemoTrace[] = [basicTrace, motionLightTrace];
@customElement("demo-automation-trace")
export class DemoAutomationTrace extends LitElement {
@property({ attribute: false }) hass?: HomeAssistant;
protected render(): TemplateResult {
if (!this.hass) {
return html``;
}
return html`
${traces.map(
(trace) => html`
<ha-card .heading=${trace.trace.config.alias}>
<div class="card-content">
<hat-trace
.hass=${this.hass}
.trace=${trace.trace}
.logbookEntries=${trace.logbookEntries}
></hat-trace>
</div>
</ha-card>
`
)}
`;
}
protected firstUpdated(changedProps) {
super.firstUpdated(changedProps);
const hass = provideHass(this);
hass.updateTranslations(null, "en");
}
static get styles() {
return css`
ha-card {
max-width: 600px;
margin: 24px;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"demo-automation-trace": DemoAutomationTrace;
}
}
+19 -30
View File
@@ -1,6 +1,11 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -71,35 +76,19 @@ const CONFIGS = [
},
];
class DemoAlarmPanelEntity extends PolymerElement {
static get template() {
return html`
<demo-cards
id="demos"
hass="[[hass]]"
configs="[[_configs]]"
></demo-cards>
`;
@customElement("demo-hui-alarm-panel-card")
class DemoAlarmPanelEntity extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
hass: Object,
};
}
public ready() {
super.ready();
this._setupDemo();
}
private async _setupDemo() {
const hass = provideHass(this.$.demos);
await hass.updateTranslations(null, "en");
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
+18 -25
View File
@@ -1,6 +1,11 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -53,31 +58,19 @@ const CONFIGS = [
},
];
class DemoConditional extends PolymerElement {
static get template() {
return html`
<demo-cards
id="demos"
hass="[[hass]]"
configs="[[_configs]]"
></demo-cards>
`;
@customElement("demo-hui-conditional-card")
class DemoConditional extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
hass: Object,
};
}
public ready() {
super.ready();
const hass = provideHass(this.$.demos);
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
+18 -18
View File
@@ -1,6 +1,11 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -217,24 +222,19 @@ const CONFIGS = [
},
];
class DemoEntities extends PolymerElement {
static get template() {
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
@customElement("demo-hui-entities-card")
class DemoEntities extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
};
}
public ready() {
super.ready();
const hass = provideHass(this.$.demos);
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
@@ -1,6 +1,11 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -20,10 +25,10 @@ const CONFIGS = [
`,
},
{
heading: "With Name",
heading: "With Name (defined in card)",
config: `
- type: button
name: Bedroom
name: Custom Name
entity: light.bed_light
`,
},
@@ -32,7 +37,7 @@ const CONFIGS = [
config: `
- type: button
entity: light.bed_light
icon: mdi:hotel
icon: mdi:tools
`,
},
{
@@ -48,7 +53,7 @@ const CONFIGS = [
config: `
- type: button
entity: light.bed_light
tap_action:
tap_action:
action: toggle
`,
},
@@ -69,31 +74,19 @@ const CONFIGS = [
},
];
class DemoButtonEntity extends PolymerElement {
static get template() {
return html`
<demo-cards
id="demos"
hass="[[hass]]"
configs="[[_configs]]"
></demo-cards>
`;
@customElement("demo-hui-entity-button-card")
class DemoButtonEntity extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
hass: Object,
};
}
public ready() {
super.ready();
const hass = provideHass(this.$.demos);
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
@@ -1,6 +1,11 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -43,7 +48,7 @@ const ENTITIES = [
const CONFIGS = [
{
heading: "Controller",
heading: "Unfiltered controller",
config: `
- type: entities
entities:
@@ -53,7 +58,7 @@ const CONFIGS = [
`,
},
{
heading: "Basic",
heading: "Filtered entities card",
config: `
- type: entity-filter
entities:
@@ -69,7 +74,27 @@ const CONFIGS = [
`,
},
{
heading: "With card config",
heading: 'With "entities" card config',
config: `
- type: entity-filter
entities:
- device_tracker.demo_anne_therese
- device_tracker.demo_home_boy
- device_tracker.demo_paulus
- light.bed_light
- light.ceiling_lights
- light.kitchen_lights
state_filter:
- "on"
- not_home
card:
type: entities
title: Custom Title
show_header_toggle: false
`,
},
{
heading: 'With "glance" card config',
config: `
- type: entity-filter
entities:
@@ -84,31 +109,27 @@ const CONFIGS = [
- not_home
card:
type: glance
show_state: false
show_state: true
title: Custom Title
`,
},
];
class DemoFilter extends PolymerElement {
static get template() {
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
@customElement("demo-hui-entity-filter-card")
class DemoEntityFilter extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
};
}
public ready() {
super.ready();
const hass = provideHass(this.$.demos);
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
customElements.define("demo-hui-entity-filter-card", DemoFilter);
customElements.define("demo-hui-entity-filter-card", DemoEntityFilter);
+52 -29
View File
@@ -1,12 +1,19 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
const ENTITIES = [
getEntity("sensor", "brightness", "12", {}),
getEntity("sensor", "brightness_medium", "53", {}),
getEntity("sensor", "brightness_high", "87", {}),
getEntity("plant", "bonsai", "ok", {}),
getEntity("sensor", "not_working", "unavailable", {}),
getEntity("sensor", "outside_humidity", "54", {
@@ -21,16 +28,10 @@ const CONFIGS = [
{
heading: "Basic example",
config: `
- type: gauge
entity: sensor.brightness
`,
},
{
heading: "With title",
config: `
- type: gauge
title: Humidity
entity: sensor.outside_humidity
name: Outside Humidity
`,
},
{
@@ -39,6 +40,7 @@ const CONFIGS = [
- type: gauge
entity: sensor.outside_temperature
unit_of_measurement: C
name: Outside Temperature
`,
},
{
@@ -46,19 +48,45 @@ const CONFIGS = [
config: `
- type: gauge
entity: sensor.brightness
name: Brightness Low
severity:
red: 32
red: 75
green: 0
yellow: 23
yellow: 50
`,
},
{
heading: "Setting Min and Max Values",
heading: "Setting Severity Levels",
config: `
- type: gauge
entity: sensor.brightness_medium
name: Brightness Medium
severity:
red: 75
green: 0
yellow: 50
`,
},
{
heading: "Setting Severity Levels",
config: `
- type: gauge
entity: sensor.brightness_high
name: Brightness High
severity:
red: 75
green: 0
yellow: 50
`,
},
{
heading: "Setting Min (0) and Max (15) Values",
config: `
- type: gauge
entity: sensor.brightness
name: Brightness
min: 0
max: 38
max: 15
`,
},
{
@@ -84,24 +112,19 @@ const CONFIGS = [
},
];
class DemoGaugeEntity extends PolymerElement {
static get template() {
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
@customElement("demo-hui-gauge-card")
class DemoGaugeEntity extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
};
}
public ready() {
super.ready();
const hass = provideHass(this.$.demos);
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
+53 -61
View File
@@ -1,6 +1,11 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -77,7 +82,8 @@ const CONFIGS = [
heading: "With title",
config: `
- type: glance
title: This is glance
title: Custom title
columns: 4
entities:
- device_tracker.demo_paulus
- media_player.living_room
@@ -104,9 +110,10 @@ const CONFIGS = [
`,
},
{
heading: "No name",
heading: "No entity names",
config: `
- type: glance
columns: 4
show_name: false
entities:
- device_tracker.demo_paulus
@@ -119,9 +126,10 @@ const CONFIGS = [
`,
},
{
heading: "No state",
heading: "No state labels",
config: `
- type: glance
columns: 4
show_state: false
entities:
- device_tracker.demo_paulus
@@ -134,9 +142,10 @@ const CONFIGS = [
`,
},
{
heading: "No name and no state",
heading: "No names and no state labels",
config: `
- type: glance
columns: 4
show_name: false
show_state: false
entities:
@@ -150,47 +159,24 @@ const CONFIGS = [
`,
},
{
heading: "Custom name, custom icon",
heading: "Custom name + custom icon",
config: `
- type: glance
columns: 4
entities:
- entity: device_tracker.demo_paulus
name: ¯\\_()_/¯
icon: mdi:home-assistant
- media_player.living_room
- sun.sun
- cover.kitchen_window
- entity: light.kitchen_lights
icon: mdi:alarm-light
- lock.kitchen_door
- light.ceiling_lights
`,
},
{
heading: "Custom tap action",
config: `
- type: glance
entities:
- entity: lock.kitchen_door
tap_action:
type: toggle
- entity: light.ceiling_lights
tap_action:
action: call-service
service: light.turn_on
service_data:
entity_id: light.ceiling_lights
- device_tracker.demo_paulus
- media_player.living_room
- sun.sun
- cover.kitchen_window
- light.kitchen_lights
- entity: media_player.living_room
name: ¯\\_()_/¯
icon: mdi:home-assistant
`,
},
{
heading: "Selectively hidden name",
config: `
- type: glance
columns: 4
entities:
- device_tracker.demo_paulus
- entity: media_player.living_room
@@ -199,45 +185,51 @@ const CONFIGS = [
- entity: cover.kitchen_window
name:
- light.kitchen_lights
- entity: lock.kitchen_door
name:
- light.ceiling_lights
`,
},
{
heading: "Primary theme",
heading: "Custom tap action",
config: `
- type: glance
theming: primary
columns: 4
entities:
- device_tracker.demo_paulus
- media_player.living_room
- sun.sun
- cover.kitchen_window
- light.kitchen_lights
- lock.kitchen_door
- light.ceiling_lights
- entity: lock.kitchen_door
name: Custom
tap_action:
type: toggle
- entity: light.ceiling_lights
name: Custom
tap_action:
action: call-service
service: light.turn_on
service_data:
entity_id: light.ceiling_lights
- entity: sun.sun
name: Regular
- entity: light.kitchen_lights
name: Regular
`,
},
];
class DemoPicEntity extends PolymerElement {
static get template() {
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
@customElement("demo-hui-glance-card")
class DemoGlanceEntity extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
};
}
public ready() {
super.ready();
const hass = provideHass(this.$.demos);
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
customElements.define("demo-hui-glance-card", DemoPicEntity);
customElements.define("demo-hui-glance-card", DemoGlanceEntity);
+5 -15
View File
@@ -1,6 +1,4 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import { customElement, html, LitElement, TemplateResult } from "lit-element";
import "../components/demo-cards";
const CONFIGS = [
@@ -37,18 +35,10 @@ const CONFIGS = [
},
];
class DemoIframe extends PolymerElement {
static get template() {
return html` <demo-cards configs="[[_configs]]"></demo-cards> `;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
};
@customElement("demo-hui-iframe-card")
class DemoIframe extends LitElement {
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
}
+37 -23
View File
@@ -1,6 +1,11 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -8,29 +13,43 @@ import "../components/demo-cards";
const ENTITIES = [
getEntity("light", "bed_light", "on", {
friendly_name: "Bed Light",
brightness: 130,
brightness: 255,
}),
getEntity("light", "dim", "off", {
getEntity("light", "dim_on", "on", {
friendly_name: "Dining Room",
supported_features: 1,
brightness: 100,
}),
getEntity("light", "dim_off", "off", {
friendly_name: "Dining Room",
supported_features: 1,
}),
getEntity("light", "unavailable", "unavailable", {
friendly_name: "Lost Light",
supported_features: 1,
}),
];
const CONFIGS = [
{
heading: "Basic example",
heading: "Switchable Light",
config: `
- type: light
entity: light.bed_light
`,
},
{
heading: "Dim",
heading: "Dimmable Light On",
config: `
- type: light
entity: light.dim
entity: light.dim_on
`,
},
{
heading: "Dimmable Light Off",
config: `
- type: light
entity: light.dim_off
`,
},
{
@@ -49,24 +68,19 @@ const CONFIGS = [
},
];
class DemoLightEntity extends PolymerElement {
static get template() {
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
@customElement("demo-hui-light-card")
class DemoLightEntity extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
};
}
public ready() {
super.ready();
const hass = provideHass(this.$.demos);
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
+18 -25
View File
@@ -1,6 +1,11 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -161,31 +166,19 @@ const CONFIGS = [
},
];
class DemoMap extends PolymerElement {
static get template() {
return html`
<demo-cards
id="demos"
hass="[[hass]]"
configs="[[_configs]]"
></demo-cards>
`;
@customElement("demo-hui-map-card")
class DemoMap extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
hass: Object,
};
}
public ready() {
super.ready();
const hass = provideHass(this.$.demos);
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
+19 -18
View File
@@ -1,6 +1,11 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { mockTemplate } from "../../../demo/src/stubs/template";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -254,23 +259,19 @@ const CONFIGS = [
},
];
class DemoMarkdown extends PolymerElement {
static get template() {
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
@customElement("demo-hui-markdown-card")
class DemoMarkdown extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
};
}
public ready() {
super.ready();
const hass = provideHass(this.$.demos);
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
mockTemplate(hass);
}
}
@@ -1,6 +1,11 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
import { createMediaPlayerEntities } from "../data/media_players";
@@ -146,35 +151,33 @@ const CONFIGS = [
entity: media_player.receiver_off
`,
},
{
heading: "Grid Full Size",
config: `
- type: grid
columns: 1
cards:
- type: media-control
entity: media_player.music_paused
`,
},
];
class DemoHuiMediControlCard extends PolymerElement {
static get template() {
return html`
<demo-cards
id="demos"
hass="[[hass]]"
configs="[[_configs]]"
></demo-cards>
`;
@customElement("demo-hui-media-control-card")
class DemoHuiMediaControlCard extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
hass: Object,
};
}
public ready() {
super.ready();
const hass = provideHass(this.$.demos);
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(createMediaPlayerEntities());
}
}
customElements.define("demo-hui-media-control-card", DemoHuiMediControlCard);
customElements.define("demo-hui-media-control-card", DemoHuiMediaControlCard);
+22 -29
View File
@@ -1,6 +1,11 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
import { createMediaPlayerEntities } from "../data/media_players";
@@ -26,9 +31,9 @@ const CONFIGS = [
- entity: media_player.android_cast
name: Screen casting
- entity: media_player.image_display
name: Digital Picture Frame
name: Digital Picture Frame
- entity: media_player.sonos_idle
name: Sonos Idle
name: Sonos Idle
- entity: media_player.idle_browse_media
name: Idle waiting for Browse Media
- entity: media_player.theater_off
@@ -38,7 +43,7 @@ const CONFIGS = [
- entity: media_player.theater_off_static
name: Player Off (cannot be switched on)
- entity: media_player.theater_on_static
name: Player On (cannot be switched off)
name: Player On (cannot be switched off)
- entity: media_player.idle
name: Player Idle
- entity: media_player.playing
@@ -55,33 +60,21 @@ const CONFIGS = [
},
];
class DemoHuiMediaPlayerRows extends PolymerElement {
static get template() {
return html`
<demo-cards
id="demos"
hass="[[hass]]"
configs="[[_configs]]"
></demo-cards>
`;
@customElement("demo-hui-media-player-row")
class DemoHuiMediaPlayerRow extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
hass: Object,
};
}
public ready() {
super.ready();
const hass = provideHass(this.$.demos);
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(createMediaPlayerEntities());
}
}
customElements.define("demo-hui-media-player-rows", DemoHuiMediaPlayerRows);
customElements.define("demo-hui-media-player-row", DemoHuiMediaPlayerRow);
@@ -1,6 +1,11 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -125,26 +130,21 @@ const CONFIGS = [
},
];
class DemoPicElements extends PolymerElement {
static get template() {
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
@customElement("demo-hui-picture-elements-card")
class DemoPictureElements extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
};
}
public ready() {
super.ready();
const hass = provideHass(this.$.demos);
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
customElements.define("demo-hui-picture-elements-card", DemoPicElements);
customElements.define("demo-hui-picture-elements-card", DemoPictureElements);
@@ -1,6 +1,11 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -80,26 +85,21 @@ const CONFIGS = [
},
];
class DemoPicEntity extends PolymerElement {
static get template() {
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
@customElement("demo-hui-picture-entity-card")
class DemoPictureEntity extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
};
}
public ready() {
super.ready();
const hass = provideHass(this.$.demos);
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
customElements.define("demo-hui-picture-entity-card", DemoPicEntity);
customElements.define("demo-hui-picture-entity-card", DemoPictureEntity);
@@ -1,6 +1,11 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -121,26 +126,21 @@ const CONFIGS = [
},
];
class DemoPicGlance extends PolymerElement {
static get template() {
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
@customElement("demo-hui-picture-glance-card")
class DemoPictureGlance extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
};
}
public ready() {
super.ready();
const hass = provideHass(this.$.demos);
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
customElements.define("demo-hui-picture-glance-card", DemoPicGlance);
customElements.define("demo-hui-picture-glance-card", DemoPictureGlance);
+55
View File
@@ -0,0 +1,55 @@
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
import { createPlantEntities } from "../data/plants";
const CONFIGS = [
{
heading: "Basic example",
config: `
- type: plant-status
entity: plant.lemon_tree
`,
},
{
heading: "Problem (too bright) + low battery",
config: `
- type: plant-status
entity: plant.apple_tree
`,
},
{
heading: "With picture + multiple problems",
config: `
- type: plant-status
entity: plant.sunflowers
name: Sunflowers Name Overwrite
`,
},
];
@customElement("demo-hui-plant-card")
export class DemoPlantEntity extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(createPlantEntities());
}
}
customElements.define("demo-hui-plant-card", DemoPlantEntity);
@@ -1,6 +1,11 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -20,24 +25,19 @@ const CONFIGS = [
},
];
class DemoShoppingListEntity extends PolymerElement {
static get template() {
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
@customElement("demo-hui-shopping-list-card")
class DemoShoppingListEntity extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
};
}
public ready() {
super.ready();
const hass = provideHass(this.$.demos);
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.mockAPI("shopping_list", () => [
{ name: "list", id: 1, complete: false },
+18 -18
View File
@@ -1,6 +1,11 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { mockHistory } from "../../../demo/src/stubs/history";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
@@ -132,24 +137,19 @@ const CONFIGS = [
},
];
class DemoStack extends PolymerElement {
static get template() {
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
@customElement("demo-hui-stack-card")
class DemoStack extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
};
}
public ready() {
super.ready();
const hass = provideHass(this.$.demos);
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
mockHistory(hass);
}
+18 -18
View File
@@ -1,6 +1,11 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -74,24 +79,19 @@ const CONFIGS = [
},
];
class DemoThermostatEntity extends PolymerElement {
static get template() {
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
@customElement("demo-hui-thermostat-card")
class DemoThermostatEntity extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS,
},
};
}
public ready() {
super.ready();
const hass = provideHass(this.$.demos);
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
+65 -30
View File
@@ -1,12 +1,29 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import {
customElement,
html,
LitElement,
property,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import "../../../src/components/ha-card";
import { SUPPORT_BRIGHTNESS } from "../../../src/data/light";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-more-infos";
import {
SUPPORT_BRIGHTNESS,
SUPPORT_COLOR,
SUPPORT_COLOR_TEMP,
SUPPORT_EFFECT,
SUPPORT_FLASH,
SUPPORT_TRANSITION,
SUPPORT_WHITE_VALUE,
} from "../../../src/data/light";
import "../../../src/dialogs/more-info/more-info-content";
import { getEntity } from "../../../src/fake_data/entity";
import {
MockHomeAssistant,
provideHass,
} from "../../../src/fake_data/provide_hass";
import "../components/demo-more-infos";
const ENTITIES = [
getEntity("light", "bed_light", "on", {
@@ -14,40 +31,58 @@ const ENTITIES = [
}),
getEntity("light", "kitchen_light", "on", {
friendly_name: "Brightness Light",
brightness: 80,
brightness: 200,
supported_features: SUPPORT_BRIGHTNESS,
}),
getEntity("light", "color_temperature_light", "on", {
friendly_name: "White Color Temperature Light",
brightness: 128,
color_temp: 75,
min_mireds: 30,
max_mireds: 150,
supported_features: SUPPORT_BRIGHTNESS + SUPPORT_COLOR_TEMP,
}),
getEntity("light", "color_effectslight", "on", {
friendly_name: "Color Effets Light",
brightness: 255,
hs_color: [30, 100],
white_value: 36,
supported_features:
SUPPORT_BRIGHTNESS +
SUPPORT_EFFECT +
SUPPORT_FLASH +
SUPPORT_COLOR +
SUPPORT_TRANSITION +
SUPPORT_WHITE_VALUE,
effect_list: ["random", "colorloop"],
}),
];
class DemoMoreInfoLight extends PolymerElement {
static get template() {
@customElement("demo-more-info-light")
class DemoMoreInfoLight extends LitElement {
@property() public hass!: MockHomeAssistant;
@query("demo-more-infos") private _demoRoot!: HTMLElement;
protected render(): TemplateResult {
return html`
<demo-more-infos
hass="[[hass]]"
entities="[[_entities]]"
.hass=${this.hass}
.entities=${ENTITIES.map((ent) => ent.entityId)}
></demo-more-infos>
`;
}
static get properties() {
return {
_entities: {
type: Array,
value: ENTITIES.map((ent) => ent.entityId),
},
};
}
public ready() {
super.ready();
this._setupDemo();
}
private async _setupDemo() {
const hass = provideHass(this);
await hass.updateTranslations(null, "en");
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties);
const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
hass.addEntities(ENTITIES);
}
}
customElements.define("demo-more-info-light", DemoMoreInfoLight);
declare global {
interface HTMLElementTagNameMap {
"demo-more-info-light": DemoMoreInfoLight;
}
}
+3 -4
View File
@@ -1,9 +1,10 @@
import "@material/mwc-button";
import { html, LitElement, TemplateResult } from "lit-element";
import { customElement, html, LitElement, TemplateResult } from "lit-element";
import "../../../src/components/ha-card";
import { ActionHandlerEvent } from "../../../src/data/lovelace";
import { actionHandler } from "../../../src/panels/lovelace/common/directives/action-handler-directive";
@customElement("demo-util-long-press")
export class DemoUtilLongPress extends LitElement {
protected render(): TemplateResult {
return html`
@@ -20,7 +21,7 @@ export class DemoUtilLongPress extends LitElement {
<textarea></textarea>
<div>(try pressing and scrolling too!)</div>
<div>Try pressing and scrolling too!</div>
</ha-card>
`
)}
@@ -62,5 +63,3 @@ export class DemoUtilLongPress extends LitElement {
`;
}
}
customElements.define("demo-util-long-press", DemoUtilLongPress);
+70 -88
View File
@@ -14,54 +14,51 @@ import "../../src/styles/polymer-ha-style";
// eslint-disable-next-line import/extensions
import { DEMOS } from "../build/import-demos";
const fixPath = (path) => path.substr(2, path.length - 5);
class HaGallery extends PolymerElement {
static get template() {
return html`
<style include="iron-positioning ha-style">
:host {
-ms-user-select: initial;
-webkit-user-select: initial;
-moz-user-select: initial;
}
app-header-layout {
min-height: 100vh;
}
ha-icon-button.invisible {
visibility: hidden;
}
:host {
-ms-user-select: initial;
-webkit-user-select: initial;
-moz-user-select: initial;
}
app-header-layout {
min-height: 100vh;
}
ha-icon-button.invisible {
visibility: hidden;
}
.pickers {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: start;
}
.pickers {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: start;
}
.pickers ha-card {
width: 400px;
display: block;
margin: 16px 8px;
}
.pickers ha-card {
width: 400px;
display: block;
margin: 16px 8px;
}
.pickers ha-card:last-child {
margin-bottom: 16px;
}
.pickers ha-card:last-child {
margin-bottom: 16px;
}
.intro {
margin: -1em 0;
}
.intro {
margin: -1em 0;
}
p a {
color: var(--primary-color);
}
a {
color: var(--primary-text-color);
text-decoration: none;
}
p a {
color: var(--primary-color);
}
a {
color: var(--primary-text-color);
text-decoration: none;
}
</style>
<app-header-layout>
@@ -70,32 +67,42 @@ class HaGallery extends PolymerElement {
<ha-icon-button
icon="hass:arrow-left"
on-click="_backTapped"
class$='[[_computeHeaderButtonClass(_demo)]]'
class$="[[_computeHeaderButtonClass(_demo)]]"
></ha-icon-button>
<div main-title>[[_withDefault(_demo, "Home Assistant Gallery")]]</div>
<div main-title>
[[_withDefault(_demo, "Home Assistant Gallery")]]
</div>
</app-toolbar>
</app-header>
<div class='content'>
<div id='demo'></div>
<template is='dom-if' if='[[!_demo]]'>
<div class='pickers'>
<ha-card header="Lovelace card demos">
<div class='card-content intro'>
<div class="content">
<div id="demo"></div>
<template is="dom-if" if="[[!_demo]]">
<div class="pickers">
<ha-card header="Lovelace Card Demos">
<div class="card-content intro">
<p>
Lovelace has many different cards. Each card allows the user to tell a different story about what is going on in their house. These cards are very customizable, as no household is the same.
Lovelace has many different cards. Each card allows the user
to tell a different story about what is going on in their
house. These cards are very customizable, as no household is
the same.
</p>
<p>
This gallery helps our developers and designers to see all the different states that each card can be in.
This gallery helps our developers and designers to see all
the different states that each card can be in.
</p>
<p>
Check <a href='https://www.home-assistant.io/lovelace'>the official website</a> for instructions on how to get started with Lovelace.</a>.
Check
<a href="https://www.home-assistant.io/lovelace"
>the official website</a
>
for instructions on how to get started with Lovelace.
</p>
</div>
<template is='dom-repeat' items='[[_lovelaceDemos]]'>
<a href='#[[item]]'>
<template is="dom-repeat" items="[[_lovelaceDemos]]">
<a href="#[[item]]">
<paper-item>
<paper-item-body>{{ item }}</paper-item-body>
<ha-icon icon="hass:chevron-right"></ha-icon>
@@ -104,30 +111,10 @@ class HaGallery extends PolymerElement {
</template>
</ha-card>
<ha-card header="More Info demos">
<div class='card-content intro'>
<p>
More info screens show up when an entity is clicked.
</p>
</div>
<template is='dom-repeat' items='[[_moreInfoDemos]]'>
<a href='#[[item]]'>
<paper-item>
<paper-item-body>{{ item }}</paper-item-body>
<ha-icon icon="hass:chevron-right"></ha-icon>
</paper-item>
</a>
</template>
</ha-card>
<ha-card header="Util demos">
<div class='card-content intro'>
<p>
Test pages for our utility functions.
</p>
</div>
<template is='dom-repeat' items='[[_utilDemos]]'>
<a href='#[[item]]'>
<ha-card header="Other Demos">
<div class="card-content intro"></div>
<template is="dom-repeat" items="[[_restDemos]]">
<a href="#[[item]]">
<paper-item>
<paper-item-body>{{ item }}</paper-item-body>
<ha-icon icon="hass:chevron-right"></ha-icon>
@@ -139,7 +126,10 @@ class HaGallery extends PolymerElement {
</template>
</div>
</app-header-layout>
<notification-manager hass=[[_fakeHass]] id='notifications'></notification-manager>
<notification-manager
hass="[[_fakeHass]]"
id="notifications"
></notification-manager>
`;
}
@@ -168,13 +158,9 @@ class HaGallery extends PolymerElement {
type: Array,
computed: "_computeLovelace(_demos)",
},
_moreInfoDemos: {
_restDemos: {
type: Array,
computed: "_computeMoreInfos(_demos)",
},
_utilDemos: {
type: Array,
computed: "_computeUtil(_demos)",
computed: "_computeRest(_demos)",
},
};
}
@@ -227,12 +213,8 @@ class HaGallery extends PolymerElement {
return demos.filter((demo) => demo.includes("hui"));
}
_computeMoreInfos(demos) {
return demos.filter((demo) => demo.includes("more-info"));
}
_computeUtil(demos) {
return demos.filter((demo) => demo.includes("util"));
_computeRest(demos) {
return demos.filter((demo) => !demo.includes("hui"));
}
}
@@ -15,6 +15,7 @@ import {
HassioAddonInfo,
HassioAddonRepository,
} from "../../../src/data/hassio/addon";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import { HomeAssistant } from "../../../src/types";
import "../components/hassio-card-content";
import { filterAndSort } from "../components/hassio-filter-addons";
@@ -23,6 +24,8 @@ import { hassioStyle } from "../resources/hassio-style";
class HassioAddonRepositoryEl extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public repo!: HassioAddonRepository;
@property({ attribute: false }) public addons!: HassioAddonInfo[];
@@ -54,7 +57,11 @@ class HassioAddonRepositoryEl extends LitElement {
return html`
<div class="content">
<p class="description">
No results found in "${repo.name}."
${this.supervisor.localize(
"store.no_results_found",
"repository",
repo.name
)}
</p>
</div>
`;
@@ -83,11 +90,13 @@ class HassioAddonRepositoryEl extends LitElement {
: mdiPuzzle}
.iconTitle=${addon.installed
? addon.update_available
? "New version available"
: "Add-on is installed"
? this.supervisor.localize(
"common.new_version_available"
)
: this.supervisor.localize("addon.installed")
: addon.available
? "Add-on is not installed"
: "Add-on is not available on your system"}
? this.supervisor.localize("addon.not_installed")
: this.supervisor.localize("addon.not_available")}
.iconClass=${addon.installed
? addon.update_available
? "update"
+69 -51
View File
@@ -11,17 +11,20 @@ import {
PropertyValues,
} from "lit-element";
import { html, TemplateResult } from "lit-html";
import memoizeOne from "memoize-one";
import { atLeastVersion } from "../../../src/common/config/version";
import { fireEvent } from "../../../src/common/dom/fire_event";
import { navigate } from "../../../src/common/navigate";
import "../../../src/common/search/search-input";
import { extractSearchParam } from "../../../src/common/url/search-params";
import "../../../src/components/ha-button-menu";
import "../../../src/components/ha-svg-icon";
import {
fetchHassioAddonsInfo,
HassioAddonInfo,
HassioAddonRepository,
reloadHassioAddons,
} from "../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import "../../../src/layouts/hass-loading-screen";
import "../../../src/layouts/hass-tabs-subpage";
import { HomeAssistant, Route } from "../../../src/types";
@@ -49,58 +52,43 @@ const sortRepos = (a: HassioAddonRepository, b: HassioAddonRepository) => {
class HassioAddonStore extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ type: Boolean }) public narrow!: boolean;
@property({ attribute: false }) public route!: Route;
@property({ attribute: false }) private _addons?: HassioAddonInfo[];
@property({ attribute: false }) private _repos?: HassioAddonRepository[];
@internalProperty() private _filter?: string;
public async refreshData() {
this._repos = undefined;
this._addons = undefined;
this._filter = undefined;
await reloadHassioAddons(this.hass);
await this._loadData();
}
protected render(): TemplateResult {
const repos: TemplateResult[] = [];
let repos: TemplateResult[] = [];
if (this._repos) {
for (const repo of this._repos) {
const addons = this._addons!.filter(
(addon) => addon.repository === repo.slug
);
if (addons.length === 0) {
continue;
}
repos.push(html`
<hassio-addon-repository
.hass=${this.hass}
.repo=${repo}
.addons=${addons}
.filter=${this._filter!}
></hassio-addon-repository>
`);
}
if (this.supervisor.addon.repositories) {
repos = this.addonRepositories(
this.supervisor.addon.repositories,
this.supervisor.addon.addons,
this._filter
);
}
return html`
<hass-tabs-subpage
.hass=${this.hass}
.localizeFunc=${this.supervisor.localize}
.narrow=${this.narrow}
.route=${this.route}
hassio
main-page
.tabs=${supervisorTabs}
main-page
supervisor
>
<span slot="header">Add-on Store</span>
<span slot="header">
${this.supervisor.localize("panel.store")}
</span>
<ha-button-menu
corner="BOTTOM_START"
slot="toolbar-icon"
@@ -110,15 +98,15 @@ class HassioAddonStore extends LitElement {
<ha-svg-icon .path=${mdiDotsVertical}></ha-svg-icon>
</mwc-icon-button>
<mwc-list-item>
Repositories
${this.supervisor.localize("store.repositories")}
</mwc-list-item>
<mwc-list-item>
Reload
${this.supervisor.localize("common.reload")}
</mwc-list-item>
${this.hass.userData?.showAdvanced &&
atLeastVersion(this.hass.config.version, 0, 117)
? html`<mwc-list-item>
Registries
${this.supervisor.localize("store.registries")}
</mwc-list-item>`
: ""}
</ha-button-menu>
@@ -139,11 +127,9 @@ class HassioAddonStore extends LitElement {
${!this.hass.userData?.showAdvanced
? html`
<div class="advanced">
Missing add-ons? Enable advanced mode on
<a href="/profile" target="_top">
your profile page
${this.supervisor.localize("store.missing_addons")}
</a>
.
</div>
`
: ""}
@@ -153,14 +139,46 @@ class HassioAddonStore extends LitElement {
protected firstUpdated(changedProps: PropertyValues) {
super.firstUpdated(changedProps);
const repositoryUrl = extractSearchParam("repository_url");
navigate(this, "/hassio/store", true);
if (repositoryUrl) {
this._manageRepositories(repositoryUrl);
}
this.addEventListener("hass-api-called", (ev) => this.apiCalled(ev));
this._loadData();
}
private addonRepositories = memoizeOne(
(
repositories: HassioAddonRepository[],
addons: HassioAddonInfo[],
filter?: string
) => {
return repositories.sort(sortRepos).map((repo) => {
const filteredAddons = addons.filter(
(addon) => addon.repository === repo.slug
);
return filteredAddons.length !== 0
? html`
<hassio-addon-repository
.hass=${this.hass}
.repo=${repo}
.addons=${filteredAddons}
.filter=${filter!}
.supervisor=${this.supervisor}
></hassio-addon-repository>
`
: html``;
});
}
);
private _handleAction(ev: CustomEvent<ActionDetail>) {
switch (ev.detail.index) {
case 0:
this._manageRepositories();
this._manageRepositoriesClicked();
break;
case 1:
this.refreshData();
@@ -177,26 +195,26 @@ class HassioAddonStore extends LitElement {
}
}
private async _manageRepositories() {
private _manageRepositoriesClicked() {
this._manageRepositories();
}
private async _manageRepositories(url?: string) {
showRepositoriesDialog(this, {
repos: this._repos!,
loadData: () => this._loadData(),
supervisor: this.supervisor,
url,
});
}
private async _manageRegistries() {
showRegistriesDialog(this);
showRegistriesDialog(this, { supervisor: this.supervisor });
}
private async _loadData() {
try {
const addonsInfo = await fetchHassioAddonsInfo(this.hass);
this._repos = addonsInfo.repositories;
this._repos.sort(sortRepos);
this._addons = addonsInfo.addons;
} catch (err) {
alert(extractApiErrorMessage(err));
}
fireEvent(this, "supervisor-collection-refresh", { collection: "addon" });
fireEvent(this, "supervisor-collection-refresh", {
collection: "supervisor",
});
}
private async _filterChanged(e) {
@@ -7,13 +7,14 @@ import {
CSSResult,
customElement,
html,
internalProperty,
LitElement,
property,
internalProperty,
PropertyValues,
TemplateResult,
} from "lit-element";
import "web-animations-js/web-animations-next-lite.min";
import "../../../../src/components/buttons/ha-progress-button";
import "../../../../src/components/ha-card";
import {
HassioAddonDetails,
@@ -24,16 +25,18 @@ import {
fetchHassioHardwareAudio,
HassioHardwareAudioDevice,
} from "../../../../src/data/hassio/hardware";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { suggestAddonRestart } from "../../dialogs/suggestAddonRestart";
import { hassioStyle } from "../../resources/hassio-style";
import "../../../../src/components/buttons/ha-progress-button";
@customElement("hassio-addon-audio")
class HassioAddonAudio extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public addon!: HassioAddonDetails;
@internalProperty() private _error?: string;
@@ -48,12 +51,16 @@ class HassioAddonAudio extends LitElement {
protected render(): TemplateResult {
return html`
<ha-card header="Audio">
<ha-card
.header=${this.supervisor.localize("addon.configuration.audio.header")}
>
<div class="card-content">
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
<paper-dropdown-menu
label="Input"
.label=${this.supervisor.localize(
"addon.configuration.audio.input"
)}
@iron-select=${this._setInputDevice}
>
<paper-listbox
@@ -64,15 +71,17 @@ class HassioAddonAudio extends LitElement {
${this._inputDevices &&
this._inputDevices.map((item) => {
return html`
<paper-item device=${item.device || ""}
>${item.name}</paper-item
>
<paper-item device=${item.device || ""}>
${item.name}
</paper-item>
`;
})}
</paper-listbox>
</paper-dropdown-menu>
<paper-dropdown-menu
label="Output"
.label=${this.supervisor.localize(
"addon.configuration.audio.output"
)}
@iron-select=${this._setOutputDevice}
>
<paper-listbox
@@ -93,7 +102,7 @@ class HassioAddonAudio extends LitElement {
</div>
<div class="card-actions">
<ha-progress-button @click=${this._saveSettings}>
Save
${this.supervisor.localize("common.save")}
</ha-progress-button>
</div>
</ha-card>
@@ -152,7 +161,7 @@ class HassioAddonAudio extends LitElement {
const noDevice: HassioHardwareAudioDevice = {
device: "default",
name: "Default",
name: this.supervisor.localize("addon.configuration.audio.default"),
};
try {
@@ -189,7 +198,7 @@ class HassioAddonAudio extends LitElement {
try {
await setHassioAddonOption(this.hass, this.addon.slug, data);
if (this.addon?.state === "started") {
await suggestAddonRestart(this, this.hass, this.addon);
await suggestAddonRestart(this, this.hass, this.supervisor, this.addon);
}
} catch {
this._error = "Failed to set addon audio device";
@@ -7,11 +7,12 @@ import {
property,
TemplateResult,
} from "lit-element";
import "../../../../src/components/ha-circular-progress";
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { hassioStyle } from "../../resources/hassio-style";
import "../../../../src/components/ha-circular-progress";
import "./hassio-addon-audio";
import "./hassio-addon-config";
import "./hassio-addon-network";
@@ -20,34 +21,51 @@ import "./hassio-addon-network";
class HassioAddonConfigDashboard extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public addon?: HassioAddonDetails;
protected render(): TemplateResult {
if (!this.addon) {
return html`<ha-circular-progress active></ha-circular-progress>`;
}
const hasConfiguration =
(this.addon.options && Object.keys(this.addon.options).length) ||
(this.addon.schema && Object.keys(this.addon.schema).length);
return html`
<div class="content">
<hassio-addon-config
.hass=${this.hass}
.addon=${this.addon}
></hassio-addon-config>
${this.addon.network
${hasConfiguration || this.addon.network || this.addon.audio
? html`
<hassio-addon-network
.hass=${this.hass}
.addon=${this.addon}
></hassio-addon-network>
${hasConfiguration
? html`
<hassio-addon-config
.hass=${this.hass}
.addon=${this.addon}
.supervisor=${this.supervisor}
></hassio-addon-config>
`
: ""}
${this.addon.network
? html`
<hassio-addon-network
.hass=${this.hass}
.addon=${this.addon}
.supervisor=${this.supervisor}
></hassio-addon-network>
`
: ""}
${this.addon.audio
? html`
<hassio-addon-audio
.hass=${this.hass}
.addon=${this.addon}
.supervisor=${this.supervisor}
></hassio-addon-audio>
`
: ""}
`
: ""}
${this.addon.audio
? html`
<hassio-addon-audio
.hass=${this.hass}
.addon=${this.addon}
></hassio-addon-audio>
`
: ""}
: this.supervisor.localize("addon.configuration.no_configuration")}
</div>
`;
}
@@ -1,4 +1,7 @@
import "@material/mwc-button";
import { ActionDetail } from "@material/mwc-list";
import "@material/mwc-list/mwc-list-item";
import { mdiDotsVertical } from "@mdi/js";
import "@polymer/iron-autogrow-textarea/iron-autogrow-textarea";
import {
css,
@@ -12,9 +15,15 @@ import {
query,
TemplateResult,
} from "lit-element";
import memoizeOne from "memoize-one";
import { fireEvent } from "../../../../src/common/dom/fire_event";
import "../../../../src/components/buttons/ha-progress-button";
import "../../../../src/components/ha-button-menu";
import "../../../../src/components/ha-card";
import "../../../../src/components/ha-form/ha-form";
import type { HaFormSchema } from "../../../../src/components/ha-form/ha-form";
import "../../../../src/components/ha-formfield";
import "../../../../src/components/ha-switch";
import "../../../../src/components/ha-yaml-editor";
import type { HaYamlEditor } from "../../../../src/components/ha-yaml-editor";
import {
@@ -23,62 +32,197 @@ import {
setHassioAddonOption,
} from "../../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { showConfirmationDialog } from "../../../../src/dialogs/generic/show-dialog-box";
import { haStyle } from "../../../../src/resources/styles";
import type { HomeAssistant } from "../../../../src/types";
import { suggestAddonRestart } from "../../dialogs/suggestAddonRestart";
import { hassioStyle } from "../../resources/hassio-style";
const SUPPORTED_UI_TYPES = ["string", "select", "boolean", "integer", "float"];
@customElement("hassio-addon-config")
class HassioAddonConfig extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public addon!: HassioAddonDetails;
@internalProperty() private _error?: string;
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ type: Boolean }) private _configHasChanged = false;
@property({ type: Boolean }) private _valid = true;
@query("ha-yaml-editor", true) private _editor!: HaYamlEditor;
@internalProperty() private _canShowSchema = false;
@internalProperty() private _showOptional = false;
@internalProperty() private _error?: string;
@internalProperty() private _options?: Record<string, unknown>;
@internalProperty() private _yamlMode = false;
@query("ha-yaml-editor") private _editor?: HaYamlEditor;
public computeLabel = (entry: HaFormSchema): string => {
return (
this.addon.translations[this.hass.language]?.configuration?.[entry.name]
?.name ||
this.addon.translations.en?.configuration?.[entry.name].name ||
entry.name
);
};
private _filteredShchema = memoizeOne(
(options: Record<string, unknown>, schema: HaFormSchema[]) => {
return schema.filter((entry) => entry.name in options || entry.required);
}
);
protected render(): TemplateResult {
const showForm =
!this._yamlMode && this._canShowSchema && this.addon.schema;
const hasHiddenOptions =
showForm &&
JSON.stringify(this.addon.schema) !==
JSON.stringify(
this._filteredShchema(this.addon.options, this.addon.schema!)
);
return html`
<h1>${this.addon.name}</h1>
<ha-card header="Configuration">
<div class="card-content">
<ha-yaml-editor
@value-changed=${this._configChanged}
></ha-yaml-editor>
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
${this._valid ? "" : html` <div class="errors">Invalid YAML</div> `}
<ha-card>
<div class="header">
<h2>
${this.supervisor.localize("addon.configuration.options.header")}
</h2>
<div class="card-menu">
<ha-button-menu corner="BOTTOM_START" @action=${this._handleAction}>
<mwc-icon-button slot="trigger">
<ha-svg-icon .path=${mdiDotsVertical}></ha-svg-icon>
</mwc-icon-button>
<mwc-list-item .disabled=${!this._canShowSchema}>
${this._yamlMode
? this.supervisor.localize(
"addon.configuration.options.edit_in_ui"
)
: this.supervisor.localize(
"addon.configuration.options.edit_in_yaml"
)}
</mwc-list-item>
<mwc-list-item class="warning">
${this.supervisor.localize("common.reset_defaults")}
</mwc-list-item>
</ha-button-menu>
</div>
</div>
<div class="card-actions">
<ha-progress-button class="warning" @click=${this._resetTapped}>
Reset to defaults
</ha-progress-button>
<div class="card-content">
${showForm
? html`<ha-form
.data=${this._options!}
@value-changed=${this._configChanged}
.computeLabel=${this.computeLabel}
.schema=${this._showOptional
? this.addon.schema!
: this._filteredShchema(
this.addon.options,
this.addon.schema!
)}
></ha-form>`
: html` <ha-yaml-editor
@value-changed=${this._configChanged}
></ha-yaml-editor>`}
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
${!this._yamlMode ||
(this._canShowSchema && this.addon.schema) ||
this._valid
? ""
: html`
<div class="errors">
${this.supervisor.localize(
"addon.configuration.options.invalid_yaml"
)}
</div>
`}
</div>
${hasHiddenOptions
? html`<ha-formfield
class="show-additional"
.label=${this.supervisor.localize(
"addon.configuration.options.show_unused_optional"
)}
>
<ha-switch
@change=${this._toggleOptional}
.checked=${this._showOptional}
>
</ha-switch>
</ha-formfield>`
: ""}
<div class="card-actions right">
<ha-progress-button
@click=${this._saveTapped}
.disabled=${!this._configHasChanged || !this._valid}
>
Save
${this.supervisor.localize("common.save")}
</ha-progress-button>
</div>
</ha-card>
`;
}
protected firstUpdated(changedProps) {
super.firstUpdated(changedProps);
this._canShowSchema = !this.addon.schema!.find(
// @ts-ignore
(entry) => !SUPPORTED_UI_TYPES.includes(entry.type) || entry.multiple
);
this._yamlMode = !this._canShowSchema;
}
protected updated(changedProperties: PropertyValues): void {
super.updated(changedProperties);
if (changedProperties.has("addon")) {
this._editor.setValue(this.addon.options);
this._options = { ...this.addon.options };
}
super.updated(changedProperties);
if (
changedProperties.has("_yamlMode") ||
changedProperties.has("_options")
) {
if (this._yamlMode) {
const editor = this._editor;
if (editor) {
editor.setValue(this._options!);
}
}
}
}
private _handleAction(ev: CustomEvent<ActionDetail>) {
switch (ev.detail.index) {
case 0:
this._yamlMode = !this._yamlMode;
break;
case 1:
this._resetTapped(ev);
break;
}
}
private _toggleOptional() {
this._showOptional = !this._showOptional;
}
private _configChanged(ev): void {
this._configHasChanged = true;
this._valid = ev.detail.isValid;
if (this.addon.schema && this._canShowSchema && !this._yamlMode) {
this._valid = true;
this._configHasChanged = true;
this._options! = ev.detail.value;
} else {
this._configHasChanged = true;
this._valid = ev.detail.isValid;
}
}
private async _resetTapped(ev: CustomEvent): Promise<void> {
@@ -86,10 +230,10 @@ class HassioAddonConfig extends LitElement {
button.progress = true;
const confirmed = await showConfirmationDialog(this, {
title: this.addon.name,
text: "Are you sure you want to reset all your options?",
confirmText: "reset options",
dismissText: "no",
title: this.supervisor.localize("confirm.reset_options.title"),
text: this.supervisor.localize("confirm.reset_options.text"),
confirmText: this.supervisor.localize("common.reset_options"),
dismissText: this.supervisor.localize("common.cancel"),
});
if (!confirmed) {
@@ -111,9 +255,11 @@ class HassioAddonConfig extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
} catch (err) {
this._error = `Failed to reset addon configuration, ${extractApiErrorMessage(
err
)}`;
this._error = this.supervisor.localize(
"addon.common.update_available",
"error",
extractApiErrorMessage(err)
);
}
button.progress = false;
}
@@ -122,18 +268,13 @@ class HassioAddonConfig extends LitElement {
const button = ev.currentTarget as any;
button.progress = true;
let data: HassioAddonSetOptionParams;
this._error = undefined;
try {
data = {
options: this._editor.value,
};
} catch (err) {
this._error = err;
return;
}
try {
await setHassioAddonOption(this.hass, this.addon.slug, data);
await setHassioAddonOption(this.hass, this.addon.slug, {
options: this._yamlMode ? this._editor?.value : this._options,
});
this._configHasChanged = false;
const eventdata = {
success: true,
@@ -142,12 +283,14 @@ class HassioAddonConfig extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
if (this.addon?.state === "started") {
await suggestAddonRestart(this, this.hass, this.addon);
await suggestAddonRestart(this, this.hass, this.supervisor, this.addon);
}
} catch (err) {
this._error = `Failed to save addon configuration, ${extractApiErrorMessage(
err
)}`;
this._error = this.supervisor.localize(
"addon.configuration.options.failed_to_save",
"error",
extractApiErrorMessage(err)
);
}
button.progress = false;
}
@@ -178,6 +321,36 @@ class HassioAddonConfig extends LitElement {
.syntaxerror {
color: var(--error-color);
}
.card-menu {
float: right;
z-index: 3;
--mdc-theme-text-primary-on-background: var(--primary-text-color);
}
mwc-list-item[disabled] {
--mdc-theme-text-primary-on-background: var(--disabled-text-color);
}
.header {
display: flex;
justify-content: space-between;
}
.header h2 {
color: var(--ha-card-header-color, --primary-text-color);
font-family: var(--ha-card-header-font-family, inherit);
font-size: var(--ha-card-header-font-size, 24px);
letter-spacing: -0.012em;
line-height: 48px;
padding: 12px 16px 16px;
display: block;
margin-block: 0px;
font-weight: normal;
}
.card-actions.right {
justify-content: flex-end;
}
.show-additional {
padding: 16px;
}
`,
];
}
@@ -19,6 +19,7 @@ import {
setHassioAddonOption,
} from "../../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { suggestAddonRestart } from "../../dialogs/suggestAddonRestart";
@@ -38,6 +39,8 @@ interface NetworkItemInput extends PaperInputElement {
class HassioAddonNetwork extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public addon!: HassioAddonDetails;
@internalProperty() private _error?: string;
@@ -55,16 +58,30 @@ class HassioAddonNetwork extends LitElement {
}
return html`
<ha-card header="Network">
<ha-card
.header=${this.supervisor.localize(
"addon.configuration.network.header"
)}
>
<div class="card-content">
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
<table>
<tbody>
<tr>
<th>Container</th>
<th>Host</th>
<th>Description</th>
<th>
${this.supervisor.localize(
"addon.configuration.network.container"
)}
</th>
<th>
${this.supervisor.localize(
"addon.configuration.network.host"
)}
</th>
<th>
${this.supervisor.localize("common.description")}
</th>
</tr>
${this._config!.map((item) => {
return html`
@@ -73,13 +90,15 @@ class HassioAddonNetwork extends LitElement {
<td>
<paper-input
@value-changed=${this._configChanged}
placeholder="disabled"
placeholder="${this.supervisor.localize(
"addon.configuration.network.disabled"
)}"
.value=${item.host ? String(item.host) : ""}
.container=${item.container}
no-label-float
></paper-input>
</td>
<td>${item.description}</td>
<td>${this._computeDescription(item)}</td>
</tr>
`;
})}
@@ -88,10 +107,10 @@ class HassioAddonNetwork extends LitElement {
</div>
<div class="card-actions">
<ha-progress-button class="warning" @click=${this._resetTapped}>
Reset to defaults
${this.supervisor.localize("common.reset_defaults")}
</ha-progress-button>
<ha-progress-button @click=${this._saveTapped}>
Save
${this.supervisor.localize("common.save")}
</ha-progress-button>
</div>
</ha-card>
@@ -105,6 +124,15 @@ class HassioAddonNetwork extends LitElement {
}
}
private _computeDescription = (item: NetworkItem): string => {
return (
this.addon.translations[this.hass.language]?.network?.[item.container]
?.description ||
this.addon.translations.en?.network?.[item.container]?.description ||
item.description
);
};
private _setNetworkConfig(): void {
const network = this.addon.network || {};
const description = this.addon.network_description || {};
@@ -147,12 +175,14 @@ class HassioAddonNetwork extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
if (this.addon?.state === "started") {
await suggestAddonRestart(this, this.hass, this.addon);
await suggestAddonRestart(this, this.hass, this.supervisor, this.addon);
}
} catch (err) {
this._error = `Failed to set addon network configuration, ${extractApiErrorMessage(
err
)}`;
this._error = this.supervisor.localize(
"addon.failed_to_reset",
"error",
extractApiErrorMessage(err)
);
}
button.progress = false;
@@ -181,12 +211,14 @@ class HassioAddonNetwork extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
if (this.addon?.state === "started") {
await suggestAddonRestart(this, this.hass, this.addon);
await suggestAddonRestart(this, this.hass, this.supervisor, this.addon);
}
} catch (err) {
this._error = `Failed to set addon network configuration, ${extractApiErrorMessage(
err
)}`;
this._error = this.supervisor.localize(
"addon.failed_to_save",
"error",
extractApiErrorMessage(err)
);
}
button.progress = false;
}
@@ -1,3 +1,4 @@
import "../../../../src/components/ha-card";
import {
css,
CSSResult,
@@ -19,11 +20,14 @@ import "../../../../src/layouts/hass-loading-screen";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { hassioStyle } from "../../resources/hassio-style";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
@customElement("hassio-addon-documentation-tab")
class HassioAddonDocumentationDashboard extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public addon?: HassioAddonDetails;
@internalProperty() private _error?: string;
@@ -81,9 +85,11 @@ class HassioAddonDocumentationDashboard extends LitElement {
this.addon!.slug
);
} catch (err) {
this._error = `Failed to get addon documentation, ${extractApiErrorMessage(
err
)}`;
this._error = this.supervisor.localize(
"addon.documentation.get_logs",
"error",
extractApiErrorMessage(err)
);
}
}
}
+66 -15
View File
@@ -9,17 +9,26 @@ import {
CSSResult,
customElement,
html,
internalProperty,
LitElement,
property,
TemplateResult,
} from "lit-element";
import memoizeOne from "memoize-one";
import { fireEvent } from "../../../src/common/dom/fire_event";
import { navigate } from "../../../src/common/navigate";
import { extractSearchParam } from "../../../src/common/url/search-params";
import "../../../src/components/ha-circular-progress";
import {
fetchHassioAddonInfo,
fetchHassioAddonsInfo,
HassioAddonDetails,
} from "../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import "../../../src/layouts/hass-error-screen";
import "../../../src/layouts/hass-loading-screen";
import "../../../src/layouts/hass-tabs-subpage";
import "../../../src/components/ha-circular-progress";
import type { PageNavigation } from "../../../src/layouts/hass-tabs-subpage";
import { haStyle } from "../../../src/resources/styles";
import { HomeAssistant, Route } from "../../../src/types";
@@ -35,12 +44,16 @@ import "./log/hassio-addon-logs";
class HassioAddonDashboard extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public route!: Route;
@property({ attribute: false }) public addon?: HassioAddonDetails;
@property({ type: Boolean }) public narrow!: boolean;
@internalProperty() _error?: string;
private _computeTail = memoizeOne((route: Route) => {
const dividerPos = route.path.indexOf("/", 1);
return dividerPos === -1
@@ -55,13 +68,19 @@ class HassioAddonDashboard extends LitElement {
});
protected render(): TemplateResult {
if (this._error) {
return html`<hass-error-screen
.error=${this._error}
></hass-error-screen>`;
}
if (!this.addon) {
return html`<ha-circular-progress active></ha-circular-progress>`;
return html`<hass-loading-screen></hass-loading-screen>`;
}
const addonTabs: PageNavigation[] = [
{
name: "Info",
translationKey: "addon.panel.info",
path: `/hassio/addon/${this.addon.slug}/info`,
iconPath: mdiInformationVariant,
},
@@ -69,7 +88,7 @@ class HassioAddonDashboard extends LitElement {
if (this.addon.documentation) {
addonTabs.push({
name: "Documentation",
translationKey: "addon.panel.documentation",
path: `/hassio/addon/${this.addon.slug}/documentation`,
iconPath: mdiFileDocument,
});
@@ -78,12 +97,12 @@ class HassioAddonDashboard extends LitElement {
if (this.addon.version) {
addonTabs.push(
{
name: "Configuration",
translationKey: "addon.panel.configuration",
path: `/hassio/addon/${this.addon.slug}/config`,
iconPath: mdiCogs,
},
{
name: "Log",
translationKey: "addon.panel.log",
path: `/hassio/addon/${this.addon.slug}/logs`,
iconPath: mdiMathLog,
}
@@ -95,17 +114,19 @@ class HassioAddonDashboard extends LitElement {
return html`
<hass-tabs-subpage
.hass=${this.hass}
.localizeFunc=${this.supervisor.localize}
.narrow=${this.narrow}
.backPath=${this.addon.version ? "/hassio/dashboard" : "/hassio/store"}
.route=${route}
hassio
.tabs=${addonTabs}
supervisor
>
<span slot="header">${this.addon.name}</span>
<hassio-addon-router
.route=${route}
.narrow=${this.narrow}
.hass=${this.hass}
.supervisor=${this.supervisor}
.addon=${this.addon}
></hassio-addon-router>
</hass-tabs-subpage>
@@ -152,30 +173,60 @@ class HassioAddonDashboard extends LitElement {
}
protected async firstUpdated(): Promise<void> {
await this._routeDataChanged(this.route);
if (this.route.path === "") {
const requestedAddon = extractSearchParam("addon");
if (requestedAddon) {
const addonsInfo = await fetchHassioAddonsInfo(this.hass);
const validAddon = addonsInfo.addons
.some((addon) => addon.slug === requestedAddon);
if (!validAddon) {
this._error = this.supervisor.localize("my.error_addon_not_found");
} else {
navigate(this, `/hassio/addon/${requestedAddon}`, true);
}
}
}
this.addEventListener("hass-api-called", (ev) => this._apiCalled(ev));
}
private async _apiCalled(ev): Promise<void> {
const path: string = ev.detail.path;
const pathSplit: string[] = ev.detail.path?.split("/");
if (!path) {
if (!pathSplit || pathSplit.length === 0) {
return;
}
const path: string = pathSplit[pathSplit.length - 1];
if (["uninstall", "install", "update", "start", "stop"].includes(path)) {
fireEvent(this, "supervisor-collection-refresh", {
collection: "supervisor",
});
}
if (path === "uninstall") {
history.back();
window.history.back();
} else {
await this._routeDataChanged(this.route);
await this._routeDataChanged();
}
}
private async _routeDataChanged(routeData: Route): Promise<void> {
const addon = routeData.path.split("/")[1];
protected updated(changedProperties) {
if (changedProperties.has("route") && !this.addon) {
this._routeDataChanged();
}
}
private async _routeDataChanged(): Promise<void> {
const addon = this.route.path.split("/")[1];
if (!addon) {
return;
}
try {
const addoninfo = await fetchHassioAddonInfo(this.hass, addon);
this.addon = addoninfo;
} catch {
} catch (err) {
this._error = `Error fetching addon info: ${extractApiErrorMessage(err)}`;
this.addon = undefined;
}
}
@@ -1,5 +1,6 @@
import { customElement, property } from "lit-element";
import { HassioAddonDetails } from "../../../src/data/hassio/addon";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import {
HassRouterPage,
RouterOptions,
@@ -17,6 +18,8 @@ class HassioAddonRouter extends HassRouterPage {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public addon!: HassioAddonDetails;
protected routerOptions: RouterOptions = {
@@ -41,6 +44,7 @@ class HassioAddonRouter extends HassRouterPage {
protected updatePageEl(el) {
el.route = this.routeTail;
el.hass = this.hass;
el.supervisor = this.supervisor;
el.addon = this.addon;
el.narrow = this.narrow;
}
@@ -7,8 +7,9 @@ import {
property,
TemplateResult,
} from "lit-element";
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
import "../../../../src/components/ha-circular-progress";
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { hassioStyle } from "../../resources/hassio-style";
@@ -20,6 +21,8 @@ class HassioAddonInfoDashboard extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public addon?: HassioAddonDetails;
protected render(): TemplateResult {
@@ -32,6 +35,7 @@ class HassioAddonInfoDashboard extends LitElement {
<hassio-addon-info
.narrow=${this.narrow}
.hass=${this.hass}
.supervisor=${this.supervisor}
.addon=${this.addon}
></hassio-addon-info>
</div>
File diff suppressed because it is too large Load Diff
@@ -7,8 +7,9 @@ import {
property,
TemplateResult,
} from "lit-element";
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
import "../../../../src/components/ha-circular-progress";
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { hassioStyle } from "../../resources/hassio-style";
@@ -18,6 +19,8 @@ import "./hassio-addon-logs";
class HassioAddonLogDashboard extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public addon?: HassioAddonDetails;
protected render(): TemplateResult {
@@ -28,6 +31,7 @@ class HassioAddonLogDashboard extends LitElement {
<div class="content">
<hassio-addon-logs
.hass=${this.hass}
.supervisor=${this.supervisor}
.addon=${this.addon}
></hassio-addon-logs>
</div>
+11 -2
View File
@@ -15,6 +15,7 @@ import {
HassioAddonDetails,
} from "../../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import "../../components/hassio-ansi-to-html";
@@ -24,6 +25,8 @@ import { hassioStyle } from "../../resources/hassio-style";
class HassioAddonLogs extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public addon!: HassioAddonDetails;
@internalProperty() private _error?: string;
@@ -48,7 +51,9 @@ class HassioAddonLogs extends LitElement {
: ""}
</div>
<div class="card-actions">
<mwc-button @click=${this._refresh}>Refresh</mwc-button>
<mwc-button @click=${this._refresh}>
${this.supervisor.localize("common.refresh")}
</mwc-button>
</div>
</ha-card>
`;
@@ -76,7 +81,11 @@ class HassioAddonLogs extends LitElement {
try {
this._content = await fetchHassioAddonLogs(this.hass, this.addon.slug);
} catch (err) {
this._error = `Failed to get addon logs, ${extractApiErrorMessage(err)}`;
this._error = this.supervisor.localize(
"addon.logs.get_logs",
"error",
extractApiErrorMessage(err)
);
}
}
+1 -1
View File
@@ -44,7 +44,7 @@ class HassioCardContent extends LitElement {
${this.iconImage
? html`
<div class="icon_image ${this.iconClass}">
<img src="${this.iconImage}" title="${this.iconTitle}" />
<img src="${this.iconImage}" .title=${this.iconTitle} />
<div></div>
</div>
`
@@ -27,6 +27,8 @@ declare global {
}
}
const MAX_FILE_SIZE = 1 * 1024 * 1024 * 1024; // 1GB
@customElement("hassio-upload-snapshot")
export class HassioUploadSnapshot extends LitElement {
public hass!: HomeAssistant;
@@ -51,6 +53,20 @@ export class HassioUploadSnapshot extends LitElement {
private async _uploadFile(ev) {
const file = ev.detail.files[0];
if (file.size > MAX_FILE_SIZE) {
showAlertDialog(this, {
title: "Snapshot file is too big",
text: html`The maximum allowed filesize is 1GB.<br />
<a
href="https://www.home-assistant.io/hassio/haos_common_tasks/#restoring-a-snapshot-on-a-new-install"
target="_blank"
>Have a look here on how to restore it.</a
>`,
confirmText: "ok",
});
return;
}
if (!["application/x-tar"].includes(file.type)) {
showAlertDialog(this, {
title: "Unsupported file format",
@@ -0,0 +1,87 @@
import {
css,
CSSResult,
customElement,
html,
LitElement,
property,
TemplateResult,
} from "lit-element";
import { classMap } from "lit-html/directives/class-map";
import "../../../src/components/ha-bar";
import "../../../src/components/ha-settings-row";
import { roundWithOneDecimal } from "../../../src/util/calculate";
@customElement("supervisor-metric")
class SupervisorMetric extends LitElement {
@property({ type: Number }) public value!: number;
@property({ type: String }) public description!: string;
@property({ type: String }) public tooltip?: string;
protected render(): TemplateResult {
const roundedValue = roundWithOneDecimal(this.value);
return html`<ha-settings-row>
<span slot="heading">
${this.description}
</span>
<div slot="description" .title=${this.tooltip ?? ""}>
<span class="value">
${roundedValue} %
</span>
<ha-bar
class="${classMap({
"target-warning": roundedValue > 50,
"target-critical": roundedValue > 85,
})}"
.value=${this.value}
></ha-bar>
</div>
</ha-settings-row>`;
}
static get styles(): CSSResult {
return css`
ha-settings-row {
padding: 0;
height: 54px;
width: 100%;
}
ha-settings-row > div[slot="description"] {
white-space: normal;
color: var(--secondary-text-color);
display: flex;
justify-content: space-between;
}
ha-bar {
--ha-bar-primary-color: var(
--hassio-bar-ok-color,
var(--success-color)
);
}
.target-warning {
--ha-bar-primary-color: var(
--hassio-bar-warning-color,
var(--warning-color)
);
}
.target-critical {
--ha-bar-primary-color: var(
--hassio-bar-critical-color,
var(--error-color)
);
}
.value {
width: 42px;
padding-right: 4px;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"supervisor-metric": SupervisorMetric;
}
}
+15 -11
View File
@@ -12,7 +12,7 @@ import { atLeastVersion } from "../../../src/common/config/version";
import { navigate } from "../../../src/common/navigate";
import { compare } from "../../../src/common/string/compare";
import "../../../src/components/ha-card";
import { HassioAddonInfo } from "../../../src/data/hassio/addon";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import { haStyle } from "../../../src/resources/styles";
import { HomeAssistant } from "../../../src/types";
import "../components/hassio-card-content";
@@ -22,26 +22,24 @@ import { hassioStyle } from "../resources/hassio-style";
class HassioAddons extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public addons?: HassioAddonInfo[];
@property({ attribute: false }) public supervisor!: Supervisor;
protected render(): TemplateResult {
return html`
<div class="content">
<h1>Add-ons</h1>
<h1>${this.supervisor.localize("dashboard.addons")}</h1>
<div class="card-group">
${!this.addons?.length
${!this.supervisor.supervisor.addons?.length
? html`
<ha-card>
<div class="card-content">
You don't have any add-ons installed yet. Head over to
<button class="link" @click=${this._openStore}>
the add-on store
${this.supervisor.localize("dashboard.no_addons")}
</button>
to get started!
</div>
</ha-card>
`
: this.addons
: this.supervisor.supervisor.addons
.sort((a, b) => compare(a.name, b.name))
.map(
(addon) => html`
@@ -58,10 +56,16 @@ class HassioAddons extends LitElement {
? mdiArrowUpBoldCircle
: mdiPuzzle}
.iconTitle=${addon.state !== "started"
? "Add-on is stopped"
? this.supervisor.localize(
"dashboard.addon_stopped"
)
: addon.update_available!
? "New version available"
: "Add-on is running"}
? this.supervisor.localize(
"dashboard.addon_new_version"
)
: this.supervisor.localize(
"dashboard.addon_running"
)}
.iconClass=${addon.update_available
? addon.state === "started"
? "update"
+11 -18
View File
@@ -7,11 +7,7 @@ import {
property,
TemplateResult,
} from "lit-element";
import { HassioHassOSInfo } from "../../../src/data/hassio/host";
import {
HassioHomeAssistantInfo,
HassioSupervisorInfo,
} from "../../../src/data/hassio/supervisor";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import "../../../src/layouts/hass-tabs-subpage";
import { haStyle } from "../../../src/resources/styles";
import { HomeAssistant, Route } from "../../../src/types";
@@ -23,37 +19,34 @@ import "./hassio-update";
class HassioDashboard extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ type: Boolean }) public narrow!: boolean;
@property({ attribute: false }) public route!: Route;
@property({ attribute: false }) public supervisorInfo!: HassioSupervisorInfo;
@property({ attribute: false }) public hassInfo!: HassioHomeAssistantInfo;
@property({ attribute: false }) public hassOsInfo!: HassioHassOSInfo;
protected render(): TemplateResult {
return html`
<hass-tabs-subpage
.hass=${this.hass}
.localizeFunc=${this.supervisor.localize}
.narrow=${this.narrow}
hassio
main-page
.route=${this.route}
.tabs=${supervisorTabs}
main-page
supervisor
>
<span slot="header">Dashboard</span>
<span slot="header">
${this.supervisor.localize("panel.dashboard")}
</span>
<div class="content">
<hassio-update
.hass=${this.hass}
.hassInfo=${this.hassInfo}
.supervisorInfo=${this.supervisorInfo}
.hassOsInfo=${this.hassOsInfo}
.supervisor=${this.supervisor}
></hassio-update>
<hassio-addons
.hass=${this.hass}
.addons=${this.supervisorInfo.addons}
.supervisor=${this.supervisor}
></hassio-addons>
</div>
</hass-tabs-subpage>
+117 -54
View File
@@ -10,56 +10,58 @@ import {
TemplateResult,
} from "lit-element";
import memoizeOne from "memoize-one";
import { atLeastVersion } from "../../../src/common/config/version";
import { fireEvent } from "../../../src/common/dom/fire_event";
import "../../../src/components/buttons/ha-progress-button";
import "../../../src/components/ha-card";
import "../../../src/components/ha-settings-row";
import "../../../src/components/ha-svg-icon";
import {
extractApiErrorMessage,
HassioResponse,
ignoredStatusCodes,
ignoreSupervisorError,
} from "../../../src/data/hassio/common";
import { HassioHassOSInfo } from "../../../src/data/hassio/host";
import {
HassioHomeAssistantInfo,
HassioSupervisorInfo,
} from "../../../src/data/hassio/supervisor";
import { updateCore } from "../../../src/data/supervisor/core";
import {
Supervisor,
supervisorApiWsRequest,
} from "../../../src/data/supervisor/supervisor";
import {
showAlertDialog,
showConfirmationDialog,
} from "../../../src/dialogs/generic/show-dialog-box";
import { haStyle } from "../../../src/resources/styles";
import { HomeAssistant } from "../../../src/types";
import { showDialogSupervisorUpdate } from "../dialogs/update/show-dialog-update";
import { hassioStyle } from "../resources/hassio-style";
const computeVersion = (key: string, version: string): string => {
return key === "os" ? version : `${key}-${version}`;
};
@customElement("hassio-update")
export class HassioUpdate extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public hassInfo?: HassioHomeAssistantInfo;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public hassOsInfo?: HassioHassOSInfo;
@property({ attribute: false }) public supervisorInfo?: HassioSupervisorInfo;
private _pendingUpdates = memoizeOne(
(
core?: HassioHomeAssistantInfo,
supervisor?: HassioSupervisorInfo,
os?: HassioHassOSInfo
): number => {
return [core, supervisor, os].filter(
(value) => !!value && value?.update_available
).length;
}
);
private _pendingUpdates = memoizeOne((supervisor: Supervisor): number => {
return Object.keys(supervisor).filter(
(value) => supervisor[value].update_available
).length;
});
protected render(): TemplateResult {
const updatesAvailable = this._pendingUpdates(
this.hassInfo,
this.supervisorInfo,
this.hassOsInfo
);
if (!this.supervisor) {
return html``;
}
const updatesAvailable = this._pendingUpdates(this.supervisor);
if (!updatesAvailable) {
return html``;
}
@@ -67,33 +69,37 @@ export class HassioUpdate extends LitElement {
return html`
<div class="content">
<h1>
${updatesAvailable > 1
? "Updates Available 🎉"
: "Update Available 🎉"}
${this.supervisor.localize(
"common.update_available",
"count",
updatesAvailable
)}
🎉
</h1>
<div class="card-group">
${this._renderUpdateCard(
"Home Assistant Core",
this.hassInfo!,
"core",
this.supervisor.core,
"hassio/homeassistant/update",
`https://${
this.hassInfo?.version_latest.includes("b") ? "rc" : "www"
this.supervisor.core.version_latest.includes("b") ? "rc" : "www"
}.home-assistant.io/latest-release-notes/`
)}
${this._renderUpdateCard(
"Supervisor",
this.supervisorInfo!,
"supervisor",
this.supervisor.supervisor,
"hassio/supervisor/update",
`https://github.com//home-assistant/hassio/releases/tag/${
this.supervisorInfo!.version_latest
}`
`https://github.com//home-assistant/hassio/releases/tag/${this.supervisor.supervisor.version_latest}`
)}
${this.hassOsInfo
${this.supervisor.host.features.includes("hassos")
? this._renderUpdateCard(
"Operating System",
this.hassOsInfo,
"os",
this.supervisor.os,
"hassio/os/update",
`https://github.com//home-assistant/hassos/releases/tag/${this.hassOsInfo.version_latest}`
`https://github.com//home-assistant/hassos/releases/tag/${this.supervisor.os.version_latest}`
)
: ""}
</div>
@@ -103,6 +109,7 @@ export class HassioUpdate extends LitElement {
private _renderUpdateCard(
name: string,
key: string,
object: HassioHomeAssistantInfo | HassioSupervisorInfo | HassioHassOSInfo,
apiPath: string,
releaseNotesUrl: string
@@ -116,22 +123,39 @@ export class HassioUpdate extends LitElement {
<div class="icon">
<ha-svg-icon .path=${mdiHomeAssistant}></ha-svg-icon>
</div>
<div class="update-heading">${name} ${object.version_latest}</div>
<div class="warning">
You are currently running version ${object.version}
</div>
<div class="update-heading">${name}</div>
<ha-settings-row two-line>
<span slot="heading">
${this.supervisor.localize("common.version")}
</span>
<span slot="description">
${computeVersion(key, object.version!)}
</span>
</ha-settings-row>
<ha-settings-row two-line>
<span slot="heading">
${this.supervisor.localize("common.newest_version")}
</span>
<span slot="description">
${computeVersion(key, object.version_latest!)}
</span>
</ha-settings-row>
</div>
<div class="card-actions">
<a href="${releaseNotesUrl}" target="_blank" rel="noreferrer">
<mwc-button>Release notes</mwc-button>
<mwc-button>
${this.supervisor.localize("common.release_notes")}
</mwc-button>
</a>
<ha-progress-button
.apiPath=${apiPath}
.name=${name}
.key=${key}
.version=${object.version_latest}
@click=${this._confirmUpdate}
>
Update
${this.supervisor.localize("common.update")}
</ha-progress-button>
</div>
</ha-card>
@@ -140,12 +164,36 @@ export class HassioUpdate extends LitElement {
private async _confirmUpdate(ev): Promise<void> {
const item = ev.currentTarget;
if (item.key === "core") {
showDialogSupervisorUpdate(this, {
supervisor: this.supervisor,
name: "Home Assistant Core",
version: this.supervisor.core.version_latest,
snapshotParams: {
name: `core_${this.supervisor.core.version}`,
folders: ["homeassistant"],
homeassistant: true,
},
updateHandler: async () => this._updateCore(),
});
return;
}
item.progress = true;
const confirmed = await showConfirmationDialog(this, {
title: `Update ${item.name}`,
text: `Are you sure you want to update ${item.name} to version ${item.version}?`,
confirmText: "update",
dismissText: "cancel",
title: this.supervisor.localize(
"confirm.update.title",
"name",
item.name
),
text: this.supervisor.localize(
"confirm.update.text",
"name",
item.name,
"version",
computeVersion(item.key, item.version)
),
confirmText: this.supervisor.localize("common.update"),
dismissText: this.supervisor.localize("common.cancel"),
});
if (!confirmed) {
@@ -153,13 +201,24 @@ export class HassioUpdate extends LitElement {
return;
}
try {
await this.hass.callApi<HassioResponse<void>>("POST", item.apiPath);
if (atLeastVersion(this.hass.config.version, 2021, 2, 4)) {
await supervisorApiWsRequest(this.hass.connection, {
method: "post",
endpoint: item.apiPath.replace("hassio", ""),
timeout: null,
});
} else {
await this.hass.callApi<HassioResponse<void>>("POST", item.apiPath);
}
fireEvent(this, "supervisor-collection-refresh", {
collection: item.key,
});
} catch (err) {
// Only show an error if the status code was not expected (user behind proxy)
// or no status at all(connection terminated)
if (err.status_code && !ignoredStatusCodes.has(err.status_code)) {
if (this.hass.connection.connected && !ignoreSupervisorError(err)) {
showAlertDialog(this, {
title: "Update failed",
title: this.supervisor.localize("common.error.update_failed"),
text: extractApiErrorMessage(err),
});
}
@@ -167,6 +226,13 @@ export class HassioUpdate extends LitElement {
item.progress = false;
}
private async _updateCore(): Promise<void> {
await updateCore(this.hass);
fireEvent(this, "supervisor-collection-refresh", {
collection: "core",
});
}
static get styles(): CSSResult[] {
return [
haStyle,
@@ -184,9 +250,6 @@ export class HassioUpdate extends LitElement {
margin-bottom: 0.5em;
color: var(--primary-text-color);
}
.warning {
color: var(--secondary-text-color);
}
.card-content {
height: calc(100% - 47px);
box-sizing: border-box;
@@ -194,13 +257,13 @@ export class HassioUpdate extends LitElement {
.card-actions {
text-align: right;
}
.errors {
color: var(--error-color);
padding: 16px;
}
a {
text-decoration: none;
}
ha-settings-row {
padding: 0;
--paper-item-body-two-line-min-height: 32px;
}
`,
];
}
@@ -3,9 +3,9 @@ import {
CSSResult,
customElement,
html,
internalProperty,
LitElement,
property,
internalProperty,
TemplateResult,
} from "lit-element";
import { createCloseHeading } from "../../../../src/components/ha-dialog";
@@ -11,10 +11,7 @@ export const showHassioMarkdownDialog = (
): void => {
fireEvent(element, "show-dialog", {
dialogTag: "dialog-hassio-markdown",
dialogImport: () =>
import(
/* webpackChunkName: "dialog-hassio-markdown" */ "./dialog-hassio-markdown"
),
dialogImport: () => import("./dialog-hassio-markdown"),
dialogParams,
});
};

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