mirror of
				https://github.com/home-assistant/frontend.git
				synced 2025-10-31 14:39:38 +00:00 
			
		
		
		
	Compare commits
	
		
			642 Commits
		
	
	
		
			20250331.0
			...
			ha-icon-pa
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 31c56eb8b5 | ||
|   | 01d2ef13c6 | ||
|   | af6911e848 | ||
|   | 21af10fd28 | ||
|   | 6d30d15638 | ||
|   | d542b52ebd | ||
|   | 43cc49bb32 | ||
|   | b3f0a6328e | ||
|   | 9d6a7e7e6f | ||
|   | 78d7da21aa | ||
|   | 0474a24df6 | ||
|   | 6e7ac6fdf7 | ||
|   | 7b9683df89 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 8523ddfd29 | ||
|   | 2589e1a49f | ||
|   | 5ce5f9a189 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 6dd7217a20 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 0d02d0d334 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | fed0dfa091 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 39de40dec9 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | e1c42d9985 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | ad375c9b01 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 07230e5ef5 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 52f5af6090 | ||
|   | 3c07289077 | ||
|   | 8eb7fe8b0a | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | c8c2966d34 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | a8768a5d9d | ||
|   | 02bb7086e7 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 42d8b2ae19 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | e08f4a6bba | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 2e6c35d977 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 17305a818b | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 08389dad04 | ||
|   | ab6ace46b5 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 535dedbbc4 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 412eb0c647 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 87c8ebd493 | ||
|   | 6e49f89126 | ||
|   | a099e65a9d | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 11e4a9f056 | ||
|   | b617299eee | ||
|   | 768f27b1b9 | ||
|   | 5ed816df6d | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 6692ac7517 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 65499db0cb | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 11a1eabf61 | ||
|   | b30fa122ba | ||
|   | 6730d08b85 | ||
|   | 67003d6fd1 | ||
|   | 414d46be65 | ||
|   | 1485d1a1de | ||
|   | fd13e41524 | ||
|   | 77f7ca0368 | ||
|   | 7471250a07 | ||
|   | 8b0a63d791 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 57ffa814ed | ||
|   | 16e20456e2 | ||
|   | 9c0ce41ebb | ||
|   | b458a1d7c6 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 0eaeeb1141 | ||
|   | b7e63e697f | ||
|   | 06db0f4b98 | ||
|   | d33636c6fb | ||
|   | bbb546159c | ||
|   | e8fc36026a | ||
|   | 38f8c804af | ||
|   | 7c5bf26240 | ||
|   | 189067d14b | ||
|   | e79e0f77b8 | ||
|   | b226e5c697 | ||
|   | 52ad31601c | ||
|   | cba3e4df7f | ||
|   | 3532cfa974 | ||
|   | 629eb29d42 | ||
|   | 61019447cf | ||
|   | cde2b436d1 | ||
|   | 6c7d750734 | ||
|   | fcf5ed7731 | ||
|   | 3ce639946c | ||
|   | bb5f01ac81 | ||
|   | 208e863327 | ||
|   | 9f5f100e98 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 114c1fb98b | ||
|   | 3e5bd64b83 | ||
|   | 02b4b8e334 | ||
|   | da8d43f5d1 | ||
|   | 18aaa44d2d | ||
|   | 7fa697a768 | ||
|   | 28fe60f02b | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 549451eccb | ||
|   | 113cc118cf | ||
|   | 7ffb0f1e3b | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 60ef43044b | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 4e4a82e023 | ||
|   | f563146165 | ||
|   | 81ba2db93a | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 4d8176ad6e | ||
|   | 9b8be9f1af | ||
|   | c11d2c10df | ||
|   | 412a0e9f6a | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 67dc830bbf | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 5581c10139 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | ec26818c53 | ||
|   | 399458f811 | ||
|   | 3355986585 | ||
|   | 9b7db191a6 | ||
|   | 2d549ba22f | ||
|   | c3e155a95c | ||
|   | 754829a836 | ||
|   | 87bd039239 | ||
|   | 32b3c83337 | ||
|   | f0beef22d2 | ||
|   | 07e5f53469 | ||
|   | 97e0217906 | ||
|   | 006c7e1ea8 | ||
|   | 9736d0cb55 | ||
|   | 9ec689382b | ||
|   | 4de95f6710 | ||
|   | a55ef8ad47 | ||
|   | 01b398c2a3 | ||
|   | 83df10ef29 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | a026c72230 | ||
|   | c4e391c264 | ||
|   | 4b72a6029c | ||
|   | 8b87188075 | ||
|   | 2a4c6c9af5 | ||
|   | 5cbadaa5f9 | ||
|   | 15fd4134d0 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | eda9abc3c5 | ||
|   | 7e56d5f351 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 5d4805cde6 | ||
|   | c94326bc08 | ||
|   | b61180baa6 | ||
|   | bc15d1474e | ||
|   | 95c3013497 | ||
|   | 69a156f352 | ||
|   | 67f3d31a4b | ||
|   | 98a2966432 | ||
|   | 75a2c061c2 | ||
|   | 724df18175 | ||
|   | c00b4120ab | ||
|   | d392bb4c83 | ||
|   | 30d46f2f8a | ||
|   | 7c879cc291 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 9a731880f3 | ||
|   | 77efaaf7de | ||
|   | da96266454 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 036d739d6e | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | c274a94ee5 | ||
|   | da7d359696 | ||
|   | 20a7b3870c | ||
|   | 9749a64ae1 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 68741f6ba4 | ||
|   | e052ee04b4 | ||
|   | d2cc4a624e | ||
|   | 5bcbe98f8e | ||
|   | beee76580d | ||
|   | 28e5a30772 | ||
|   | 785929b370 | ||
|   | 55cf7e635d | ||
|   | 4b270eb444 | ||
|   | d0e55719d1 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 87f9397643 | ||
|   | 910e7e10a7 | ||
|   | e1b9b47ac7 | ||
|   | 89e04fcc45 | ||
|   | 93f2e75fc9 | ||
|   | 6c671d398f | ||
|   | 2e5c6a4d3f | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 04e736a51e | ||
|   | ec3fdc0ea7 | ||
|   | a7a8c25d24 | ||
|   | 60d457c3d9 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | a58b1e636d | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | f67e7ae081 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 0032c5508e | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 036df78de8 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 617a6ba938 | ||
|   | 76b9063aec | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 60c1d0a556 | ||
|   | 193caec2df | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 42c8d132bf | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 0311a7c976 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 40ffd50b8a | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 334991902a | ||
|   | c968266065 | ||
|   | d4fc0318f7 | ||
|   | 8a0d3baf67 | ||
|   | 8fc55cb6e2 | ||
|   | d6ebd9bfc4 | ||
|   | 15ae37d077 | ||
|   | 461d5eb687 | ||
|   | 3058fcad46 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 06bd1ae4cd | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 00733357a1 | ||
|   | 7f6ce97199 | ||
|   | 0742aed8e7 | ||
|   | f675dd3388 | ||
|   | 9751cb4e50 | ||
|   | 7919028780 | ||
|   | 1508c7c905 | ||
|   | 3fe907f388 | ||
|   | 5cc87661b9 | ||
|   | fc372172a6 | ||
|   | 7bd9a39bf5 | ||
|   | 665c971822 | ||
|   | eff5471dd1 | ||
|   | 4fba9c3c0a | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 0b32b51e2f | ||
|   | 6370b0b8e5 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 681518f443 | ||
|   | 9f5b89978d | ||
|   | 130839ee7b | ||
|   | ba4ec960c8 | ||
|   | 6692d9c6aa | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 4d2d94c54f | ||
|   | d59c6612c6 | ||
|   | 498f158253 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | b8026ccf46 | ||
|   | 84def48222 | ||
|   | cea0ac02fe | ||
|   | e1b099e88b | ||
|   | d571ef3f18 | ||
|   | c8cffef647 | ||
|   | 6b568307a4 | ||
|   | 1b501907f1 | ||
|   | c7e79998a4 | ||
|   | 03ccf014d9 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | ab41bdb87d | ||
|   | 821a0bc418 | ||
|   | 6d931b9e37 | ||
|   | f0341f28ab | ||
|   | 603663e0cc | ||
|   | 80dddc9eef | ||
|   | b823a3b139 | ||
|   | 47c9a407e6 | ||
|   | 8494d0542e | ||
|   | 467a5bef0b | ||
|   | 24736e36ff | ||
|   | 604c00d772 | ||
|   | 12bbba1bff | ||
|   | c0ba48beb6 | ||
|   | 075e1df204 | ||
|   | 22c57853b4 | ||
|   | fe824062a5 | ||
|   | e3221ad4ee | ||
|   | 7d3a7fa1db | ||
|   | 5e67bf1fa7 | ||
|   | 7147c7578d | ||
|   | 90710fedf2 | ||
|   | 9629159ef1 | ||
|   | bfac6e1516 | ||
|   | 7c288d1769 | ||
|   | 39119eeb2a | ||
|   | 9c16ce3342 | ||
|   | 3595fab5cb | ||
|   | 78b2d17f10 | ||
|   | 92bf9b4979 | ||
|   | ac616a4d3d | ||
|   | 1aa1bfda2c | ||
|   | 38a5035d68 | ||
|   | 042cd0d3a3 | ||
|   | 00d708fbd4 | ||
|   | 852278e8aa | ||
|   | 15dcdffe55 | ||
|   | 0729aaacb8 | ||
|   | 92b8cd8f45 | ||
|   | ad8d3dd598 | ||
|   | d618c25095 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 83289bdd41 | ||
|   | 7b8b8f9d0b | ||
|   | b7f866faff | ||
|   | 37671fd613 | ||
|   | 92905c1433 | ||
|   | cb7251cb5e | ||
|   | 44485c0de4 | ||
|   | 1191a09576 | ||
|   | c178488aac | ||
|   | 9f6463eec0 | ||
|   | 70fef59401 | ||
|   | 3e053e07c6 | ||
|   | 376cac6002 | ||
|   | 5cd68301ed | ||
|   | 3121721ac7 | ||
|   | 868daf692d | ||
|   | 75e9ac9e73 | ||
|   | f6e36f2038 | ||
|   | 55770f3e02 | ||
|   | cfc7f91f03 | ||
|   | 74488c0b96 | ||
|   | c7882f3926 | ||
|   | 7434b12d9f | ||
|   | 9081441d95 | ||
|   | d63f610023 | ||
|   | e069875432 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 91026b0986 | ||
|   | 4ec5fbc9a4 | ||
|   | fb3a59272d | ||
|   | 9155c85509 | ||
|   | 9d74cd7561 | ||
|   | 22ddcca954 | ||
|   | 8f422357f1 | ||
|   | 44f5f7bdb5 | ||
|   | 83819a9be0 | ||
|   | 3c9dce20e2 | ||
|   | a19e7002ea | ||
|   | 75608db9b8 | ||
|   | 08f30b714b | ||
|   | 9983129e26 | ||
|   | 40fe62c2ec | ||
|   | d7660370ab | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | bdad76937e | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | d2822308ec | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 99b94e799d | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 1fb28df1a6 | ||
|   | 1154d1769d | ||
|   | a820cd4576 | ||
|   | 678a8a85cb | ||
|   | 358e450e60 | ||
|   | 32acef8fad | ||
|   | fae619085c | ||
|   | 5d89563aa5 | ||
|   | d7dd11ba7f | ||
|   | 4624cc609f | ||
|   | f24b6a4cb1 | ||
|   | 2b06742bb9 | ||
|   | 9e5b7462af | ||
|   | a544ff4c8a | ||
|   | b81d2013dc | ||
|   | 9b7e2886b6 | ||
|   | 69eaf178ca | ||
|   | 1a14511fa6 | ||
|   | b4e8c56f58 | ||
|   | 17cc63deba | ||
|   | b4f1c8755d | ||
|   | b0d4c699db | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | c07bf68161 | ||
|   | d1a0eaece5 | ||
|   | f608783551 | ||
|   | dddba58d38 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | ebc16d6520 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 4ed8ecad01 | ||
|   | c26fb1713d | ||
|   | 2b7b17625e | ||
|   | cd3e4f55e2 | ||
|   | 1c12aea8f6 | ||
|   | 3722f971ca | ||
|   | 409f665641 | ||
|   | 5b3b17ef6d | ||
|   | 05b49e8c80 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 2dbdbb4b64 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | a825b632bf | ||
|   | f8d706277d | ||
|   | e517175f68 | ||
|   | ee9cbf7370 | ||
|   | efd7b380a9 | ||
|   | 46cc254f77 | ||
|   | 221bc732fb | ||
|   | 055c18463c | ||
|   | d996ba818f | ||
|   | e5f41ceb3e | ||
|   | 2e4ce71d06 | ||
|   | 50e39de974 | ||
|   | 1ba941282c | ||
|   | b656ddc1f0 | ||
|   | ddd51ff097 | ||
|   | 55c75096d0 | ||
|   | fd3502f3bc | ||
|   | 7d6bec01ae | ||
|   | a699149388 | ||
|   | 0aeb8fa75c | ||
|   | 456a44fdfd | ||
|   | 53a0b311de | ||
|   | ded5ade0f2 | ||
|   | 5d2d6dcd6c | ||
|   | 92353ebed5 | ||
|   | bc582db7fc | ||
|   | ab415188ba | ||
|   | 29c11978b3 | ||
|   | 574f9e8936 | ||
|   | fddc00bfab | ||
|   | ff5cbb0613 | ||
|   | 498d933c06 | ||
|   | f9fbb254bf | ||
|   | 536602580d | ||
|   | c111bf1062 | ||
|   | 0242fbc6f8 | ||
|   | f65a0ef4f7 | ||
|   | 92521d4565 | ||
|   | 66dbafb5f5 | ||
|   | 7c46d2d2f4 | ||
|   | ca642d46cc | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 9a52185e13 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 39a73774b0 | ||
|   | b25b170539 | ||
|   | 6442606fc5 | ||
|   | 1b79869c87 | ||
|   | 672fbc6007 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | e1899836bf | ||
|   | e90967d200 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 631bfe46ba | ||
|   | a5762f07ac | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | bf7422e4c5 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 45994e7989 | ||
|   | 995e3f10ad | ||
|   | 6464c2b602 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 8901c1fb31 | ||
|   | 1f5f18f7e7 | ||
|   | 51ca3e277c | ||
|   | ee495a432f | ||
|   | d75ea3bb8d | ||
|   | 40fbeaae1c | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | dc2c6cee21 | ||
|   | 3b0cd9e3ae | ||
|   | 834ece8547 | ||
|   | b7aa296be7 | ||
|   | 0cab6c9e2e | ||
|   | 94c8665528 | ||
|   | c7ca654926 | ||
|   | 488599905b | ||
|   | 221e1d9ed8 | ||
|   | 0229f67751 | ||
|   | 3a0c367f76 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | af0854e480 | ||
|   | 14f4120926 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | e2bd464001 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | eb9f81d9a1 | ||
|   | 078209d154 | ||
|   | 7a617600ad | ||
|   | ae74e3496c | ||
|   | c0f304ad40 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | c794a2734b | ||
|   | e156dd36f4 | ||
|   | c40bf8f3cd | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 93485d8b57 | ||
|   | ce5cdaa496 | ||
|   | dcbaa31c96 | ||
|   | 71b2e5f827 | ||
|   | d58590b534 | ||
|   | b2044e88b6 | ||
|   | 94b5ed97c6 | ||
|   | 11b8f6210f | ||
|   | 8e778cfc32 | ||
|   | 4c6a5ed2e3 | ||
|   | 48c90267df | ||
|   | fcab356639 | ||
|   | a70a0d4b4a | ||
|   | 5a34560381 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | f71245893a | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 1e7bfd59f2 | ||
|   | 1c15116052 | ||
|   | 3647722824 | ||
|   | 713dd68089 | ||
|   | 53dd0cbaa8 | ||
|   | 6bf8faa96a | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 09a17131ab | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 7f20b2d6d2 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | fa05cd0c90 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 0b7fc330b3 | ||
|   | 6aa78794a7 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 3f17548582 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 0cee3c2882 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 5753b3e166 | ||
|   | 7b78d821f9 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 9a4469588c | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | f9eadf08fd | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | c630176fcf | ||
|   | 0389fbba52 | ||
|   | d56c7c41e2 | ||
|   | e74cac697e | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 77216e8e76 | ||
|   | 02a8924f63 | ||
|   | 9fc28e5abb | ||
|   | 933fb1327a | ||
|   | c73a9fccb8 | ||
|   | 38c11e738e | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 93c5632ee0 | ||
|   | 5459eaff30 | ||
|   | b02f1037fb | ||
|   | 3d130b790c | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | e23d2392d8 | ||
|   | d5a6e16bf8 | ||
|   | 91a5497c60 | ||
|   | 65dae09a49 | ||
|   | 7e0f293d1f | ||
|   | 2682011ae6 | ||
|   | 1bba103a3d | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | e425375d55 | ||
|   | a2689eee63 | ||
|   | 74741c5d69 | ||
|   | 53426d647a | ||
|   | f6e4f4c0d6 | ||
|   | 2f086f4d00 | ||
|   | cd91e8c07c | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | b3a5ea2893 | ||
|   | 98ae0295b4 | ||
|   | 43bb9d3401 | ||
|   | 8ad4385d67 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 8fb7c1594a | ||
|   | 4fca09f9ae | ||
|   | 6793753755 | ||
|   | f4e3fdb98e | ||
|   | 63f4cc456c | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 33735abfb0 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 22b59b247e | ||
|   | 6d7a40368c | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | fbeb457c25 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 4a6834f0d9 | ||
|   | add417a166 | ||
|   | ae4f43496e | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 4ce792e5bf | ||
|   | b9433b96dc | ||
|   | 1dfd937c94 | ||
|   | 6a333a4774 | ||
|   | 7742ccf631 | ||
|   | 20f2a8d53e | ||
|   | ec9fbe7d77 | ||
|   | 6fa226d30a | ||
|   | b76a723fd9 | ||
|   | 5237cc72b7 | ||
|   | 63d2718f67 | ||
|   | 14e0666c3a | ||
|   | 929a0b9cd4 | ||
|   | 0541270695 | ||
|   | 20d357fb13 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 6658c10b94 | ||
|   | c2ce02652b | ||
|   | 634db1944f | ||
|   | 21b3177f95 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 7383e3247b | ||
|   | b33e4bf305 | ||
|   | 9d9522cade | ||
|   | 430e47c0fc | ||
|   | a6c9702ab2 | ||
|   | e3122e8e4d | ||
|   | c8e46bd239 | ||
|   | 4fd87a1d7c | ||
|   | 80151ff759 | ||
|   | 5f187c1bb3 | ||
|   | ddc04dd48a | ||
|   | 228acf1fae | ||
|   | 74acd7ec38 | ||
|   | 9bc867d0dc | ||
|   | 590df8dd1a | ||
|   | ccee57f4a5 | ||
|   | 828bf977b2 | ||
|   | a2b3ea2ac6 | ||
|   | 9c3f77532c | ||
|   | 4a1cf250c4 | ||
|   | 9df5141aac | ||
|   | 13aeb02b53 | ||
|   | f0f60bae78 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | d1465a79ae | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 6fe8af7c75 | ||
|   | 21180d066e | ||
|   | dec968af54 | ||
|   | 2ccc5355c4 | ||
|   | 316c3f4e1f | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | f88d0ca613 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | edd4a3c31f | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | a7ee98e7de | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 1b6ed8cdc3 | ||
|   | 671049beb2 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | daf4158fa0 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 848713858f | ||
|   | f0ef7e0c53 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | e10b0fad95 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 8d50bb1d2b | ||
|   | 1e26f155a7 | ||
|   | 27e13017c3 | ||
|   | 88f1dc9c16 | ||
|   | 825e707a80 | ||
|   | a15f0c7814 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | e37f7219c2 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 570076c539 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | cfeb0336d1 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | b18cc4dcfb | ||
|   | e271989cee | ||
|   | ca223f9d73 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 8fb1cf35ad | ||
|   | 9f59be492e | ||
|   | 8429d114a8 | ||
|   | 4fbc155f8b | ||
|   | 0bcaa104e7 | ||
|   | 6b3f807129 | ||
|   | c464d344db | ||
|   | 69f0a4a728 | ||
|   | cd39e2d0f2 | ||
|   | a23f57256c | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | c279efaa99 | ||
|   | c4389ec119 | ||
|   | 50d632f8d4 | ||
|   | dba2fba828 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 3890afddb9 | ||
|   | 76f187ee2c | ||
|   | 488b54cf19 | ||
|   | 29d2c29af3 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | a2f9101a9f | ||
|   | 7893eba7a7 | ||
|   | 94ced8af32 | ||
|   | c4b5882b2d | ||
|   | 6e8bac2e58 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 8a2ab2eab4 | ||
|   | c7e5be185d | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | e98721aa76 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 4c8d661c63 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | b7c60ffc74 | ||
|   | db6c728cd6 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 34f8335a9d | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | ecf5068bd0 | ||
|   | 0a2a2b8a70 | ||
|   | 52f4fe6bc0 | ||
|   | a781bca94b | ||
|   | 63b44c25f8 | ||
|   | b96319703a | ||
|   | 9e686190f6 | ||
|   | 5ca7b1d508 | ||
|   | 7c1d74c6c3 | ||
|   | d257f667c1 | ||
|   | 842a064682 | ||
|   | 3d8e146582 | ||
|   | 78e8bd4305 | ||
|   | 0152a79bd5 | ||
|   | f5bb72f067 | ||
|   | 9ca6a886f5 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | f39011f8f4 | ||
|   | 8b190867e3 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 321b15a270 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 6ba235d540 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | e34fd8161c | ||
|   | 084cda8218 | ||
|   | f06a0fa34c | ||
|   | 750c59399b | ||
|   | a6a17cd70c | ||
|   | de1c6a5178 | ||
|   | 04c3cd7d68 | ||
|   | 17ef74d680 | ||
|   | 098c6a2567 | ||
|   | 899288ae43 | ||
|   | a9823f30e3 | ||
|   | 97966805fa | 
| @@ -21,7 +21,8 @@ | |||||||
|         "esbenp.prettier-vscode", |         "esbenp.prettier-vscode", | ||||||
|         "runem.lit-plugin", |         "runem.lit-plugin", | ||||||
|         "github.vscode-pull-request-github", |         "github.vscode-pull-request-github", | ||||||
|         "eamodio.gitlens" |         "eamodio.gitlens", | ||||||
|  |         "yeion7.styled-global-variables-autocomplete" | ||||||
|       ], |       ], | ||||||
|       "settings": { |       "settings": { | ||||||
|         "files.eol": "\n", |         "files.eol": "\n", | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								.github/ISSUE_TEMPLATE/bug_report.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/ISSUE_TEMPLATE/bug_report.yml
									
									
									
									
										vendored
									
									
								
							| @@ -108,9 +108,9 @@ body: | |||||||
|       render: yaml |       render: yaml | ||||||
|   - type: textarea |   - type: textarea | ||||||
|     attributes: |     attributes: | ||||||
|       label: Javascript errors shown in your browser console/inspector |       label: JavaScript errors shown in your browser console/inspector | ||||||
|       description: > |       description: > | ||||||
|         If you come across any Javascript or other error logs, e.g., in your |         If you come across any JavaScript or other error logs, e.g., in your | ||||||
|         browser console/inspector please provide them. |         browser console/inspector please provide them. | ||||||
|       render: txt |       render: txt | ||||||
|   - type: textarea |   - type: textarea | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								.github/workflows/cast_deployment.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								.github/workflows/cast_deployment.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -26,7 +26,7 @@ jobs: | |||||||
|           ref: dev |           ref: dev | ||||||
|  |  | ||||||
|       - name: Setup Node |       - name: Setup Node | ||||||
|         uses: actions/setup-node@v4.3.0 |         uses: actions/setup-node@v4.4.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version-file: ".nvmrc" | ||||||
|           cache: yarn |           cache: yarn | ||||||
| @@ -41,9 +41,8 @@ jobs: | |||||||
|  |  | ||||||
|       - name: Deploy to Netlify |       - name: Deploy to Netlify | ||||||
|         id: deploy |         id: deploy | ||||||
|         uses: netlify/actions/cli@master |         run: | | ||||||
|         with: |           npx -y netlify-cli deploy --dir=cast/dist --alias dev | ||||||
|           args: deploy --dir=cast/dist --alias dev |  | ||||||
|         env: |         env: | ||||||
|           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} |           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} | ||||||
|           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_CAST_SITE_ID }} |           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_CAST_SITE_ID }} | ||||||
| @@ -62,7 +61,7 @@ jobs: | |||||||
|           ref: master |           ref: master | ||||||
|  |  | ||||||
|       - name: Setup Node |       - name: Setup Node | ||||||
|         uses: actions/setup-node@v4.3.0 |         uses: actions/setup-node@v4.4.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version-file: ".nvmrc" | ||||||
|           cache: yarn |           cache: yarn | ||||||
| @@ -77,9 +76,8 @@ jobs: | |||||||
|  |  | ||||||
|       - name: Deploy to Netlify |       - name: Deploy to Netlify | ||||||
|         id: deploy |         id: deploy | ||||||
|         uses: netlify/actions/cli@master |         run: | | ||||||
|         with: |           npx -y netlify-cli deploy --dir=cast/dist --prod | ||||||
|           args: deploy --dir=cast/dist --prod |  | ||||||
|         env: |         env: | ||||||
|           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} |           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} | ||||||
|           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_CAST_SITE_ID }} |           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_CAST_SITE_ID }} | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								.github/workflows/ci.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/ci.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -26,7 +26,7 @@ jobs: | |||||||
|       - name: Check out files from GitHub |       - name: Check out files from GitHub | ||||||
|         uses: actions/checkout@v4.2.2 |         uses: actions/checkout@v4.2.2 | ||||||
|       - name: Setup Node |       - name: Setup Node | ||||||
|         uses: actions/setup-node@v4.3.0 |         uses: actions/setup-node@v4.4.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version-file: ".nvmrc" | ||||||
|           cache: yarn |           cache: yarn | ||||||
| @@ -60,7 +60,7 @@ jobs: | |||||||
|       - name: Check out files from GitHub |       - name: Check out files from GitHub | ||||||
|         uses: actions/checkout@v4.2.2 |         uses: actions/checkout@v4.2.2 | ||||||
|       - name: Setup Node |       - name: Setup Node | ||||||
|         uses: actions/setup-node@v4.3.0 |         uses: actions/setup-node@v4.4.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version-file: ".nvmrc" | ||||||
|           cache: yarn |           cache: yarn | ||||||
| @@ -78,7 +78,7 @@ jobs: | |||||||
|       - name: Check out files from GitHub |       - name: Check out files from GitHub | ||||||
|         uses: actions/checkout@v4.2.2 |         uses: actions/checkout@v4.2.2 | ||||||
|       - name: Setup Node |       - name: Setup Node | ||||||
|         uses: actions/setup-node@v4.3.0 |         uses: actions/setup-node@v4.4.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version-file: ".nvmrc" | ||||||
|           cache: yarn |           cache: yarn | ||||||
| @@ -102,7 +102,7 @@ jobs: | |||||||
|       - name: Check out files from GitHub |       - name: Check out files from GitHub | ||||||
|         uses: actions/checkout@v4.2.2 |         uses: actions/checkout@v4.2.2 | ||||||
|       - name: Setup Node |       - name: Setup Node | ||||||
|         uses: actions/setup-node@v4.3.0 |         uses: actions/setup-node@v4.4.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version-file: ".nvmrc" | ||||||
|           cache: yarn |           cache: yarn | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								.github/workflows/demo_deployment.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								.github/workflows/demo_deployment.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -27,7 +27,7 @@ jobs: | |||||||
|           ref: dev |           ref: dev | ||||||
|  |  | ||||||
|       - name: Setup Node |       - name: Setup Node | ||||||
|         uses: actions/setup-node@v4.3.0 |         uses: actions/setup-node@v4.4.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version-file: ".nvmrc" | ||||||
|           cache: yarn |           cache: yarn | ||||||
| @@ -42,9 +42,8 @@ jobs: | |||||||
|  |  | ||||||
|       - name: Deploy to Netlify |       - name: Deploy to Netlify | ||||||
|         id: deploy |         id: deploy | ||||||
|         uses: netlify/actions/cli@master |         run: | | ||||||
|         with: |           npx -y netlify-cli deploy --dir=demo/dist --prod | ||||||
|           args: deploy --dir=demo/dist --prod |  | ||||||
|         env: |         env: | ||||||
|           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} |           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} | ||||||
|           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_DEMO_DEV_SITE_ID }} |           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_DEMO_DEV_SITE_ID }} | ||||||
| @@ -63,7 +62,7 @@ jobs: | |||||||
|           ref: master |           ref: master | ||||||
|  |  | ||||||
|       - name: Setup Node |       - name: Setup Node | ||||||
|         uses: actions/setup-node@v4.3.0 |         uses: actions/setup-node@v4.4.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version-file: ".nvmrc" | ||||||
|           cache: yarn |           cache: yarn | ||||||
| @@ -78,9 +77,8 @@ jobs: | |||||||
|  |  | ||||||
|       - name: Deploy to Netlify |       - name: Deploy to Netlify | ||||||
|         id: deploy |         id: deploy | ||||||
|         uses: netlify/actions/cli@master |         run: | | ||||||
|         with: |           npx -y netlify-cli deploy --dir=demo/dist --prod | ||||||
|           args: deploy --dir=demo/dist --prod |  | ||||||
|         env: |         env: | ||||||
|           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} |           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} | ||||||
|           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_DEMO_SITE_ID }} |           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_DEMO_SITE_ID }} | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								.github/workflows/design_deployment.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.github/workflows/design_deployment.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -19,7 +19,7 @@ jobs: | |||||||
|         uses: actions/checkout@v4.2.2 |         uses: actions/checkout@v4.2.2 | ||||||
|  |  | ||||||
|       - name: Setup Node |       - name: Setup Node | ||||||
|         uses: actions/setup-node@v4.3.0 |         uses: actions/setup-node@v4.4.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version-file: ".nvmrc" | ||||||
|           cache: yarn |           cache: yarn | ||||||
| @@ -34,9 +34,8 @@ jobs: | |||||||
|  |  | ||||||
|       - name: Deploy to Netlify |       - name: Deploy to Netlify | ||||||
|         id: deploy |         id: deploy | ||||||
|         uses: netlify/actions/cli@master |         run: | | ||||||
|         with: |           npx -y netlify-cli deploy --dir=gallery/dist --prod | ||||||
|           args: deploy --dir=gallery/dist --prod |  | ||||||
|         env: |         env: | ||||||
|           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} |           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} | ||||||
|           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_GALLERY_SITE_ID }} |           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_GALLERY_SITE_ID }} | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								.github/workflows/design_preview.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								.github/workflows/design_preview.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -24,7 +24,7 @@ jobs: | |||||||
|         uses: actions/checkout@v4.2.2 |         uses: actions/checkout@v4.2.2 | ||||||
|  |  | ||||||
|       - name: Setup Node |       - name: Setup Node | ||||||
|         uses: actions/setup-node@v4.3.0 |         uses: actions/setup-node@v4.4.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version-file: ".nvmrc" | ||||||
|           cache: yarn |           cache: yarn | ||||||
| @@ -39,13 +39,14 @@ jobs: | |||||||
|  |  | ||||||
|       - name: Deploy preview to Netlify |       - name: Deploy preview to Netlify | ||||||
|         id: deploy |         id: deploy | ||||||
|         uses: netlify/actions/cli@master |         run: | | ||||||
|         with: |           npx -y netlify-cli deploy --dir=gallery/dist --alias "deploy-preview-${{ github.event.number }}" \ | ||||||
|           args: deploy --dir=gallery/dist --alias "deploy-preview-${{ github.event.number }}" |             --json > deploy_output.json | ||||||
|         env: |         env: | ||||||
|           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} |           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} | ||||||
|           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_GALLERY_SITE_ID }} |           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_GALLERY_SITE_ID }} | ||||||
|  |  | ||||||
|       - name: Generate summary |       - name: Generate summary | ||||||
|         run: | |         run: | | ||||||
|           echo "${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}" >> "$GITHUB_STEP_SUMMARY" |           NETLIFY_LIVE_URL=$(jq -r '.deploy_url' deploy_output.json) | ||||||
|  |           echo "$NETLIFY_LIVE_URL" >> "$GITHUB_STEP_SUMMARY" | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.github/workflows/nightly.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/nightly.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -28,7 +28,7 @@ jobs: | |||||||
|           python-version: ${{ env.PYTHON_VERSION }} |           python-version: ${{ env.PYTHON_VERSION }} | ||||||
|  |  | ||||||
|       - name: Setup Node |       - name: Setup Node | ||||||
|         uses: actions/setup-node@v4.3.0 |         uses: actions/setup-node@v4.4.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version-file: ".nvmrc" | ||||||
|           cache: yarn |           cache: yarn | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.github/workflows/relative-ci.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/relative-ci.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -17,7 +17,7 @@ jobs: | |||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|       - name: Send bundle stats and build information to RelativeCI |       - name: Send bundle stats and build information to RelativeCI | ||||||
|         uses: relative-ci/agent-action@v2.2.0 |         uses: relative-ci/agent-action@v3.0.0 | ||||||
|         with: |         with: | ||||||
|           key: ${{ secrets[format('RELATIVE_CI_KEY_{0}_{1}', matrix.bundle, matrix.build)] }} |           key: ${{ secrets[format('RELATIVE_CI_KEY_{0}_{1}', matrix.bundle, matrix.build)] }} | ||||||
|           token: ${{ github.token }} |           token: ${{ github.token }} | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								.github/workflows/release.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								.github/workflows/release.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -34,7 +34,7 @@ jobs: | |||||||
|         uses: home-assistant/actions/helpers/verify-version@master |         uses: home-assistant/actions/helpers/verify-version@master | ||||||
|  |  | ||||||
|       - name: Setup Node |       - name: Setup Node | ||||||
|         uses: actions/setup-node@v4.3.0 |         uses: actions/setup-node@v4.4.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version-file: ".nvmrc" | ||||||
|           cache: yarn |           cache: yarn | ||||||
| @@ -55,7 +55,7 @@ jobs: | |||||||
|           script/release |           script/release | ||||||
|  |  | ||||||
|       - name: Upload release assets |       - name: Upload release assets | ||||||
|         uses: softprops/action-gh-release@v2.2.1 |         uses: softprops/action-gh-release@v2.2.2 | ||||||
|         with: |         with: | ||||||
|           files: | |           files: | | ||||||
|             dist/*.whl |             dist/*.whl | ||||||
| @@ -74,7 +74,7 @@ jobs: | |||||||
|           echo "home-assistant-frontend==$version" > ./requirements.txt |           echo "home-assistant-frontend==$version" > ./requirements.txt | ||||||
|  |  | ||||||
|       - name: Build wheels |       - name: Build wheels | ||||||
|         uses: home-assistant/wheels@2025.02.0 |         uses: home-assistant/wheels@2025.03.0 | ||||||
|         with: |         with: | ||||||
|           abi: cp313 |           abi: cp313 | ||||||
|           tag: musllinux_1_2 |           tag: musllinux_1_2 | ||||||
| @@ -92,7 +92,7 @@ jobs: | |||||||
|       - name: Checkout the repository |       - name: Checkout the repository | ||||||
|         uses: actions/checkout@v4.2.2 |         uses: actions/checkout@v4.2.2 | ||||||
|       - name: Setup Node |       - name: Setup Node | ||||||
|         uses: actions/setup-node@v4.3.0 |         uses: actions/setup-node@v4.4.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version-file: ".nvmrc" | ||||||
|           cache: yarn |           cache: yarn | ||||||
| @@ -107,7 +107,7 @@ jobs: | |||||||
|       - name: Tar folder |       - name: Tar folder | ||||||
|         run: tar -czf landing-page/home_assistant_frontend_landingpage-${{ github.event.release.tag_name }}.tar.gz -C landing-page/dist . |         run: tar -czf landing-page/home_assistant_frontend_landingpage-${{ github.event.release.tag_name }}.tar.gz -C landing-page/dist . | ||||||
|       - name: Upload release asset |       - name: Upload release asset | ||||||
|         uses: softprops/action-gh-release@v2.2.1 |         uses: softprops/action-gh-release@v2.2.2 | ||||||
|         with: |         with: | ||||||
|           files: landing-page/home_assistant_frontend_landingpage-${{ github.event.release.tag_name }}.tar.gz |           files: landing-page/home_assistant_frontend_landingpage-${{ github.event.release.tag_name }}.tar.gz | ||||||
|  |  | ||||||
| @@ -121,7 +121,7 @@ jobs: | |||||||
|       - name: Checkout the repository |       - name: Checkout the repository | ||||||
|         uses: actions/checkout@v4.2.2 |         uses: actions/checkout@v4.2.2 | ||||||
|       - name: Setup Node |       - name: Setup Node | ||||||
|         uses: actions/setup-node@v4.3.0 |         uses: actions/setup-node@v4.4.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version-file: ".nvmrc" | ||||||
|           cache: yarn |           cache: yarn | ||||||
| @@ -136,6 +136,6 @@ jobs: | |||||||
|       - name: Tar folder |       - name: Tar folder | ||||||
|         run: tar -czf hassio/home_assistant_frontend_supervisor-${{ github.event.release.tag_name }}.tar.gz -C hassio/build . |         run: tar -czf hassio/home_assistant_frontend_supervisor-${{ github.event.release.tag_name }}.tar.gz -C hassio/build . | ||||||
|       - name: Upload release asset |       - name: Upload release asset | ||||||
|         uses: softprops/action-gh-release@v2.2.1 |         uses: softprops/action-gh-release@v2.2.2 | ||||||
|         with: |         with: | ||||||
|           files: hassio/home_assistant_frontend_supervisor-${{ github.event.release.tag_name }}.tar.gz |           files: hassio/home_assistant_frontend_supervisor-${{ github.event.release.tag_name }}.tar.gz | ||||||
|   | |||||||
| @@ -1 +1 @@ | |||||||
| yarn run lint-staged --relative --shell "/bin/bash" | yarn run lint-staged --relative | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								.vscode/extensions.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.vscode/extensions.json
									
									
									
									
										vendored
									
									
								
							| @@ -5,6 +5,7 @@ | |||||||
|     "runem.lit-plugin", |     "runem.lit-plugin", | ||||||
|     "github.vscode-pull-request-github", |     "github.vscode-pull-request-github", | ||||||
|     "eamodio.gitlens", |     "eamodio.gitlens", | ||||||
|     "vitest.explorer" |     "vitest.explorer", | ||||||
|  |     "yeion7.styled-global-variables-autocomplete" | ||||||
|   ] |   ] | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,22 @@ | |||||||
|  | diff --git a/mwc-formfield-base.js b/mwc-formfield-base.js | ||||||
|  | index 7b763326d7d51835ad52646bfbc80fe21989abd3..f2baa8224e6d03df1fdb0b9fd03f5c6d77fc8747 100644 | ||||||
|  | --- a/mwc-formfield-base.js | ||||||
|  | +++ b/mwc-formfield-base.js | ||||||
|  | @@ -9,7 +9,7 @@ import { BaseElement } from '@material/mwc-base/base-element.js'; | ||||||
|  |  import { FormElement } from '@material/mwc-base/form-element.js'; | ||||||
|  |  import { observer } from '@material/mwc-base/observer.js'; | ||||||
|  |  import { html } from 'lit'; | ||||||
|  | -import { property, query, queryAssignedNodes } from 'lit/decorators.js'; | ||||||
|  | +import { property, query, queryAssignedElements } from 'lit/decorators.js'; | ||||||
|  |  import { classMap } from 'lit/directives/class-map.js'; | ||||||
|  |  export class FormfieldBase extends BaseElement { | ||||||
|  |      constructor() { | ||||||
|  | @@ -96,7 +96,7 @@ __decorate([ | ||||||
|  |      query('.mdc-form-field') | ||||||
|  |  ], FormfieldBase.prototype, "mdcRoot", void 0); | ||||||
|  |  __decorate([ | ||||||
|  | -    queryAssignedNodes('', true, '*') | ||||||
|  | +    queryAssignedElements({ slot: "", flatten: true, selector: "*" }) | ||||||
|  |  ], FormfieldBase.prototype, "slottedInputs", void 0); | ||||||
|  |  __decorate([ | ||||||
|  |      query('label') | ||||||
							
								
								
									
										26
									
								
								.yarn/patches/@material-mwc-list-npm-0.27.0-5344fc9de4.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								.yarn/patches/@material-mwc-list-npm-0.27.0-5344fc9de4.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | diff --git a/mwc-list-base.js b/mwc-list-base.js | ||||||
|  | index 1ba95b6a01dcecea4d85b5cbbbcc3dfb04c40d5f..dced13fdb7929c490d6661b1bbe7e9f96dcd2285 100644 | ||||||
|  | --- a/mwc-list-base.js | ||||||
|  | +++ b/mwc-list-base.js | ||||||
|  | @@ -11,7 +11,7 @@ import { BaseElement } from '@material/mwc-base/base-element.js'; | ||||||
|  |  import { observer } from '@material/mwc-base/observer.js'; | ||||||
|  |  import { deepActiveElementPath, doesElementContainFocus, isNodeElement } from '@material/mwc-base/utils.js'; | ||||||
|  |  import { html } from 'lit'; | ||||||
|  | -import { property, query, queryAssignedNodes } from 'lit/decorators.js'; | ||||||
|  | +import { property, query, queryAssignedElements } from 'lit/decorators.js'; | ||||||
|  |  import { ifDefined } from 'lit/directives/if-defined.js'; | ||||||
|  |  import MDCListFoundation, { isIndexSet } from './mwc-list-foundation.js'; | ||||||
|  |  export { createSetFromIndex, isEventMulti, isIndexSet } from './mwc-list-foundation.js'; | ||||||
|  | @@ -425,10 +425,10 @@ __decorate([ | ||||||
|  |      query('.mdc-deprecated-list') | ||||||
|  |  ], ListBase.prototype, "mdcRoot", void 0); | ||||||
|  |  __decorate([ | ||||||
|  | -    queryAssignedNodes('', true, '*') | ||||||
|  | +    queryAssignedElements({ flatten: true, selector: "*" }) | ||||||
|  |  ], ListBase.prototype, "assignedElements", void 0); | ||||||
|  |  __decorate([ | ||||||
|  | -    queryAssignedNodes('', true, '[tabindex="0"]') | ||||||
|  | +    queryAssignedElements({ flatten: true, selector: '[tabindex="0"]' }) | ||||||
|  |  ], ListBase.prototype, "tabbableElements", void 0); | ||||||
|  |  __decorate([ | ||||||
|  |      property({ type: Boolean }), | ||||||
| @@ -1,34 +0,0 @@ | |||||||
| diff --git a/lib/legacy/class.js b/lib/legacy/class.js |  | ||||||
| index aee2511be1cd9bf900ee552bc98190c1631c57c0..f2f499d68bf52034cac9c28307c99e8ce6b8417d 100644 |  | ||||||
| --- a/lib/legacy/class.js |  | ||||||
| +++ b/lib/legacy/class.js |  | ||||||
| @@ -304,17 +304,23 @@ function GenerateClassFromInfo(info, Base, behaviors) { |  | ||||||
|        // only proceed if the generated class' prototype has not been registered. |  | ||||||
|        const generatedProto = PolymerGenerated.prototype; |  | ||||||
|        if (!generatedProto.hasOwnProperty(JSCompiler_renameProperty('__hasRegisterFinished', generatedProto))) { |  | ||||||
| -        generatedProto.__hasRegisterFinished = true; |  | ||||||
| +        // make sure legacy lifecycle is called on the *element*'s prototype |  | ||||||
| +        // and not the generated class prototype; if the element has been |  | ||||||
| +        // extended, these are *not* the same. |  | ||||||
| +        const proto = Object.getPrototypeOf(this); |  | ||||||
| +        // Only set flag when generated prototype itself is registered, |  | ||||||
| +        // as this element may be extended from, and needs to run `registered` |  | ||||||
| +        // on all behaviors on the subclass as well. |  | ||||||
| +        if (proto === generatedProto) { |  | ||||||
| +          generatedProto.__hasRegisterFinished = true; |  | ||||||
| +        } |  | ||||||
|          // ensure superclass is registered first. |  | ||||||
|          super._registered(); |  | ||||||
|          // copy properties onto the generated class lazily if we're optimizing, |  | ||||||
| -        if (legacyOptimizations) { |  | ||||||
| +        if (legacyOptimizations && !Object.hasOwnProperty(generatedProto, '__hasCopiedProperties')) { |  | ||||||
| +          generatedProto.__hasCopiedProperties = true; |  | ||||||
|            copyPropertiesToProto(generatedProto); |  | ||||||
|          } |  | ||||||
| -        // make sure legacy lifecycle is called on the *element*'s prototype |  | ||||||
| -        // and not the generated class prototype; if the element has been |  | ||||||
| -        // extended, these are *not* the same. |  | ||||||
| -        const proto = Object.getPrototypeOf(this); |  | ||||||
|          let list = lifecycle.beforeRegister; |  | ||||||
|          if (list) { |  | ||||||
|            for (let i=0; i < list.length; i++) { |  | ||||||
| @@ -1,18 +0,0 @@ | |||||||
| diff --git a/dist/hls.light.mjs b/dist/hls.light.mjs |  | ||||||
| index eed9d788fafdb159975e1a2eb08ac88ba9c9ac33..ace881935e6665946f1c8110ebd2f739cde4427e 100644 |  | ||||||
| --- a/dist/hls.light.mjs |  | ||||||
| +++ b/dist/hls.light.mjs |  | ||||||
| @@ -20523,9 +20523,9 @@ class Hls { |  | ||||||
|  } |  | ||||||
|  Hls.defaultConfig = void 0; |  | ||||||
|   |  | ||||||
| -var KeySystemFormats = empty.KeySystemFormats; |  | ||||||
| -var KeySystems = empty.KeySystems; |  | ||||||
| -var SubtitleStreamController = empty.SubtitleStreamController; |  | ||||||
| -var TimelineController = empty.TimelineController; |  | ||||||
| +var KeySystemFormats = empty; |  | ||||||
| +var KeySystems = empty; |  | ||||||
| +var SubtitleStreamController = empty; |  | ||||||
| +var TimelineController = empty; |  | ||||||
|  export { AbrController, AttrList, Cues as AudioStreamController, Cues as AudioTrackController, BasePlaylistController, BaseSegment, BaseStreamController, BufferController, Cues as CMCDController, CapLevelController, ChunkMetadata, ContentSteeringController, DateRange, Cues as EMEController, ErrorActionFlags, ErrorController, ErrorDetails, ErrorTypes, Events, FPSController, Fragment, Hls, HlsSkip, HlsUrlParameters, KeySystemFormats, KeySystems, Level, LevelDetails, LevelKey, LoadStats, MetadataSchema, NetworkErrorAction, Part, PlaylistLevelType, SubtitleStreamController, Cues as SubtitleTrackController, TimelineController, Hls as default, getMediaSource, isMSESupported, isSupported }; |  | ||||||
|  //# sourceMappingURL=hls.light.mjs.map |  | ||||||
							
								
								
									
										935
									
								
								.yarn/releases/yarn-4.7.0.cjs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										935
									
								
								.yarn/releases/yarn-4.7.0.cjs
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										942
									
								
								.yarn/releases/yarn-4.9.2.cjs
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										942
									
								
								.yarn/releases/yarn-4.9.2.cjs
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -6,4 +6,4 @@ enableGlobalCache: false | |||||||
|  |  | ||||||
| nodeLinker: node-modules | nodeLinker: node-modules | ||||||
|  |  | ||||||
| yarnPath: .yarn/releases/yarn-4.7.0.cjs | yarnPath: .yarn/releases/yarn-4.9.2.cjs | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ import defineProvider from "@babel/helper-define-polyfill-provider"; | |||||||
| import { join } from "node:path"; | import { join } from "node:path"; | ||||||
| import paths from "../paths.cjs"; | import paths from "../paths.cjs"; | ||||||
|  |  | ||||||
| const POLYFILL_DIR = join(paths.polymer_dir, "src/resources/polyfills"); | const POLYFILL_DIR = join(paths.root_dir, "src/resources/polyfills"); | ||||||
|  |  | ||||||
| // List of polyfill keys with supported browser targets for the functionality | // List of polyfill keys with supported browser targets for the functionality | ||||||
| const polyfillSupport = { | const polyfillSupport = { | ||||||
|   | |||||||
| @@ -20,22 +20,16 @@ module.exports.ignorePackages = () => []; | |||||||
| // Files from NPM packages that we should replace with empty file | // Files from NPM packages that we should replace with empty file | ||||||
| module.exports.emptyPackages = ({ isHassioBuild }) => | module.exports.emptyPackages = ({ isHassioBuild }) => | ||||||
|   [ |   [ | ||||||
|     // Contains all color definitions for all material color sets. |  | ||||||
|     // We don't use it |  | ||||||
|     require.resolve("@polymer/paper-styles/color.js"), |  | ||||||
|     require.resolve("@polymer/paper-styles/default-theme.js"), |  | ||||||
|     // Loads stuff from a CDN |  | ||||||
|     require.resolve("@polymer/font-roboto/roboto.js"), |  | ||||||
|     require.resolve("@vaadin/vaadin-material-styles/typography.js"), |     require.resolve("@vaadin/vaadin-material-styles/typography.js"), | ||||||
|     require.resolve("@vaadin/vaadin-material-styles/font-icons.js"), |     require.resolve("@vaadin/vaadin-material-styles/font-icons.js"), | ||||||
|     // Icons in supervisor conflict with icons in HA so we don't load. |     // Icons in supervisor conflict with icons in HA so we don't load. | ||||||
|     isHassioBuild && |     isHassioBuild && | ||||||
|       require.resolve( |       require.resolve( | ||||||
|         path.resolve(paths.polymer_dir, "src/components/ha-icon.ts") |         path.resolve(paths.root_dir, "src/components/ha-icon.ts") | ||||||
|       ), |       ), | ||||||
|     isHassioBuild && |     isHassioBuild && | ||||||
|       require.resolve( |       require.resolve( | ||||||
|         path.resolve(paths.polymer_dir, "src/components/ha-icon-picker.ts") |         path.resolve(paths.root_dir, "src/components/ha-icon-picker.ts") | ||||||
|       ), |       ), | ||||||
|   ].filter(Boolean); |   ].filter(Boolean); | ||||||
|  |  | ||||||
| @@ -50,7 +44,8 @@ module.exports.definedVars = ({ isProdBuild, latestBuild, defineOverlay }) => ({ | |||||||
|   __HASS_URL__: `\`${ |   __HASS_URL__: `\`${ | ||||||
|     "HASS_URL" in process.env |     "HASS_URL" in process.env | ||||||
|       ? process.env.HASS_URL |       ? process.env.HASS_URL | ||||||
|       : "${location.protocol}//${location.host}" |       : // eslint-disable-next-line no-template-curly-in-string | ||||||
|  |         "${location.protocol}//${location.host}" | ||||||
|   }\``, |   }\``, | ||||||
|   "process.env.NODE_ENV": JSON.stringify( |   "process.env.NODE_ENV": JSON.stringify( | ||||||
|     isProdBuild ? "production" : "development" |     isProdBuild ? "production" : "development" | ||||||
| @@ -78,6 +73,19 @@ module.exports.terserOptions = ({ latestBuild, isTestBuild }) => ({ | |||||||
|   sourceMap: !isTestBuild, |   sourceMap: !isTestBuild, | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | /** @type {import('@rspack/core').SwcLoaderOptions} */ | ||||||
|  | module.exports.swcOptions = () => ({ | ||||||
|  |   jsc: { | ||||||
|  |     loose: true, | ||||||
|  |     externalHelpers: true, | ||||||
|  |     target: "ES2021", | ||||||
|  |     parser: { | ||||||
|  |       syntax: "typescript", | ||||||
|  |       decorators: true, | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  | }); | ||||||
|  |  | ||||||
| module.exports.babelOptions = ({ | module.exports.babelOptions = ({ | ||||||
|   latestBuild, |   latestBuild, | ||||||
|   isProdBuild, |   isProdBuild, | ||||||
| @@ -102,7 +110,6 @@ module.exports.babelOptions = ({ | |||||||
|         shippedProposals: true, |         shippedProposals: true, | ||||||
|       }, |       }, | ||||||
|     ], |     ], | ||||||
|     "@babel/preset-typescript", |  | ||||||
|   ], |   ], | ||||||
|   plugins: [ |   plugins: [ | ||||||
|     [ |     [ | ||||||
| @@ -139,12 +146,6 @@ module.exports.babelOptions = ({ | |||||||
|       "@babel/plugin-transform-runtime", |       "@babel/plugin-transform-runtime", | ||||||
|       { version: dependencies["@babel/runtime"] }, |       { version: dependencies["@babel/runtime"] }, | ||||||
|     ], |     ], | ||||||
|     // Transpile decorators (still in TC39 process) |  | ||||||
|     // Modern browsers support class fields and private methods, but transform is required with the older decorator version dictated by Lit |  | ||||||
|     [ |  | ||||||
|       "@babel/plugin-proposal-decorators", |  | ||||||
|       { version: "2018-09", decoratorsBeforeExport: true }, |  | ||||||
|     ], |  | ||||||
|     "@babel/plugin-transform-class-properties", |     "@babel/plugin-transform-class-properties", | ||||||
|     "@babel/plugin-transform-private-methods", |     "@babel/plugin-transform-private-methods", | ||||||
|   ].filter(Boolean), |   ].filter(Boolean), | ||||||
| @@ -164,7 +165,7 @@ module.exports.babelOptions = ({ | |||||||
|         ], |         ], | ||||||
|       ], |       ], | ||||||
|       exclude: [ |       exclude: [ | ||||||
|         path.join(paths.polymer_dir, "src/resources/polyfills"), |         path.join(paths.root_dir, "src/resources/polyfills"), | ||||||
|         ...[ |         ...[ | ||||||
|           "@formatjs/(?:ecma402-abstract|intl-\\w+)", |           "@formatjs/(?:ecma402-abstract|intl-\\w+)", | ||||||
|           "@lit-labs/virtualizer/polyfills", |           "@lit-labs/virtualizer/polyfills", | ||||||
| @@ -182,6 +183,7 @@ module.exports.babelOptions = ({ | |||||||
|       include: /\/node_modules\//, |       include: /\/node_modules\//, | ||||||
|       exclude: [ |       exclude: [ | ||||||
|         "element-internals-polyfill", |         "element-internals-polyfill", | ||||||
|  |         "@shoelace-style", | ||||||
|         "@?lit(?:-labs|-element|-html)?", |         "@?lit(?:-labs|-element|-html)?", | ||||||
|       ].map((p) => new RegExp(`/node_modules/${p}/`)), |       ].map((p) => new RegExp(`/node_modules/${p}/`)), | ||||||
|     }, |     }, | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ module.exports = { | |||||||
|   }, |   }, | ||||||
|   version() { |   version() { | ||||||
|     const version = fs |     const version = fs | ||||||
|       .readFileSync(path.resolve(paths.polymer_dir, "pyproject.toml"), "utf8") |       .readFileSync(path.resolve(paths.root_dir, "pyproject.toml"), "utf8") | ||||||
|       .match(/version\W+=\W"(\d{8}\.\d(?:\.dev)?)"/); |       .match(/version\W+=\W"(\d{8}\.\d(?:\.dev)?)"/); | ||||||
|     if (!version) { |     if (!version) { | ||||||
|       throw Error("Version not found"); |       throw Error("Version not found"); | ||||||
|   | |||||||
| @@ -169,14 +169,14 @@ const APP_PAGE_ENTRIES = { | |||||||
|  |  | ||||||
| gulp.task( | gulp.task( | ||||||
|   "gen-pages-app-dev", |   "gen-pages-app-dev", | ||||||
|   genPagesDevTask(APP_PAGE_ENTRIES, paths.polymer_dir, paths.app_output_root) |   genPagesDevTask(APP_PAGE_ENTRIES, paths.root_dir, paths.app_output_root) | ||||||
| ); | ); | ||||||
|  |  | ||||||
| gulp.task( | gulp.task( | ||||||
|   "gen-pages-app-prod", |   "gen-pages-app-prod", | ||||||
|   genPagesProdTask( |   genPagesProdTask( | ||||||
|     APP_PAGE_ENTRIES, |     APP_PAGE_ENTRIES, | ||||||
|     paths.polymer_dir, |     paths.root_dir, | ||||||
|     paths.app_output_root, |     paths.app_output_root, | ||||||
|     paths.app_output_latest, |     paths.app_output_latest, | ||||||
|     paths.app_output_es5 |     paths.app_output_es5 | ||||||
|   | |||||||
| @@ -6,8 +6,8 @@ import path from "path"; | |||||||
| import paths from "../paths.cjs"; | import paths from "../paths.cjs"; | ||||||
|  |  | ||||||
| const npmPath = (...parts) => | const npmPath = (...parts) => | ||||||
|   path.resolve(paths.polymer_dir, "node_modules", ...parts); |   path.resolve(paths.root_dir, "node_modules", ...parts); | ||||||
| const polyPath = (...parts) => path.resolve(paths.polymer_dir, ...parts); | const polyPath = (...parts) => path.resolve(paths.root_dir, ...parts); | ||||||
|  |  | ||||||
| const copyFileDir = (fromFile, toDir) => | const copyFileDir = (fromFile, toDir) => | ||||||
|   fs.copySync(fromFile, path.join(toDir, path.basename(fromFile))); |   fs.copySync(fromFile, path.join(toDir, path.basename(fromFile))); | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ import gulp from "gulp"; | |||||||
| import { join, resolve } from "node:path"; | import { join, resolve } from "node:path"; | ||||||
| import paths from "../paths.cjs"; | import paths from "../paths.cjs"; | ||||||
|  |  | ||||||
| const formatjsDir = join(paths.polymer_dir, "node_modules", "@formatjs"); | const formatjsDir = join(paths.root_dir, "node_modules", "@formatjs"); | ||||||
| const outDir = join(paths.build_dir, "locale-data"); | const outDir = join(paths.build_dir, "locale-data"); | ||||||
|  |  | ||||||
| const INTL_POLYFILLS = { | const INTL_POLYFILLS = { | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ const detailsClose = "</details>\n"; | |||||||
|  |  | ||||||
| const dummyAPI = { | const dummyAPI = { | ||||||
|   version: babelVersion, |   version: babelVersion, | ||||||
|  |   // eslint-disable-next-line @typescript-eslint/no-empty-function | ||||||
|   assertVersion: () => {}, |   assertVersion: () => {}, | ||||||
|   caller: (callback) => |   caller: (callback) => | ||||||
|     callback({ |     callback({ | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| const path = require("path"); | const path = require("path"); | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|   polymer_dir: path.resolve(__dirname, ".."), |   root_dir: path.resolve(__dirname, ".."), | ||||||
|  |  | ||||||
|   build_dir: path.resolve(__dirname, "../build"), |   build_dir: path.resolve(__dirname, "../build"), | ||||||
|   app_output_root: path.resolve(__dirname, "../hass_frontend"), |   app_output_root: path.resolve(__dirname, "../hass_frontend"), | ||||||
|   | |||||||
| @@ -65,7 +65,9 @@ const createRspackConfig = ({ | |||||||
|       rules: [ |       rules: [ | ||||||
|         { |         { | ||||||
|           test: /\.m?js$|\.ts$/, |           test: /\.m?js$|\.ts$/, | ||||||
|           use: (info) => ({ |           exclude: /node_modules[\\/]core-js/, | ||||||
|  |           use: (info) => [ | ||||||
|  |             { | ||||||
|               loader: "babel-loader", |               loader: "babel-loader", | ||||||
|               options: { |               options: { | ||||||
|                 ...bundle.babelOptions({ |                 ...bundle.babelOptions({ | ||||||
| @@ -77,7 +79,12 @@ const createRspackConfig = ({ | |||||||
|                 cacheDirectory: !isProdBuild, |                 cacheDirectory: !isProdBuild, | ||||||
|                 cacheCompression: false, |                 cacheCompression: false, | ||||||
|               }, |               }, | ||||||
|           }), |             }, | ||||||
|  |             { | ||||||
|  |               loader: "builtin:swc-loader", | ||||||
|  |               options: bundle.swcOptions(), | ||||||
|  |             }, | ||||||
|  |           ], | ||||||
|           resolve: { |           resolve: { | ||||||
|             fullySpecified: false, |             fullySpecified: false, | ||||||
|           }, |           }, | ||||||
| @@ -136,7 +143,8 @@ const createRspackConfig = ({ | |||||||
|             // calling define.amd will call require("!!webpack amd options") |             // calling define.amd will call require("!!webpack amd options") | ||||||
|             resource.startsWith("!!webpack") || |             resource.startsWith("!!webpack") || | ||||||
|             // loaded by webpack dev server but doesn't exist. |             // loaded by webpack dev server but doesn't exist. | ||||||
|             resource === "webpack/hot" |             resource === "webpack/hot" || | ||||||
|  |             resource.startsWith("@swc/helpers") | ||||||
|           ) { |           ) { | ||||||
|             return false; |             return false; | ||||||
|           } |           } | ||||||
| @@ -161,7 +169,7 @@ const createRspackConfig = ({ | |||||||
|       }), |       }), | ||||||
|       new rspack.NormalModuleReplacementPlugin( |       new rspack.NormalModuleReplacementPlugin( | ||||||
|         new RegExp(bundle.emptyPackages({ isHassioBuild }).join("|")), |         new RegExp(bundle.emptyPackages({ isHassioBuild }).join("|")), | ||||||
|         path.resolve(paths.polymer_dir, "src/util/empty.js") |         path.resolve(paths.root_dir, "src/util/empty.js") | ||||||
|       ), |       ), | ||||||
|       !isProdBuild && new LogStartCompilePlugin(), |       !isProdBuild && new LogStartCompilePlugin(), | ||||||
|       isProdBuild && |       isProdBuild && | ||||||
|   | |||||||
| @@ -1,3 +1,3 @@ | |||||||
| import "./layout/hc-connect"; | import "./layout/hc-connect"; | ||||||
|  |  | ||||||
| import("../../../src/resources/ha-style"); | import("../../../src/resources/append-ha-style"); | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import "@material/mwc-button/mwc-button"; | import "@material/mwc-button/mwc-button"; | ||||||
| import "@material/mwc-list/mwc-list"; |  | ||||||
| import type { ActionDetail } from "@material/mwc-list/mwc-list"; | import type { ActionDetail } from "@material/mwc-list/mwc-list"; | ||||||
| import { mdiCast, mdiCastConnected, mdiViewDashboard } from "@mdi/js"; | import { mdiCast, mdiCastConnected, mdiViewDashboard } from "@mdi/js"; | ||||||
| import type { Auth, Connection } from "home-assistant-js-websocket"; | import type { Auth, Connection } from "home-assistant-js-websocket"; | ||||||
| @@ -19,6 +19,8 @@ import { | |||||||
| import { atLeastVersion } from "../../../../src/common/config/version"; | import { atLeastVersion } from "../../../../src/common/config/version"; | ||||||
| import { toggleAttribute } from "../../../../src/common/dom/toggle_attribute"; | import { toggleAttribute } from "../../../../src/common/dom/toggle_attribute"; | ||||||
| import "../../../../src/components/ha-icon"; | import "../../../../src/components/ha-icon"; | ||||||
|  | import "../../../../src/components/ha-list"; | ||||||
|  | import "../../../../src/components/ha-list-item"; | ||||||
| import "../../../../src/components/ha-svg-icon"; | import "../../../../src/components/ha-svg-icon"; | ||||||
| import { | import { | ||||||
|   getLegacyLovelaceCollection, |   getLegacyLovelaceCollection, | ||||||
| @@ -29,7 +31,6 @@ import type { LovelaceViewConfig } from "../../../../src/data/lovelace/config/vi | |||||||
| import "../../../../src/layouts/hass-loading-screen"; | import "../../../../src/layouts/hass-loading-screen"; | ||||||
| import { generateDefaultViewConfig } from "../../../../src/panels/lovelace/common/generate-lovelace-config"; | import { generateDefaultViewConfig } from "../../../../src/panels/lovelace/common/generate-lovelace-config"; | ||||||
| import "./hc-layout"; | import "./hc-layout"; | ||||||
| import "../../../../src/components/ha-list-item"; |  | ||||||
|  |  | ||||||
| @customElement("hc-cast") | @customElement("hc-cast") | ||||||
| class HcCast extends LitElement { | class HcCast extends LitElement { | ||||||
| @@ -85,7 +86,7 @@ class HcCast extends LitElement { | |||||||
|               ` |               ` | ||||||
|             : html` |             : html` | ||||||
|                 <div class="section-header">PICK A VIEW</div> |                 <div class="section-header">PICK A VIEW</div> | ||||||
|                 <mwc-list @action=${this._handlePickView} activatable> |                 <ha-list @action=${this._handlePickView} activatable> | ||||||
|                   ${( |                   ${( | ||||||
|                     this.lovelaceViews ?? [ |                     this.lovelaceViews ?? [ | ||||||
|                       generateDefaultViewConfig({}, {}, {}, {}, () => ""), |                       generateDefaultViewConfig({}, {}, {}, {}, () => ""), | ||||||
| @@ -113,7 +114,7 @@ class HcCast extends LitElement { | |||||||
|                             ></ha-svg-icon>`} |                             ></ha-svg-icon>`} | ||||||
|                       </ha-list-item> |                       </ha-list-item> | ||||||
|                     ` |                     ` | ||||||
|                   )}</mwc-list |                   )}</ha-list | ||||||
|                 > |                 > | ||||||
|               `} |               `} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -302,7 +302,7 @@ export class HcConnect extends LitElement { | |||||||
|     } |     } | ||||||
|     .error { |     .error { | ||||||
|       color: red; |       color: red; | ||||||
|       font-weight: bold; |       font-weight: var(--ha-font-weight-bold); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     .error a { |     .error a { | ||||||
|   | |||||||
| @@ -86,9 +86,9 @@ class HcLayout extends LitElement { | |||||||
|     .card-header { |     .card-header { | ||||||
|       color: var(--ha-card-header-color, var(--primary-text-color)); |       color: var(--ha-card-header-color, var(--primary-text-color)); | ||||||
|       font-family: var(--ha-card-header-font-family, inherit); |       font-family: var(--ha-card-header-font-family, inherit); | ||||||
|       font-size: var(--ha-card-header-font-size, 24px); |       font-size: var(--ha-card-header-font-size, var(--ha-font-size-2xl)); | ||||||
|       letter-spacing: -0.012em; |       letter-spacing: -0.012em; | ||||||
|       line-height: 32px; |       line-height: var(--ha-line-height-condensed); | ||||||
|       padding: 24px 16px 16px; |       padding: 24px 16px 16px; | ||||||
|       display: block; |       display: block; | ||||||
|       margin: 0; |       margin: 0; | ||||||
| @@ -98,7 +98,7 @@ class HcLayout extends LitElement { | |||||||
|       border-radius: 4px 4px 0 0; |       border-radius: 4px 4px 0 0; | ||||||
|     } |     } | ||||||
|     .subtitle { |     .subtitle { | ||||||
|       font-size: 14px; |       font-size: var(--ha-font-size-m); | ||||||
|       color: var(--secondary-text-color); |       color: var(--secondary-text-color); | ||||||
|       line-height: initial; |       line-height: initial; | ||||||
|     } |     } | ||||||
| @@ -113,7 +113,7 @@ class HcLayout extends LitElement { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     :host ::slotted(.section-header) { |     :host ::slotted(.section-header) { | ||||||
|       font-weight: 500; |       font-weight: var(--ha-font-weight-medium); | ||||||
|       padding: 4px 16px; |       padding: 4px 16px; | ||||||
|       text-transform: uppercase; |       text-transform: uppercase; | ||||||
|     } |     } | ||||||
| @@ -135,7 +135,7 @@ class HcLayout extends LitElement { | |||||||
|  |  | ||||||
|     .footer { |     .footer { | ||||||
|       text-align: center; |       text-align: center; | ||||||
|       font-size: 12px; |       font-size: var(--ha-font-size-s); | ||||||
|       padding: 8px 0 24px; |       padding: 8px 0 24px; | ||||||
|       color: var(--secondary-text-color); |       color: var(--secondary-text-color); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ class HcLaunchScreen extends LitElement { | |||||||
|       display: block; |       display: block; | ||||||
|       height: 100vh; |       height: 100vh; | ||||||
|       background-color: #f2f4f9; |       background-color: #f2f4f9; | ||||||
|       font-size: 24px; |       font-size: var(--ha-font-size-2xl); | ||||||
|     } |     } | ||||||
|     .container { |     .container { | ||||||
|       display: flex; |       display: flex; | ||||||
|   | |||||||
| @@ -109,7 +109,7 @@ export class HcMain extends HassElement { | |||||||
|   protected firstUpdated(changedProps) { |   protected firstUpdated(changedProps) { | ||||||
|     super.firstUpdated(changedProps); |     super.firstUpdated(changedProps); | ||||||
|     import("./hc-lovelace"); |     import("./hc-lovelace"); | ||||||
|     import("../../../../src/resources/ha-style"); |     import("../../../../src/resources/append-ha-style"); | ||||||
|  |  | ||||||
|     window.addEventListener("location-changed", () => { |     window.addEventListener("location-changed", () => { | ||||||
|       const panelPath = `/${this._urlPath || "lovelace"}/`; |       const panelPath = `/${this._urlPath || "lovelace"}/`; | ||||||
|   | |||||||
| @@ -1,37 +1,28 @@ | |||||||
| export const demoThemeJimpower = () => ({ | export const demoThemeJimpower = () => ({ | ||||||
|   "text-primary-color": "var(--primary-text-color)", |   "text-primary-color": "var(--primary-text-color)", | ||||||
|   "paper-item-icon-color": "var(--primary-text-color)", |  | ||||||
|   "primary-color": "#5294E2", |   "primary-color": "#5294E2", | ||||||
|   "label-badge-red": "var(--accent-color)", |   "label-badge-red": "var(--accent-color)", | ||||||
|   "paper-tabs-selection-bar-color": "green", |  | ||||||
|   "light-primary-color": "var(--accent-color)", |   "light-primary-color": "var(--accent-color)", | ||||||
|   "primary-background-color": "#383C45", |   "primary-background-color": "#383C45", | ||||||
|   "primary-text-color": "#FFFFFF", |   "primary-text-color": "#FFFFFF", | ||||||
|   "paper-item-selected_-_background-color": "#434954", |  | ||||||
|   "secondary-background-color": "#383C45", |   "secondary-background-color": "#383C45", | ||||||
|   "disabled-text-color": "#7F848E", |   "disabled-text-color": "#7F848E", | ||||||
|   "paper-item-icon_-_color": "green", |  | ||||||
|   "paper-grey-200": "#414A59", |   "paper-grey-200": "#414A59", | ||||||
|   "label-badge-background-color": "#2E333A", |   "label-badge-background-color": "#2E333A", | ||||||
|   "paper-card-header-color": "var(--accent-color)", |   "sidebar-icon-color": "var(--state-icon-color)", | ||||||
|   "sidebar-icon-color": "var(--paper-item-icon-color)", |  | ||||||
|   "paper-listbox-background-color": "#2E333A", |  | ||||||
|   "table-row-background-color": "#353840", |   "table-row-background-color": "#353840", | ||||||
|   "paper-grey-50": "var(--primary-text-color)", |   "paper-grey-50": "var(--primary-text-color)", | ||||||
|   "switch-checked-color": "var(--accent-color)", |   "switch-checked-color": "var(--accent-color)", | ||||||
|   "paper-dialog-background-color": "#434954", |  | ||||||
|   "secondary-text-color": "#5294E2", |   "secondary-text-color": "#5294E2", | ||||||
|   "error-color": "#E45E65", |   "error-color": "#E45E65", | ||||||
|   "divider-color": "rgba(0, 0, 0, .12)", |   "divider-color": "rgba(0, 0, 0, .12)", | ||||||
|   "success-color": "#39E949", |   "success-color": "#39E949", | ||||||
|   "switch-unchecked-button-color": "var(--disabled-text-color)", |   "switch-unchecked-button-color": "var(--disabled-text-color)", | ||||||
|   "label-badge-border-color": "green", |   "label-badge-border-color": "green", | ||||||
|   "paper-listbox-color": "var(--primary-color)", |  | ||||||
|   "card-background-color": "#434954", |   "card-background-color": "#434954", | ||||||
|   "label-badge-text-color": "var(--primary-text-color)", |   "label-badge-text-color": "var(--primary-text-color)", | ||||||
|   "switch-unchecked-track-color": "var(--disabled-text-color)", |   "switch-unchecked-track-color": "var(--disabled-text-color)", | ||||||
|   "dark-primary-color": "var(--accent-color)", |   "dark-primary-color": "var(--accent-color)", | ||||||
|   "paper-item-icon-active-color": "#F9C536", |  | ||||||
|   "accent-color": "#E45E65", |   "accent-color": "#E45E65", | ||||||
|   "table-row-alternative-background-color": "#3E424B", |   "table-row-alternative-background-color": "#3E424B", | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -1,38 +1,29 @@ | |||||||
| // https://community.home-assistant.io/t/slate-a-new-dark-theme/86410 | // https://community.home-assistant.io/t/slate-a-new-dark-theme/86410 | ||||||
| export const demoThemeKernehed = () => ({ | export const demoThemeKernehed = () => ({ | ||||||
|   "text-primary-color": "var(--primary-text-color)", |   "text-primary-color": "var(--primary-text-color)", | ||||||
|   "paper-item-icon-color": "var(--primary-text-color)", |  | ||||||
|   "primary-color": "#2980b9", |   "primary-color": "#2980b9", | ||||||
|   "label-badge-red": "var(--accent-color)", |   "label-badge-red": "var(--accent-color)", | ||||||
|   "paper-tabs-selection-bar-color": "green", |  | ||||||
|   "primary-text-color": "#FFFFFF", |   "primary-text-color": "#FFFFFF", | ||||||
|   "light-primary-color": "var(--accent-color)", |   "light-primary-color": "var(--accent-color)", | ||||||
|   "primary-background-color": "#222222", |   "primary-background-color": "#222222", | ||||||
|   "sidebar-icon-color": "#777777", |   "sidebar-icon-color": "#777777", | ||||||
|   "paper-item-selected_-_background-color": "#292929", |  | ||||||
|   "secondary-background-color": "#222222", |   "secondary-background-color": "#222222", | ||||||
|   "disabled-text-color": "#777777", |   "disabled-text-color": "#777777", | ||||||
|   "paper-item-icon_-_color": "green", |  | ||||||
|   "paper-grey-200": "#222222", |   "paper-grey-200": "#222222", | ||||||
|   "label-badge-background-color": "#222222", |   "label-badge-background-color": "#222222", | ||||||
|   "paper-card-header-color": "var(--accent-color)", |  | ||||||
|   "paper-listbox-background-color": "#141414", |  | ||||||
|   "table-row-background-color": "#292929", |   "table-row-background-color": "#292929", | ||||||
|   "paper-grey-50": "var(--primary-text-color)", |   "paper-grey-50": "var(--primary-text-color)", | ||||||
|   "switch-checked-color": "var(--accent-color)", |   "switch-checked-color": "var(--accent-color)", | ||||||
|   "paper-dialog-background-color": "#292929", |  | ||||||
|   "secondary-text-color": "#b58e31", |   "secondary-text-color": "#b58e31", | ||||||
|   "error-color": "#b58e31", |   "error-color": "#b58e31", | ||||||
|   "divider-color": "rgba(0, 0, 0, .12)", |   "divider-color": "rgba(0, 0, 0, .12)", | ||||||
|   "success-color": "#2980b9", |   "success-color": "#2980b9", | ||||||
|   "switch-unchecked-button-color": "var(--disabled-text-color)", |   "switch-unchecked-button-color": "var(--disabled-text-color)", | ||||||
|   "label-badge-border-color": "green", |   "label-badge-border-color": "green", | ||||||
|   "paper-listbox-color": "#777777", |  | ||||||
|   "card-background-color": "#292929", |   "card-background-color": "#292929", | ||||||
|   "label-badge-text-color": "var(--primary-text-color)", |   "label-badge-text-color": "var(--primary-text-color)", | ||||||
|   "switch-unchecked-track-color": "var(--disabled-text-color)", |   "switch-unchecked-track-color": "var(--disabled-text-color)", | ||||||
|   "dark-primary-color": "var(--accent-color)", |   "dark-primary-color": "var(--accent-color)", | ||||||
|   "paper-item-icon-active-color": "#b58e31", |  | ||||||
|   "accent-color": "#2980b9", |   "accent-color": "#2980b9", | ||||||
|   "table-row-alternative-background-color": "#292929", |   "table-row-alternative-background-color": "#292929", | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -1,26 +1,18 @@ | |||||||
| export const demoThemeTeachingbirds = () => ({ | export const demoThemeTeachingbirds = () => ({ | ||||||
|   "paper-card-header-color": "var(--paper-item-icon-color)", |  | ||||||
|   "paper-listbox-background-color": "#202020", |  | ||||||
|   "paper-grey-50": "var(--primary-text-color)", |   "paper-grey-50": "var(--primary-text-color)", | ||||||
|   "paper-item-icon-color": "#d3d3d3", |  | ||||||
|   "divider-color": "rgba(255, 255, 255, 0.12)", |   "divider-color": "rgba(255, 255, 255, 0.12)", | ||||||
|   "primary-color": "#389638", |   "primary-color": "#389638", | ||||||
|   "light-primary-color": "#6f956f", |   "light-primary-color": "#6f956f", | ||||||
|   "label-badge-red": "var(--primary-color)", |   "label-badge-red": "var(--primary-color)", | ||||||
|   "paper-listbox-color": "#FFFFFF", |  | ||||||
|   "paper-toggle-button-checked-bar-color": "var(--light-primary-color)", |  | ||||||
|   "switch-unchecked-track-color": "var(--primary-text-color)", |   "switch-unchecked-track-color": "var(--primary-text-color)", | ||||||
|   "card-background-color": "#4e4e4e", |   "card-background-color": "#4e4e4e", | ||||||
|   "label-badge-text-color": "var(--text-primary-color)", |   "label-badge-text-color": "var(--text-primary-color)", | ||||||
|   "primary-background-color": "#303030", |   "primary-background-color": "#303030", | ||||||
|   "sidebar-icon-color": "var(--paper-item-icon-color)", |   "sidebar-icon-color": "#d3d3d3", | ||||||
|   "secondary-background-color": "#2b2b2b", |   "secondary-background-color": "#2b2b2b", | ||||||
|   "paper-item-icon-active-color": "#d8bf50", |  | ||||||
|   "switch-checked-color": "var(--primary-color)", |   "switch-checked-color": "var(--primary-color)", | ||||||
|   "secondary-text-color": "#389638", |   "secondary-text-color": "#389638", | ||||||
|   "disabled-text-color": "#545454", |   "disabled-text-color": "#545454", | ||||||
|   "paper-item-icon_-_color": "var(--primary-text-color)", |  | ||||||
|   "paper-grey-200": "#191919", |   "paper-grey-200": "#191919", | ||||||
|   "primary-text-color": "#cfcfcf", |  | ||||||
|   "label-badge-background-color": "var(--secondary-background-color)", |   "label-badge-background-color": "var(--secondary-background-color)", | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -73,7 +73,7 @@ class CastDemoRow extends LitElement implements LovelaceRow { | |||||||
|     } |     } | ||||||
|     ha-svg-icon { |     ha-svg-icon { | ||||||
|       padding: 8px; |       padding: 8px; | ||||||
|       color: var(--paper-item-icon-color); |       color: var(--state-icon-color); | ||||||
|     } |     } | ||||||
|     .flex { |     .flex { | ||||||
|       flex: 1; |       flex: 1; | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import "./util/is_frontpage"; | import "./util/is_frontpage"; | ||||||
| import "./ha-demo"; | import "./ha-demo"; | ||||||
|  |  | ||||||
| import("../../src/resources/ha-style"); | import("../../src/resources/append-ha-style"); | ||||||
|   | |||||||
| @@ -68,7 +68,7 @@ | |||||||
|       } |       } | ||||||
|       #ha-launch-screen .ha-launch-screen-spacer-top { |       #ha-launch-screen .ha-launch-screen-spacer-top { | ||||||
|         flex: 1; |         flex: 1; | ||||||
|         margin-top: calc( 2 * max(env(safe-area-inset-bottom), 48px) + 46px ); |         margin-top: calc( 2 * max(var(--safe-area-inset-bottom), 48px) + 46px ); | ||||||
|         padding-top: 48px; |         padding-top: 48px; | ||||||
|       } |       } | ||||||
|       #ha-launch-screen .ha-launch-screen-spacer-bottom { |       #ha-launch-screen .ha-launch-screen-spacer-bottom { | ||||||
| @@ -76,7 +76,7 @@ | |||||||
|         padding-top: 48px; |         padding-top: 48px; | ||||||
|       } |       } | ||||||
|       .ohf-logo { |       .ohf-logo { | ||||||
|         margin: max(env(safe-area-inset-bottom), 48px) 0; |         margin: max(var(--safe-area-inset-bottom), 48px) 0; | ||||||
|         display: flex; |         display: flex; | ||||||
|         flex-direction: column; |         flex-direction: column; | ||||||
|         align-items: center; |         align-items: center; | ||||||
|   | |||||||
| @@ -1,7 +1,30 @@ | |||||||
| import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; | import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; | ||||||
|  |  | ||||||
|  | let changeFunction; | ||||||
|  |  | ||||||
| export const mockFrontend = (hass: MockHomeAssistant) => { | export const mockFrontend = (hass: MockHomeAssistant) => { | ||||||
|   hass.mockWS("frontend/get_user_data", () => ({ |   hass.mockWS("frontend/get_user_data", () => ({ | ||||||
|     value: null, |     value: null, | ||||||
|   })); |   })); | ||||||
|  |   hass.mockWS("frontend/set_user_data", ({ key, value }) => { | ||||||
|  |     if (key === "sidebar") { | ||||||
|  |       changeFunction?.({ | ||||||
|  |         value: { | ||||||
|  |           panelOrder: value.panelOrder || [], | ||||||
|  |           hiddenPanels: value.hiddenPanels || [], | ||||||
|  |         }, | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |   }); | ||||||
|  |   hass.mockWS("frontend/subscribe_user_data", (_msg, _hass, onChange) => { | ||||||
|  |     changeFunction = onChange; | ||||||
|  |     onChange?.({ | ||||||
|  |       value: { | ||||||
|  |         panelOrder: [], | ||||||
|  |         hiddenPanels: [], | ||||||
|  |       }, | ||||||
|  |     }); | ||||||
|  |     // eslint-disable-next-line @typescript-eslint/no-empty-function | ||||||
|  |     return () => {}; | ||||||
|  |   }); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -2,8 +2,7 @@ import type { TodoItem } from "../../../src/data/todo"; | |||||||
| import { TodoItemStatus } from "../../../src/data/todo"; | import { TodoItemStatus } from "../../../src/data/todo"; | ||||||
| import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; | import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; | ||||||
|  |  | ||||||
| export const mockTodo = (hass: MockHomeAssistant) => { | const items = { | ||||||
|   hass.mockWS("todo/item/list", () => ({ |  | ||||||
|   items: [ |   items: [ | ||||||
|     { |     { | ||||||
|       uid: "12", |       uid: "12", | ||||||
| @@ -20,8 +19,19 @@ export const mockTodo = (hass: MockHomeAssistant) => { | |||||||
|       summary: "Oranges", |       summary: "Oranges", | ||||||
|       status: TodoItemStatus.Completed, |       status: TodoItemStatus.Completed, | ||||||
|     }, |     }, | ||||||
|  |     { | ||||||
|  |       uid: "15", | ||||||
|  |       summary: "Beer", | ||||||
|  |     }, | ||||||
|   ] as TodoItem[], |   ] as TodoItem[], | ||||||
|   })); | }; | ||||||
|   // eslint-disable-next-line @typescript-eslint/no-empty-function |  | ||||||
|   hass.mockWS("todo/item/subscribe", (_msg, _hass) => () => {}); | export const mockTodo = (hass: MockHomeAssistant) => { | ||||||
|  |   hass.mockWS("todo/item/list", () => items); | ||||||
|  |   hass.mockWS("todo/item/move", () => undefined); | ||||||
|  |   hass.mockWS("todo/item/subscribe", (_msg, _hass, onChange) => { | ||||||
|  |     onChange!(items); | ||||||
|  |     // eslint-disable-next-line @typescript-eslint/no-empty-function | ||||||
|  |     return () => {}; | ||||||
|  |   }); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -42,7 +42,6 @@ export default tseslint.config( | |||||||
|         __VERSION__: false, |         __VERSION__: false, | ||||||
|         __STATIC_PATH__: false, |         __STATIC_PATH__: false, | ||||||
|         __SUPERVISOR__: false, |         __SUPERVISOR__: false, | ||||||
|         Polymer: true, |  | ||||||
|       }, |       }, | ||||||
|  |  | ||||||
|       parser: tseslint.parser, |       parser: tseslint.parser, | ||||||
|   | |||||||
| @@ -38,12 +38,12 @@ class PageDescription extends HaMarkdown { | |||||||
|       } |       } | ||||||
|       .title { |       .title { | ||||||
|         font-size: 42px; |         font-size: 42px; | ||||||
|         line-height: 56px; |         line-height: var(--ha-line-height-condensed); | ||||||
|         padding-bottom: 8px; |         padding-bottom: 8px; | ||||||
|       } |       } | ||||||
|       .subtitle { |       .subtitle { | ||||||
|         font-size: 18px; |         font-size: var(--ha-font-size-l); | ||||||
|         line-height: 24px; |         line-height: var(--ha-line-height-normal); | ||||||
|       } |       } | ||||||
|       .root { |       .root { | ||||||
|         max-width: 800px; |         max-width: 800px; | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import "./ha-gallery"; | import "./ha-gallery"; | ||||||
|  |  | ||||||
| import("../../src/resources/ha-style"); | import("../../src/resources/append-ha-style"); | ||||||
|  |  | ||||||
| document.body.appendChild(document.createElement("ha-gallery")); | document.body.appendChild(document.createElement("ha-gallery")); | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ class HaDemoOptions extends LitElement { | |||||||
|         height: 64px; |         height: 64px; | ||||||
|         padding: 0 16px; |         padding: 0 16px; | ||||||
|         pointer-events: none; |         pointer-events: none; | ||||||
|         font-size: 20px; |         font-size: var(--ha-font-size-xl); | ||||||
|       } |       } | ||||||
|     `, |     `, | ||||||
|   ]; |   ]; | ||||||
|   | |||||||
| @@ -250,14 +250,14 @@ class HaGallery extends LitElement { | |||||||
|       } |       } | ||||||
|  |  | ||||||
|       .page-footer .header { |       .page-footer .header { | ||||||
|         font-size: 16px; |         font-size: var(--ha-font-size-l); | ||||||
|         font-weight: 500; |         font-weight: var(--ha-font-weight-medium); | ||||||
|         line-height: 28px; |         line-height: var(--ha-line-height-normal); | ||||||
|         text-align: center; |         text-align: center; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       .page-footer .secondary { |       .page-footer .secondary { | ||||||
|         line-height: 23px; |         line-height: var(--ha-line-height-normal); | ||||||
|         text-align: center; |         text-align: center; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,29 +1,30 @@ | |||||||
| import type { TemplateResult } from "lit"; | import type { TemplateResult } from "lit"; | ||||||
| import { LitElement, html, css } from "lit"; | import { LitElement, css, html } from "lit"; | ||||||
| import { customElement, state } from "lit/decorators"; | import { customElement, state } from "lit/decorators"; | ||||||
|  | import "../../../../src/components/ha-formfield"; | ||||||
| import { provideHass } from "../../../../src/fake_data/provide_hass"; | import { provideHass } from "../../../../src/fake_data/provide_hass"; | ||||||
| import type { HomeAssistant } from "../../../../src/types"; | import type { HomeAssistant } from "../../../../src/types"; | ||||||
| import "../../components/demo-black-white-row"; | import "../../components/demo-black-white-row"; | ||||||
| import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry"; |  | ||||||
| import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry"; |  | ||||||
| import { mockAreaRegistry } from "../../../../demo/src/stubs/area_registry"; | import { mockAreaRegistry } from "../../../../demo/src/stubs/area_registry"; | ||||||
|  | import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry"; | ||||||
|  | import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry"; | ||||||
| import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor"; | import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor"; | ||||||
|  | import type { Action } from "../../../../src/data/script"; | ||||||
| import "../../../../src/panels/config/automation/action/ha-automation-action"; | import "../../../../src/panels/config/automation/action/ha-automation-action"; | ||||||
| import { HaChooseAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-choose"; | import { HaChooseAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-choose"; | ||||||
|  | import { HaConditionAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-condition"; | ||||||
| import { HaDelayAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-delay"; | import { HaDelayAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-delay"; | ||||||
| import { HaDeviceAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-device_id"; | import { HaDeviceAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-device_id"; | ||||||
| import { HaEventAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-event"; | import { HaEventAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-event"; | ||||||
|  | import { HaIfAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-if"; | ||||||
|  | import { HaParallelAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-parallel"; | ||||||
|  | import { HaPlayMediaAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-play_media"; | ||||||
| import { HaRepeatAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-repeat"; | import { HaRepeatAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-repeat"; | ||||||
|  | import { HaSequenceAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-sequence"; | ||||||
| import { HaServiceAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-service"; | import { HaServiceAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-service"; | ||||||
|  | import { HaStopAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-stop"; | ||||||
| import { HaWaitForTriggerAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-wait_for_trigger"; | import { HaWaitForTriggerAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-wait_for_trigger"; | ||||||
| import { HaWaitAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-wait_template"; | import { HaWaitAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-wait_template"; | ||||||
| import type { Action } from "../../../../src/data/script"; |  | ||||||
| import { HaConditionAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-condition"; |  | ||||||
| import { HaSequenceAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-sequence"; |  | ||||||
| import { HaParallelAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-parallel"; |  | ||||||
| import { HaIfAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-if"; |  | ||||||
| import { HaStopAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-stop"; |  | ||||||
| import { HaPlayMediaAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-play_media"; |  | ||||||
|  |  | ||||||
| const SCHEMAS: { name: string; actions: Action[] }[] = [ | const SCHEMAS: { name: string; actions: Action[] }[] = [ | ||||||
|   { name: "Event", actions: [HaEventAction.defaultConfig] }, |   { name: "Event", actions: [HaEventAction.defaultConfig] }, | ||||||
|   | |||||||
| @@ -1,26 +1,27 @@ | |||||||
| import type { TemplateResult } from "lit"; | import type { TemplateResult } from "lit"; | ||||||
| import { LitElement, html, css } from "lit"; | import { LitElement, css, html } from "lit"; | ||||||
| import { customElement, state } from "lit/decorators"; | import { customElement, state } from "lit/decorators"; | ||||||
| import { provideHass } from "../../../../src/fake_data/provide_hass"; |  | ||||||
| import type { HomeAssistant } from "../../../../src/types"; |  | ||||||
| import "../../components/demo-black-white-row"; |  | ||||||
| import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry"; |  | ||||||
| import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry"; |  | ||||||
| import { mockAreaRegistry } from "../../../../demo/src/stubs/area_registry"; | import { mockAreaRegistry } from "../../../../demo/src/stubs/area_registry"; | ||||||
|  | import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry"; | ||||||
|  | import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry"; | ||||||
| import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor"; | import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor"; | ||||||
|  | import "../../../../src/components/ha-formfield"; | ||||||
| import type { ConditionWithShorthand } from "../../../../src/data/automation"; | import type { ConditionWithShorthand } from "../../../../src/data/automation"; | ||||||
|  | import { provideHass } from "../../../../src/fake_data/provide_hass"; | ||||||
| import "../../../../src/panels/config/automation/condition/ha-automation-condition"; | import "../../../../src/panels/config/automation/condition/ha-automation-condition"; | ||||||
|  | import { HaAndCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-and"; | ||||||
| import { HaDeviceCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-device"; | import { HaDeviceCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-device"; | ||||||
|  | import { HaNotCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-not"; | ||||||
| import HaNumericStateCondition from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-numeric_state"; | import HaNumericStateCondition from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-numeric_state"; | ||||||
|  | import { HaOrCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-or"; | ||||||
| import { HaStateCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-state"; | import { HaStateCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-state"; | ||||||
| import { HaSunCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-sun"; | import { HaSunCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-sun"; | ||||||
| import { HaTemplateCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-template"; | import { HaTemplateCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-template"; | ||||||
| import { HaTimeCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-time"; | import { HaTimeCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-time"; | ||||||
| import { HaTriggerCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-trigger"; | import { HaTriggerCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-trigger"; | ||||||
| import { HaZoneCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-zone"; | import { HaZoneCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-zone"; | ||||||
| import { HaAndCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-and"; | import type { HomeAssistant } from "../../../../src/types"; | ||||||
| import { HaOrCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-or"; | import "../../components/demo-black-white-row"; | ||||||
| import { HaNotCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-not"; |  | ||||||
|  |  | ||||||
| const SCHEMAS: { name: string; conditions: ConditionWithShorthand[] }[] = [ | const SCHEMAS: { name: string; conditions: ConditionWithShorthand[] }[] = [ | ||||||
|   { |   { | ||||||
|   | |||||||
| @@ -1,35 +1,36 @@ | |||||||
| import type { TemplateResult } from "lit"; | import type { TemplateResult } from "lit"; | ||||||
| import { LitElement, html, css } from "lit"; | import { LitElement, css, html } from "lit"; | ||||||
| import { customElement, state } from "lit/decorators"; | import { customElement, state } from "lit/decorators"; | ||||||
| import { provideHass } from "../../../../src/fake_data/provide_hass"; |  | ||||||
| import type { HomeAssistant } from "../../../../src/types"; |  | ||||||
| import "../../components/demo-black-white-row"; |  | ||||||
| import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry"; |  | ||||||
| import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry"; |  | ||||||
| import { mockAreaRegistry } from "../../../../demo/src/stubs/area_registry"; | import { mockAreaRegistry } from "../../../../demo/src/stubs/area_registry"; | ||||||
| import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor"; |  | ||||||
| import { mockConfig } from "../../../../demo/src/stubs/config"; |  | ||||||
| import { mockTags } from "../../../../demo/src/stubs/tags"; |  | ||||||
| import { mockAuth } from "../../../../demo/src/stubs/auth"; | import { mockAuth } from "../../../../demo/src/stubs/auth"; | ||||||
|  | import { mockConfig } from "../../../../demo/src/stubs/config"; | ||||||
|  | import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry"; | ||||||
|  | import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry"; | ||||||
|  | import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor"; | ||||||
|  | import { mockTags } from "../../../../demo/src/stubs/tags"; | ||||||
|  | import "../../../../src/components/ha-formfield"; | ||||||
| import type { Trigger } from "../../../../src/data/automation"; | import type { Trigger } from "../../../../src/data/automation"; | ||||||
| import { HaGeolocationTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-geo_location"; | import { provideHass } from "../../../../src/fake_data/provide_hass"; | ||||||
|  | import "../../../../src/panels/config/automation/trigger/ha-automation-trigger"; | ||||||
|  | import { HaConversationTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-conversation"; | ||||||
|  | import { HaDeviceTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-device"; | ||||||
| import { HaEventTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-event"; | import { HaEventTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-event"; | ||||||
|  | import { HaGeolocationTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-geo_location"; | ||||||
| import { HaHassTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-homeassistant"; | import { HaHassTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-homeassistant"; | ||||||
|  | import { HaTriggerList } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-list"; | ||||||
|  | import { HaMQTTTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-mqtt"; | ||||||
| import { HaNumericStateTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-numeric_state"; | import { HaNumericStateTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-numeric_state"; | ||||||
|  | import { HaPersistentNotificationTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-persistent_notification"; | ||||||
|  | import { HaStateTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-state"; | ||||||
| import { HaSunTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-sun"; | import { HaSunTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-sun"; | ||||||
| import { HaTagTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-tag"; | import { HaTagTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-tag"; | ||||||
| import { HaTemplateTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-template"; | import { HaTemplateTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-template"; | ||||||
| import { HaTimeTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-time"; | import { HaTimeTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-time"; | ||||||
| import { HaTimePatternTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-time_pattern"; | import { HaTimePatternTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-time_pattern"; | ||||||
| import { HaWebhookTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-webhook"; | import { HaWebhookTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-webhook"; | ||||||
| import { HaPersistentNotificationTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-persistent_notification"; |  | ||||||
| import { HaZoneTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-zone"; | import { HaZoneTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-zone"; | ||||||
| import { HaDeviceTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-device"; | import type { HomeAssistant } from "../../../../src/types"; | ||||||
| import { HaStateTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-state"; | import "../../components/demo-black-white-row"; | ||||||
| import { HaMQTTTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-mqtt"; |  | ||||||
| import "../../../../src/panels/config/automation/trigger/ha-automation-trigger"; |  | ||||||
| import { HaConversationTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-conversation"; |  | ||||||
| import { HaTriggerList } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-list"; |  | ||||||
|  |  | ||||||
| const SCHEMAS: { name: string; triggers: Trigger[] }[] = [ | const SCHEMAS: { name: string; triggers: Trigger[] }[] = [ | ||||||
|   { |   { | ||||||
|   | |||||||
							
								
								
									
										65
									
								
								gallery/src/pages/components/ha-badge.markdown
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								gallery/src/pages/components/ha-badge.markdown
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | |||||||
|  | --- | ||||||
|  | title: Badge | ||||||
|  | subtitle: Lovelace dashboard badge | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | <style> | ||||||
|  |   .wrapper { | ||||||
|  |     display: flex; | ||||||
|  |     gap: 24px; | ||||||
|  |   } | ||||||
|  | </style> | ||||||
|  |  | ||||||
|  | # Badge `<ha-badge>` | ||||||
|  |  | ||||||
|  | The badge component is a small component that displays a number or status information. It is used in the lovelace dashboard on the top. | ||||||
|  |  | ||||||
|  | ## Implementation | ||||||
|  |  | ||||||
|  | ### Example Usage | ||||||
|  |  | ||||||
|  | <div class="wrapper"> | ||||||
|  |   <ha-badge> | ||||||
|  |     simple badge | ||||||
|  |   </ha-badge> | ||||||
|  |  | ||||||
|  |   <ha-badge label="Info"> | ||||||
|  |     With a label | ||||||
|  |   </ha-badge> | ||||||
|  |  | ||||||
|  |   <ha-badge type="button"> | ||||||
|  |     Type button | ||||||
|  |   </ha-badge> | ||||||
|  | </div> | ||||||
|  |  | ||||||
|  | ```html | ||||||
|  | <ha-badge> simple badge </ha-badge> | ||||||
|  |  | ||||||
|  | <ha-badge label="Info"> With a label </ha-badge> | ||||||
|  |  | ||||||
|  | <ha-badge type="button"> Type button </ha-badge> | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### API | ||||||
|  |  | ||||||
|  | **Slots** | ||||||
|  |  | ||||||
|  | - default slot is the content of the badge | ||||||
|  |   - no default | ||||||
|  | - `icon` set the icon of the badge | ||||||
|  |   - no default | ||||||
|  |  | ||||||
|  | **Properties/Attributes** | ||||||
|  |  | ||||||
|  | | Name     | Type                    | Default     | Description                                                  | | ||||||
|  | | -------- | ----------------------- | ----------- | ------------------------------------------------------------ | | ||||||
|  | | type     | `"badge"` or `"button"` | `"badge"`   | If it's button it shows a ripple effect                      | | ||||||
|  | | label    | string                  | `undefined` | Text label for the badge, only visible if `iconOnly = false` | | ||||||
|  | | iconOnly | boolean                 | `false`     | Only show label                                              | | ||||||
|  |  | ||||||
|  | **CSS Custom Properties** | ||||||
|  |  | ||||||
|  | - `--ha-badge-size` (default `36px`) | ||||||
|  | - `--ha-badge-border-radius` (default `calc(var(--ha-badge-size, 36px) / 2)`) | ||||||
|  | - `--ha-badge-font-size` (default `var(--ha-font-size-s)`) | ||||||
|  | - `--ha-badge-icon-size` (default `18px`) | ||||||
							
								
								
									
										129
									
								
								gallery/src/pages/components/ha-badge.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								gallery/src/pages/components/ha-badge.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | |||||||
|  | import { mdiButtonCursor, mdiHome } from "@mdi/js"; | ||||||
|  | import type { TemplateResult } from "lit"; | ||||||
|  | import { css, html, LitElement } from "lit"; | ||||||
|  | import { customElement } from "lit/decorators"; | ||||||
|  | import { applyThemesOnElement } from "../../../../src/common/dom/apply_themes_on_element"; | ||||||
|  | import "../../../../src/components/ha-badge"; | ||||||
|  | import "../../../../src/components/ha-card"; | ||||||
|  | import "../../../../src/components/ha-svg-icon"; | ||||||
|  | import { mdiHomeAssistant } from "../../../../src/resources/home-assistant-logo-svg"; | ||||||
|  |  | ||||||
|  | const badges: { | ||||||
|  |   type?: "badge" | "button"; | ||||||
|  |   label?: string; | ||||||
|  |   iconOnly?: boolean; | ||||||
|  |   slot?: TemplateResult; | ||||||
|  |   iconSlot?: TemplateResult; | ||||||
|  | }[] = [ | ||||||
|  |   { | ||||||
|  |     slot: html`<span>Badge</span>`, | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     type: "badge", | ||||||
|  |     label: "Badge", | ||||||
|  |     iconSlot: html`<ha-svg-icon slot="icon" .path=${mdiHome}></ha-svg-icon>`, | ||||||
|  |     slot: html`<span>Badge</span>`, | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     type: "button", | ||||||
|  |     label: "Button", | ||||||
|  |     iconSlot: html`<ha-svg-icon | ||||||
|  |       slot="icon" | ||||||
|  |       .path=${mdiButtonCursor} | ||||||
|  |     ></ha-svg-icon>`, | ||||||
|  |     slot: html`<span>Button</span>`, | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     type: "button", | ||||||
|  |     label: "Label only", | ||||||
|  |     iconSlot: html`<ha-svg-icon | ||||||
|  |       slot="icon" | ||||||
|  |       .path=${mdiButtonCursor} | ||||||
|  |     ></ha-svg-icon>`, | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     type: "button", | ||||||
|  |     label: "Label", | ||||||
|  |     slot: html`<span>Button no label</span>`, | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     label: "Icon only", | ||||||
|  |     iconOnly: true, | ||||||
|  |     iconSlot: html`<ha-svg-icon | ||||||
|  |       slot="icon" | ||||||
|  |       .path=${mdiHomeAssistant} | ||||||
|  |     ></ha-svg-icon>`, | ||||||
|  |   }, | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  | @customElement("demo-components-ha-badge") | ||||||
|  | export class DemoHaBadge extends LitElement { | ||||||
|  |   protected render(): TemplateResult { | ||||||
|  |     return html` | ||||||
|  |       ${["light", "dark"].map( | ||||||
|  |         (mode) => html` | ||||||
|  |           <div class=${mode}> | ||||||
|  |             <ha-card header="ha-badge ${mode} demo"> | ||||||
|  |               <div class="card-content"> | ||||||
|  |                 ${badges.map( | ||||||
|  |                   (badge) => html` | ||||||
|  |                     <ha-badge | ||||||
|  |                       .type=${badge.type || undefined} | ||||||
|  |                       .label=${badge.label} | ||||||
|  |                       .iconOnly=${badge.iconOnly || false} | ||||||
|  |                     > | ||||||
|  |                       ${badge.iconSlot} ${badge.slot} | ||||||
|  |                     </ha-badge> | ||||||
|  |                   ` | ||||||
|  |                 )} | ||||||
|  |               </div> | ||||||
|  |             </ha-card> | ||||||
|  |           </div> | ||||||
|  |         ` | ||||||
|  |       )} | ||||||
|  |     `; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   firstUpdated(changedProps) { | ||||||
|  |     super.firstUpdated(changedProps); | ||||||
|  |     applyThemesOnElement( | ||||||
|  |       this.shadowRoot!.querySelector(".dark"), | ||||||
|  |       { | ||||||
|  |         default_theme: "default", | ||||||
|  |         default_dark_theme: "default", | ||||||
|  |         themes: {}, | ||||||
|  |         darkMode: true, | ||||||
|  |         theme: "default", | ||||||
|  |       }, | ||||||
|  |       undefined, | ||||||
|  |       undefined, | ||||||
|  |       true | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static styles = css` | ||||||
|  |     :host { | ||||||
|  |       display: flex; | ||||||
|  |       justify-content: center; | ||||||
|  |     } | ||||||
|  |     .dark, | ||||||
|  |     .light { | ||||||
|  |       display: block; | ||||||
|  |       background-color: var(--primary-background-color); | ||||||
|  |       padding: 0 50px; | ||||||
|  |     } | ||||||
|  |     ha-card { | ||||||
|  |       margin: 24px auto; | ||||||
|  |     } | ||||||
|  |     .card-content { | ||||||
|  |       display: flex; | ||||||
|  |       gap: 24px; | ||||||
|  |     } | ||||||
|  |   `; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | declare global { | ||||||
|  |   interface HTMLElementTagNameMap { | ||||||
|  |     "demo-components-ha-badge": DemoHaBadge; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -150,7 +150,7 @@ export class DemoHaBarButton extends LitElement { | |||||||
|       margin: 0; |       margin: 0; | ||||||
|     } |     } | ||||||
|     label { |     label { | ||||||
|       font-weight: 600; |       font-weight: var(--ha-font-weight-bold); | ||||||
|     } |     } | ||||||
|     .custom { |     .custom { | ||||||
|       --control-button-icon-color: var(--primary-color); |       --control-button-icon-color: var(--primary-color); | ||||||
|   | |||||||
| @@ -86,7 +86,7 @@ export class DemoHarControlNumberButtons extends LitElement { | |||||||
|       margin: 0; |       margin: 0; | ||||||
|     } |     } | ||||||
|     label { |     label { | ||||||
|       font-weight: 600; |       font-weight: var(--ha-font-weight-bold); | ||||||
|     } |     } | ||||||
|     .custom { |     .custom { | ||||||
|       color: #2196f3; |       color: #2196f3; | ||||||
|   | |||||||
| @@ -125,7 +125,7 @@ export class DemoHaControlSelectMenu extends LitElement { | |||||||
|       margin: 0; |       margin: 0; | ||||||
|     } |     } | ||||||
|     label { |     label { | ||||||
|       font-weight: 600; |       font-weight: var(--ha-font-weight-bold); | ||||||
|     } |     } | ||||||
|     .custom { |     .custom { | ||||||
|       --control-button-icon-color: var(--primary-color); |       --control-button-icon-color: var(--primary-color); | ||||||
|   | |||||||
| @@ -181,7 +181,7 @@ export class DemoHaControlSelect extends LitElement { | |||||||
|       margin: 0; |       margin: 0; | ||||||
|     } |     } | ||||||
|     label { |     label { | ||||||
|       font-weight: 600; |       font-weight: var(--ha-font-weight-bold); | ||||||
|     } |     } | ||||||
|     .custom { |     .custom { | ||||||
|       --mdc-icon-size: 24px; |       --mdc-icon-size: 24px; | ||||||
|   | |||||||
| @@ -144,7 +144,7 @@ export class DemoHaBarSlider extends LitElement { | |||||||
|       margin: 0; |       margin: 0; | ||||||
|     } |     } | ||||||
|     label { |     label { | ||||||
|       font-weight: 600; |       font-weight: var(--ha-font-weight-bold); | ||||||
|     } |     } | ||||||
|     .custom { |     .custom { | ||||||
|       --control-slider-color: #ffcf4c; |       --control-slider-color: #ffcf4c; | ||||||
|   | |||||||
| @@ -112,7 +112,7 @@ export class DemoHaControlSwitch extends LitElement { | |||||||
|       margin: 0; |       margin: 0; | ||||||
|     } |     } | ||||||
|     label { |     label { | ||||||
|       font-weight: 600; |       font-weight: var(--ha-font-weight-bold); | ||||||
|     } |     } | ||||||
|     .custom { |     .custom { | ||||||
|       --control-switch-on-color: var(--green-color); |       --control-switch-on-color: var(--green-color); | ||||||
|   | |||||||
| @@ -105,8 +105,8 @@ export class DemoHaHsColorPicker extends LitElement { | |||||||
|       width: 400px; |       width: 400px; | ||||||
|     } |     } | ||||||
|     .value { |     .value { | ||||||
|       font-size: 22px; |       font-size: var(--ha-font-size-xl); | ||||||
|       font-weight: bold; |       font-weight: var(--ha-font-weight-bold); | ||||||
|       margin: 0 0 12px 0; |       margin: 0 0 12px 0; | ||||||
|     } |     } | ||||||
|   `; |   `; | ||||||
|   | |||||||
| @@ -123,7 +123,7 @@ export class DemoHaSelectBox extends LitElement { | |||||||
|       margin: 0; |       margin: 0; | ||||||
|     } |     } | ||||||
|     label { |     label { | ||||||
|       font-weight: 600; |       font-weight: var(--ha-font-weight-bold); | ||||||
|       margin-bottom: 8px; |       margin-bottom: 8px; | ||||||
|       display: block; |       display: block; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -6,22 +6,23 @@ import { mockAreaRegistry } from "../../../../demo/src/stubs/area_registry"; | |||||||
| import { mockConfigEntries } from "../../../../demo/src/stubs/config_entries"; | import { mockConfigEntries } from "../../../../demo/src/stubs/config_entries"; | ||||||
| import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry"; | import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry"; | ||||||
| import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry"; | import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry"; | ||||||
|  | import { mockFloorRegistry } from "../../../../demo/src/stubs/floor_registry"; | ||||||
| import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor"; | import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor"; | ||||||
|  | import { mockLabelRegistry } from "../../../../demo/src/stubs/label_registry"; | ||||||
|  | import "../../../../src/components/ha-formfield"; | ||||||
| import "../../../../src/components/ha-selector/ha-selector"; | import "../../../../src/components/ha-selector/ha-selector"; | ||||||
| import "../../../../src/components/ha-settings-row"; | import "../../../../src/components/ha-settings-row"; | ||||||
| import type { AreaRegistryEntry } from "../../../../src/data/area_registry"; | import type { AreaRegistryEntry } from "../../../../src/data/area_registry"; | ||||||
| import type { BlueprintInput } from "../../../../src/data/blueprint"; | import type { BlueprintInput } from "../../../../src/data/blueprint"; | ||||||
|  | import type { DeviceRegistryEntry } from "../../../../src/data/device_registry"; | ||||||
|  | import type { FloorRegistryEntry } from "../../../../src/data/floor_registry"; | ||||||
|  | import type { LabelRegistryEntry } from "../../../../src/data/label_registry"; | ||||||
| import { showDialog } from "../../../../src/dialogs/make-dialog-manager"; | import { showDialog } from "../../../../src/dialogs/make-dialog-manager"; | ||||||
| import { getEntity } from "../../../../src/fake_data/entity"; | import { getEntity } from "../../../../src/fake_data/entity"; | ||||||
| import { provideHass } from "../../../../src/fake_data/provide_hass"; | import { provideHass } from "../../../../src/fake_data/provide_hass"; | ||||||
| import type { ProvideHassElement } from "../../../../src/mixins/provide-hass-lit-mixin"; | import type { ProvideHassElement } from "../../../../src/mixins/provide-hass-lit-mixin"; | ||||||
| import type { HomeAssistant } from "../../../../src/types"; | import type { HomeAssistant } from "../../../../src/types"; | ||||||
| import "../../components/demo-black-white-row"; | import "../../components/demo-black-white-row"; | ||||||
| import type { FloorRegistryEntry } from "../../../../src/data/floor_registry"; |  | ||||||
| import type { LabelRegistryEntry } from "../../../../src/data/label_registry"; |  | ||||||
| import { mockFloorRegistry } from "../../../../demo/src/stubs/floor_registry"; |  | ||||||
| import { mockLabelRegistry } from "../../../../demo/src/stubs/label_registry"; |  | ||||||
| import type { DeviceRegistryEntry } from "../../../../src/data/device_registry"; |  | ||||||
|  |  | ||||||
| const ENTITIES = [ | const ENTITIES = [ | ||||||
|   getEntity("alarm_control_panel", "alarm", "disarmed", { |   getEntity("alarm_control_panel", "alarm", "disarmed", { | ||||||
| @@ -643,9 +644,6 @@ class DemoHaSelector extends LitElement implements ProvideHassElement { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static styles = css` |   static styles = css` | ||||||
|     ha-settings-row { |  | ||||||
|       --paper-item-body-two-line-min-height: 0; |  | ||||||
|     } |  | ||||||
|     .options { |     .options { | ||||||
|       max-width: 800px; |       max-width: 800px; | ||||||
|       margin: 16px auto; |       margin: 16px auto; | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| import type { TemplateResult } from "lit"; | import type { TemplateResult } from "lit"; | ||||||
| import { html, css, LitElement } from "lit"; | import { css, html, LitElement } from "lit"; | ||||||
| import { customElement, property } from "lit/decorators"; | import { customElement, property } from "lit/decorators"; | ||||||
|  | import { applyThemesOnElement } from "../../../../src/common/dom/apply_themes_on_element"; | ||||||
| import "../../../../src/components/ha-bar"; | import "../../../../src/components/ha-bar"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
| import "../../../../src/components/ha-spinner"; | import "../../../../src/components/ha-spinner"; | ||||||
| @@ -11,29 +12,66 @@ export class DemoHaSpinner extends LitElement { | |||||||
|   @property({ attribute: false }) hass!: HomeAssistant; |   @property({ attribute: false }) hass!: HomeAssistant; | ||||||
|  |  | ||||||
|   protected render(): TemplateResult { |   protected render(): TemplateResult { | ||||||
|     return html`<ha-card header="Basic spinner"> |     return html` | ||||||
|         <div class="card-content"> |       ${["light", "dark"].map( | ||||||
|           <ha-spinner></ha-spinner></div |         (mode) => html` | ||||||
|       ></ha-card> |           <div class=${mode}> | ||||||
|       <ha-card header="Different spinner sizes"> |             <ha-card header="ha-badge ${mode} demo"> | ||||||
|               <div class="card-content"> |               <div class="card-content"> | ||||||
|  |                 <ha-spinner></ha-spinner> | ||||||
|                 <ha-spinner size="tiny"></ha-spinner> |                 <ha-spinner size="tiny"></ha-spinner> | ||||||
|                 <ha-spinner size="small"></ha-spinner> |                 <ha-spinner size="small"></ha-spinner> | ||||||
|                 <ha-spinner size="medium"></ha-spinner> |                 <ha-spinner size="medium"></ha-spinner> | ||||||
|           <ha-spinner size="large"></ha-spinner></div |                 <ha-spinner size="large"></ha-spinner> | ||||||
|       ></ha-card> |  | ||||||
|       <ha-card header="Spinner with an aria-label"> |  | ||||||
|         <div class="card-content"> |  | ||||||
|                 <ha-spinner aria-label="Doing something..."></ha-spinner> |                 <ha-spinner aria-label="Doing something..."></ha-spinner> | ||||||
|           <ha-spinner .ariaLabel=${"Doing something..."}></ha-spinner></div |                 <ha-spinner .ariaLabel=${"Doing something..."}></ha-spinner> | ||||||
|       ></ha-card>`; |               </div> | ||||||
|  |             </ha-card> | ||||||
|  |           </div> | ||||||
|  |         ` | ||||||
|  |       )} | ||||||
|  |     `; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   firstUpdated(changedProps) { | ||||||
|  |     super.firstUpdated(changedProps); | ||||||
|  |     applyThemesOnElement( | ||||||
|  |       this.shadowRoot!.querySelector(".dark"), | ||||||
|  |       { | ||||||
|  |         default_theme: "default", | ||||||
|  |         default_dark_theme: "default", | ||||||
|  |         themes: {}, | ||||||
|  |         darkMode: true, | ||||||
|  |         theme: "default", | ||||||
|  |       }, | ||||||
|  |       undefined, | ||||||
|  |       undefined, | ||||||
|  |       true | ||||||
|  |     ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static styles = css` |   static styles = css` | ||||||
|  |     :host { | ||||||
|  |       display: flex; | ||||||
|  |       justify-content: center; | ||||||
|  |     } | ||||||
|  |     .dark, | ||||||
|  |     .light { | ||||||
|  |       display: block; | ||||||
|  |       background-color: var(--primary-background-color); | ||||||
|  |       padding: 0 50px; | ||||||
|  |       margin: 16px; | ||||||
|  |       border-radius: 8px; | ||||||
|  |     } | ||||||
|     ha-card { |     ha-card { | ||||||
|       max-width: 600px; |  | ||||||
|       margin: 24px auto; |       margin: 24px auto; | ||||||
|     } |     } | ||||||
|  |     .card-content { | ||||||
|  |       display: flex; | ||||||
|  |       flex-direction: column; | ||||||
|  |       align-items: center; | ||||||
|  |       gap: 24px; | ||||||
|  |     } | ||||||
|   `; |   `; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ Tooltips use `display: contents` so they won't interfere with how elements are p | |||||||
|  |  | ||||||
| ## Documentation | ## Documentation | ||||||
|  |  | ||||||
| This element is based on sholace `sl-tooltip` it only sets some css tokens and has a custom show/hide animation. | This element is based on shoelace `sl-tooltip` it only sets some css tokens and has a custom show/hide animation. | ||||||
|  |  | ||||||
| <a href="https://shoelace.style/components/tooltip" target="_blank" rel="noopener noreferrer">Shoelace documentation</a> | <a href="https://shoelace.style/components/tooltip" target="_blank" rel="noopener noreferrer">Shoelace documentation</a> | ||||||
|  |  | ||||||
| @@ -28,3 +28,7 @@ In your theme settings use this without the prefixed `--`. | |||||||
|  |  | ||||||
| - `--ha-tooltip-border-radius` (Default: 4px) | - `--ha-tooltip-border-radius` (Default: 4px) | ||||||
| - `--ha-tooltip-arrow-size` (Default: 8px) | - `--ha-tooltip-arrow-size` (Default: 8px) | ||||||
|  | - `--sl-tooltip-font-family` (Default: `var(--ha-font-family-body)`) | ||||||
|  | - `--ha-tooltip-font-size` (Default: `var(--ha-font-size-s)`) | ||||||
|  | - `--sl-tooltip-font-weight` (Default: `var(--ha-font-weight-normal)`) | ||||||
|  | - `--sl-tooltip-line-height` (Default: `var(--ha-line-height-condensed)`) | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| import "@material/mwc-list/mwc-list"; |  | ||||||
| import { LitElement, css, html } from "lit"; | import { LitElement, css, html } from "lit"; | ||||||
| import { customElement, state } from "lit/decorators"; | import { customElement, state } from "lit/decorators"; | ||||||
| import { formatDateTimeNumeric } from "../../../../src/common/datetime/format_date_time"; | import { formatDateTimeNumeric } from "../../../../src/common/datetime/format_date_time"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
| import "../../../../src/components/ha-control-select"; | import "../../../../src/components/ha-control-select"; | ||||||
|  | import "../../../../src/components/ha-list"; | ||||||
| import type { FrontendLocaleData } from "../../../../src/data/translation"; | import type { FrontendLocaleData } from "../../../../src/data/translation"; | ||||||
| import { | import { | ||||||
|   DateFormat, |   DateFormat, | ||||||
| @@ -49,7 +49,7 @@ export class DemoDateTimeDateTimeNumeric extends LitElement { | |||||||
|         @value-changed=${this.handleValueChanged} |         @value-changed=${this.handleValueChanged} | ||||||
|       > |       > | ||||||
|       </ha-control-select> |       </ha-control-select> | ||||||
|       <mwc-list> |       <ha-list> | ||||||
|         <div class="container header"> |         <div class="container header"> | ||||||
|           <div>Language</div> |           <div>Language</div> | ||||||
|           <div class="center">Default (lang)</div> |           <div class="center">Default (lang)</div> | ||||||
| @@ -96,7 +96,7 @@ export class DemoDateTimeDateTimeNumeric extends LitElement { | |||||||
|             </div> |             </div> | ||||||
|           ` |           ` | ||||||
|         )} |         )} | ||||||
|       </mwc-list> |       </ha-list> | ||||||
|     `; |     `; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -106,7 +106,7 @@ export class DemoDateTimeDateTimeNumeric extends LitElement { | |||||||
|       margin: 12px auto; |       margin: 12px auto; | ||||||
|     } |     } | ||||||
|     .header { |     .header { | ||||||
|       font-weight: bold; |       font-weight: var(--ha-font-weight-bold); | ||||||
|     } |     } | ||||||
|     .center { |     .center { | ||||||
|       text-align: center; |       text-align: center; | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| import "@material/mwc-list/mwc-list"; |  | ||||||
| import { LitElement, css, html } from "lit"; | import { LitElement, css, html } from "lit"; | ||||||
| import { customElement, state } from "lit/decorators"; | import { customElement, state } from "lit/decorators"; | ||||||
| import { formatDateTimeWithSeconds } from "../../../../src/common/datetime/format_date_time"; | import { formatDateTimeWithSeconds } from "../../../../src/common/datetime/format_date_time"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
| import "../../../../src/components/ha-control-select"; | import "../../../../src/components/ha-control-select"; | ||||||
|  | import "../../../../src/components/ha-list"; | ||||||
| import type { FrontendLocaleData } from "../../../../src/data/translation"; | import type { FrontendLocaleData } from "../../../../src/data/translation"; | ||||||
| import { | import { | ||||||
|   DateFormat, |   DateFormat, | ||||||
| @@ -49,7 +49,7 @@ export class DemoDateTimeDateTimeSeconds extends LitElement { | |||||||
|         @value-changed=${this.handleValueChanged} |         @value-changed=${this.handleValueChanged} | ||||||
|       > |       > | ||||||
|       </ha-control-select> |       </ha-control-select> | ||||||
|       <mwc-list> |       <ha-list> | ||||||
|         <div class="container header"> |         <div class="container header"> | ||||||
|           <div>Language</div> |           <div>Language</div> | ||||||
|           <div class="center">Default (lang)</div> |           <div class="center">Default (lang)</div> | ||||||
| @@ -96,7 +96,7 @@ export class DemoDateTimeDateTimeSeconds extends LitElement { | |||||||
|             </div> |             </div> | ||||||
|           ` |           ` | ||||||
|         )} |         )} | ||||||
|       </mwc-list> |       </ha-list> | ||||||
|     `; |     `; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -106,7 +106,7 @@ export class DemoDateTimeDateTimeSeconds extends LitElement { | |||||||
|       margin: 12px auto; |       margin: 12px auto; | ||||||
|     } |     } | ||||||
|     .header { |     .header { | ||||||
|       font-weight: bold; |       font-weight: var(--ha-font-weight-bold); | ||||||
|     } |     } | ||||||
|     .center { |     .center { | ||||||
|       text-align: center; |       text-align: center; | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| import "@material/mwc-list/mwc-list"; |  | ||||||
| import { LitElement, css, html } from "lit"; | import { LitElement, css, html } from "lit"; | ||||||
| import { customElement, state } from "lit/decorators"; | import { customElement, state } from "lit/decorators"; | ||||||
| import { formatShortDateTimeWithYear } from "../../../../src/common/datetime/format_date_time"; | import { formatShortDateTimeWithYear } from "../../../../src/common/datetime/format_date_time"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
| import "../../../../src/components/ha-control-select"; | import "../../../../src/components/ha-control-select"; | ||||||
|  | import "../../../../src/components/ha-list"; | ||||||
| import type { FrontendLocaleData } from "../../../../src/data/translation"; | import type { FrontendLocaleData } from "../../../../src/data/translation"; | ||||||
| import { | import { | ||||||
|   DateFormat, |   DateFormat, | ||||||
| @@ -49,7 +49,7 @@ export class DemoDateTimeDateTimeShortYear extends LitElement { | |||||||
|         @value-changed=${this.handleValueChanged} |         @value-changed=${this.handleValueChanged} | ||||||
|       > |       > | ||||||
|       </ha-control-select> |       </ha-control-select> | ||||||
|       <mwc-list> |       <ha-list> | ||||||
|         <div class="container header"> |         <div class="container header"> | ||||||
|           <div>Language</div> |           <div>Language</div> | ||||||
|           <div class="center">Default (lang)</div> |           <div class="center">Default (lang)</div> | ||||||
| @@ -96,7 +96,7 @@ export class DemoDateTimeDateTimeShortYear extends LitElement { | |||||||
|             </div> |             </div> | ||||||
|           ` |           ` | ||||||
|         )} |         )} | ||||||
|       </mwc-list> |       </ha-list> | ||||||
|     `; |     `; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -106,7 +106,7 @@ export class DemoDateTimeDateTimeShortYear extends LitElement { | |||||||
|       margin: 12px auto; |       margin: 12px auto; | ||||||
|     } |     } | ||||||
|     .header { |     .header { | ||||||
|       font-weight: bold; |       font-weight: var(--ha-font-weight-bold); | ||||||
|     } |     } | ||||||
|     .center { |     .center { | ||||||
|       text-align: center; |       text-align: center; | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| import "@material/mwc-list/mwc-list"; |  | ||||||
| import { LitElement, css, html } from "lit"; | import { LitElement, css, html } from "lit"; | ||||||
| import { customElement, state } from "lit/decorators"; | import { customElement, state } from "lit/decorators"; | ||||||
| import { formatShortDateTime } from "../../../../src/common/datetime/format_date_time"; | import { formatShortDateTime } from "../../../../src/common/datetime/format_date_time"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
| import "../../../../src/components/ha-control-select"; | import "../../../../src/components/ha-control-select"; | ||||||
|  | import "../../../../src/components/ha-list"; | ||||||
| import type { FrontendLocaleData } from "../../../../src/data/translation"; | import type { FrontendLocaleData } from "../../../../src/data/translation"; | ||||||
| import { | import { | ||||||
|   DateFormat, |   DateFormat, | ||||||
| @@ -49,7 +49,7 @@ export class DemoDateTimeDateTimeShort extends LitElement { | |||||||
|         @value-changed=${this.handleValueChanged} |         @value-changed=${this.handleValueChanged} | ||||||
|       > |       > | ||||||
|       </ha-control-select> |       </ha-control-select> | ||||||
|       <mwc-list> |       <ha-list> | ||||||
|         <div class="container header"> |         <div class="container header"> | ||||||
|           <div>Language</div> |           <div>Language</div> | ||||||
|           <div class="center">Default (lang)</div> |           <div class="center">Default (lang)</div> | ||||||
| @@ -96,7 +96,7 @@ export class DemoDateTimeDateTimeShort extends LitElement { | |||||||
|             </div> |             </div> | ||||||
|           ` |           ` | ||||||
|         )} |         )} | ||||||
|       </mwc-list> |       </ha-list> | ||||||
|     `; |     `; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -106,7 +106,7 @@ export class DemoDateTimeDateTimeShort extends LitElement { | |||||||
|       margin: 12px auto; |       margin: 12px auto; | ||||||
|     } |     } | ||||||
|     .header { |     .header { | ||||||
|       font-weight: bold; |       font-weight: var(--ha-font-weight-bold); | ||||||
|     } |     } | ||||||
|     .center { |     .center { | ||||||
|       text-align: center; |       text-align: center; | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| import "@material/mwc-list/mwc-list"; |  | ||||||
| import { LitElement, css, html } from "lit"; | import { LitElement, css, html } from "lit"; | ||||||
| import { customElement, state } from "lit/decorators"; | import { customElement, state } from "lit/decorators"; | ||||||
| import { formatDateTime } from "../../../../src/common/datetime/format_date_time"; | import { formatDateTime } from "../../../../src/common/datetime/format_date_time"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
| import "../../../../src/components/ha-control-select"; | import "../../../../src/components/ha-control-select"; | ||||||
|  | import "../../../../src/components/ha-list"; | ||||||
| import type { FrontendLocaleData } from "../../../../src/data/translation"; | import type { FrontendLocaleData } from "../../../../src/data/translation"; | ||||||
| import { | import { | ||||||
|   DateFormat, |   DateFormat, | ||||||
| @@ -49,7 +49,7 @@ export class DemoDateTimeDateTime extends LitElement { | |||||||
|         @value-changed=${this.handleValueChanged} |         @value-changed=${this.handleValueChanged} | ||||||
|       > |       > | ||||||
|       </ha-control-select> |       </ha-control-select> | ||||||
|       <mwc-list> |       <ha-list> | ||||||
|         <div class="container header"> |         <div class="container header"> | ||||||
|           <div>Language</div> |           <div>Language</div> | ||||||
|           <div class="center">Default (lang)</div> |           <div class="center">Default (lang)</div> | ||||||
| @@ -96,7 +96,7 @@ export class DemoDateTimeDateTime extends LitElement { | |||||||
|             </div> |             </div> | ||||||
|           ` |           ` | ||||||
|         )} |         )} | ||||||
|       </mwc-list> |       </ha-list> | ||||||
|     `; |     `; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -106,7 +106,7 @@ export class DemoDateTimeDateTime extends LitElement { | |||||||
|       margin: 12px auto; |       margin: 12px auto; | ||||||
|     } |     } | ||||||
|     .header { |     .header { | ||||||
|       font-weight: bold; |       font-weight: var(--ha-font-weight-bold); | ||||||
|     } |     } | ||||||
|     .center { |     .center { | ||||||
|       text-align: center; |       text-align: center; | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| import "@material/mwc-list/mwc-list"; |  | ||||||
| import { css, html, LitElement } from "lit"; | import { css, html, LitElement } from "lit"; | ||||||
| import { customElement } from "lit/decorators"; | import { customElement } from "lit/decorators"; | ||||||
| import { formatDateNumeric } from "../../../../src/common/datetime/format_date"; | import { formatDateNumeric } from "../../../../src/common/datetime/format_date"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
|  | import "../../../../src/components/ha-list"; | ||||||
| import type { FrontendLocaleData } from "../../../../src/data/translation"; | import type { FrontendLocaleData } from "../../../../src/data/translation"; | ||||||
| import { | import { | ||||||
|   DateFormat, |   DateFormat, | ||||||
| @@ -27,7 +27,7 @@ export class DemoDateTimeDate extends LitElement { | |||||||
|     }; |     }; | ||||||
|     const date = new Date(); |     const date = new Date(); | ||||||
|     return html` |     return html` | ||||||
|       <mwc-list> |       <ha-list> | ||||||
|         <div class="container header"> |         <div class="container header"> | ||||||
|           <div>Language</div> |           <div>Language</div> | ||||||
|           <div class="center">Default (lang)</div> |           <div class="center">Default (lang)</div> | ||||||
| @@ -86,13 +86,13 @@ export class DemoDateTimeDate extends LitElement { | |||||||
|             </div> |             </div> | ||||||
|           ` |           ` | ||||||
|         )} |         )} | ||||||
|       </mwc-list> |       </ha-list> | ||||||
|     `; |     `; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static styles = css` |   static styles = css` | ||||||
|     .header { |     .header { | ||||||
|       font-weight: bold; |       font-weight: var(--ha-font-weight-bold); | ||||||
|     } |     } | ||||||
|     .center { |     .center { | ||||||
|       text-align: center; |       text-align: center; | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| import "@material/mwc-list/mwc-list"; |  | ||||||
| import { LitElement, css, html } from "lit"; | import { LitElement, css, html } from "lit"; | ||||||
| import { customElement, state } from "lit/decorators"; | import { customElement, state } from "lit/decorators"; | ||||||
| import { formatTimeWithSeconds } from "../../../../src/common/datetime/format_time"; | import { formatTimeWithSeconds } from "../../../../src/common/datetime/format_time"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
| import "../../../../src/components/ha-control-select"; | import "../../../../src/components/ha-control-select"; | ||||||
|  | import "../../../../src/components/ha-list"; | ||||||
| import type { FrontendLocaleData } from "../../../../src/data/translation"; | import type { FrontendLocaleData } from "../../../../src/data/translation"; | ||||||
| import { | import { | ||||||
|   DateFormat, |   DateFormat, | ||||||
| @@ -49,7 +49,7 @@ export class DemoDateTimeTimeSeconds extends LitElement { | |||||||
|         @value-changed=${this.handleValueChanged} |         @value-changed=${this.handleValueChanged} | ||||||
|       > |       > | ||||||
|       </ha-control-select> |       </ha-control-select> | ||||||
|       <mwc-list> |       <ha-list> | ||||||
|         <div class="container header"> |         <div class="container header"> | ||||||
|           <div>Language</div> |           <div>Language</div> | ||||||
|           <div class="center">Default (lang)</div> |           <div class="center">Default (lang)</div> | ||||||
| @@ -96,7 +96,7 @@ export class DemoDateTimeTimeSeconds extends LitElement { | |||||||
|             </div> |             </div> | ||||||
|           ` |           ` | ||||||
|         )} |         )} | ||||||
|       </mwc-list> |       </ha-list> | ||||||
|     `; |     `; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -106,7 +106,7 @@ export class DemoDateTimeTimeSeconds extends LitElement { | |||||||
|       margin: 12px auto; |       margin: 12px auto; | ||||||
|     } |     } | ||||||
|     .header { |     .header { | ||||||
|       font-weight: bold; |       font-weight: var(--ha-font-weight-bold); | ||||||
|     } |     } | ||||||
|     .center { |     .center { | ||||||
|       text-align: center; |       text-align: center; | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| import "@material/mwc-list/mwc-list"; |  | ||||||
| import { LitElement, css, html } from "lit"; | import { LitElement, css, html } from "lit"; | ||||||
| import { customElement, state } from "lit/decorators"; | import { customElement, state } from "lit/decorators"; | ||||||
| import { formatTimeWeekday } from "../../../../src/common/datetime/format_time"; | import { formatTimeWeekday } from "../../../../src/common/datetime/format_time"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
| import "../../../../src/components/ha-control-select"; | import "../../../../src/components/ha-control-select"; | ||||||
|  | import "../../../../src/components/ha-list"; | ||||||
| import type { FrontendLocaleData } from "../../../../src/data/translation"; | import type { FrontendLocaleData } from "../../../../src/data/translation"; | ||||||
| import { | import { | ||||||
|   DateFormat, |   DateFormat, | ||||||
| @@ -49,7 +49,7 @@ export class DemoDateTimeTimeWeekday extends LitElement { | |||||||
|         @value-changed=${this.handleValueChanged} |         @value-changed=${this.handleValueChanged} | ||||||
|       > |       > | ||||||
|       </ha-control-select> |       </ha-control-select> | ||||||
|       <mwc-list> |       <ha-list> | ||||||
|         <div class="container header"> |         <div class="container header"> | ||||||
|           <div>Language</div> |           <div>Language</div> | ||||||
|           <div class="center">Default (lang)</div> |           <div class="center">Default (lang)</div> | ||||||
| @@ -96,7 +96,7 @@ export class DemoDateTimeTimeWeekday extends LitElement { | |||||||
|             </div> |             </div> | ||||||
|           ` |           ` | ||||||
|         )} |         )} | ||||||
|       </mwc-list> |       </ha-list> | ||||||
|     `; |     `; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -106,7 +106,7 @@ export class DemoDateTimeTimeWeekday extends LitElement { | |||||||
|       margin: 12px auto; |       margin: 12px auto; | ||||||
|     } |     } | ||||||
|     .header { |     .header { | ||||||
|       font-weight: bold; |       font-weight: var(--ha-font-weight-bold); | ||||||
|     } |     } | ||||||
|     .center { |     .center { | ||||||
|       text-align: center; |       text-align: center; | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| import "@material/mwc-list/mwc-list"; |  | ||||||
| import { LitElement, css, html } from "lit"; | import { LitElement, css, html } from "lit"; | ||||||
| import { customElement, state } from "lit/decorators"; | import { customElement, state } from "lit/decorators"; | ||||||
| import { formatTime } from "../../../../src/common/datetime/format_time"; | import { formatTime } from "../../../../src/common/datetime/format_time"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
| import "../../../../src/components/ha-control-select"; | import "../../../../src/components/ha-control-select"; | ||||||
|  | import "../../../../src/components/ha-list"; | ||||||
| import type { FrontendLocaleData } from "../../../../src/data/translation"; | import type { FrontendLocaleData } from "../../../../src/data/translation"; | ||||||
| import { | import { | ||||||
|   DateFormat, |   DateFormat, | ||||||
| @@ -49,7 +49,7 @@ export class DemoDateTimeTime extends LitElement { | |||||||
|         @value-changed=${this.handleValueChanged} |         @value-changed=${this.handleValueChanged} | ||||||
|       > |       > | ||||||
|       </ha-control-select> |       </ha-control-select> | ||||||
|       <mwc-list> |       <ha-list> | ||||||
|         <div class="container header"> |         <div class="container header"> | ||||||
|           <div>Language</div> |           <div>Language</div> | ||||||
|           <div class="center">Default (lang)</div> |           <div class="center">Default (lang)</div> | ||||||
| @@ -96,7 +96,7 @@ export class DemoDateTimeTime extends LitElement { | |||||||
|             </div> |             </div> | ||||||
|           ` |           ` | ||||||
|         )} |         )} | ||||||
|       </mwc-list> |       </ha-list> | ||||||
|     `; |     `; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -106,7 +106,7 @@ export class DemoDateTimeTime extends LitElement { | |||||||
|       margin: 12px auto; |       margin: 12px auto; | ||||||
|     } |     } | ||||||
|     .header { |     .header { | ||||||
|       font-weight: bold; |       font-weight: var(--ha-font-weight-bold); | ||||||
|     } |     } | ||||||
|     .center { |     .center { | ||||||
|       text-align: center; |       text-align: center; | ||||||
|   | |||||||
| @@ -1,11 +1,11 @@ | |||||||
| import type { PropertyValues, TemplateResult } from "lit"; | import type { PropertyValues, TemplateResult } from "lit"; | ||||||
| import { html, LitElement } from "lit"; | import { html, LitElement } from "lit"; | ||||||
| import { customElement, query } from "lit/decorators"; | import { customElement, query } from "lit/decorators"; | ||||||
|  | import { mockIcons } from "../../../../demo/src/stubs/icons"; | ||||||
|  | import { mockTodo } from "../../../../demo/src/stubs/todo"; | ||||||
|  | import { getEntity } from "../../../../src/fake_data/entity"; | ||||||
| import { provideHass } from "../../../../src/fake_data/provide_hass"; | import { provideHass } from "../../../../src/fake_data/provide_hass"; | ||||||
| import "../../components/demo-cards"; | import "../../components/demo-cards"; | ||||||
| import { getEntity } from "../../../../src/fake_data/entity"; |  | ||||||
| import { mockTodo } from "../../../../demo/src/stubs/todo"; |  | ||||||
| import { mockIcons } from "../../../../demo/src/stubs/icons"; |  | ||||||
|  |  | ||||||
| const ENTITIES = [ | const ENTITIES = [ | ||||||
|   getEntity("todo", "shopping_list", "2", { |   getEntity("todo", "shopping_list", "2", { | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import type { ActionDetail } from "@material/mwc-list/mwc-list-foundation"; | import type { ActionDetail } from "@material/mwc-list/mwc-list-foundation"; | ||||||
| import "@material/mwc-list/mwc-list-item"; |  | ||||||
| import { mdiDotsVertical } from "@mdi/js"; | import { mdiDotsVertical } from "@mdi/js"; | ||||||
| import type { PropertyValues, TemplateResult } from "lit"; | import type { PropertyValues, TemplateResult } from "lit"; | ||||||
| import { css, html, LitElement, nothing } from "lit"; | import { css, html, LitElement, nothing } from "lit"; | ||||||
| @@ -11,6 +11,7 @@ import { navigate } from "../../../src/common/navigate"; | |||||||
| import { extractSearchParam } from "../../../src/common/url/search-params"; | import { extractSearchParam } from "../../../src/common/url/search-params"; | ||||||
| import "../../../src/components/ha-button-menu"; | import "../../../src/components/ha-button-menu"; | ||||||
| import "../../../src/components/ha-icon-button"; | import "../../../src/components/ha-icon-button"; | ||||||
|  | import "../../../src/components/ha-list-item"; | ||||||
| import "../../../src/components/search-input"; | import "../../../src/components/search-input"; | ||||||
| import type { HassioAddonRepository } from "../../../src/data/hassio/addon"; | import type { HassioAddonRepository } from "../../../src/data/hassio/addon"; | ||||||
| import { reloadHassioAddons } from "../../../src/data/hassio/addon"; | import { reloadHassioAddons } from "../../../src/data/hassio/addon"; | ||||||
| @@ -89,17 +90,17 @@ export class HassioAddonStore extends LitElement { | |||||||
|             .path=${mdiDotsVertical} |             .path=${mdiDotsVertical} | ||||||
|             slot="trigger" |             slot="trigger" | ||||||
|           ></ha-icon-button> |           ></ha-icon-button> | ||||||
|           <mwc-list-item> |           <ha-list-item> | ||||||
|             ${this.supervisor.localize("store.check_updates")} |             ${this.supervisor.localize("store.check_updates")} | ||||||
|           </mwc-list-item> |           </ha-list-item> | ||||||
|           <mwc-list-item> |           <ha-list-item> | ||||||
|             ${this.supervisor.localize("store.repositories")} |             ${this.supervisor.localize("store.repositories")} | ||||||
|           </mwc-list-item> |           </ha-list-item> | ||||||
|           ${this.hass.userData?.showAdvanced && |           ${this.hass.userData?.showAdvanced && | ||||||
|           atLeastVersion(this.hass.config.version, 0, 117) |           atLeastVersion(this.hass.config.version, 0, 117) | ||||||
|             ? html`<mwc-list-item> |             ? html`<ha-list-item> | ||||||
|                 ${this.supervisor.localize("store.registries")} |                 ${this.supervisor.localize("store.registries")} | ||||||
|               </mwc-list-item>` |               </ha-list-item>` | ||||||
|             : ""} |             : ""} | ||||||
|         </ha-button-menu> |         </ha-button-menu> | ||||||
|         ${repos.length === 0 |         ${repos.length === 0 | ||||||
|   | |||||||
| @@ -1,12 +1,11 @@ | |||||||
| import "@material/mwc-button"; |  | ||||||
| import "@material/mwc-list/mwc-list-item"; |  | ||||||
| import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit"; | import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit"; | ||||||
| import { css, html, LitElement } from "lit"; | import { css, html, LitElement, nothing } from "lit"; | ||||||
| import { customElement, property, state } from "lit/decorators"; | import { customElement, property, state } from "lit/decorators"; | ||||||
| import { stopPropagation } from "../../../../src/common/dom/stop_propagation"; | import { stopPropagation } from "../../../../src/common/dom/stop_propagation"; | ||||||
| import "../../../../src/components/buttons/ha-progress-button"; | import "../../../../src/components/buttons/ha-progress-button"; | ||||||
| import "../../../../src/components/ha-alert"; | import "../../../../src/components/ha-alert"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
|  | import "../../../../src/components/ha-list-item"; | ||||||
| import "../../../../src/components/ha-select"; | import "../../../../src/components/ha-select"; | ||||||
| import type { | import type { | ||||||
|   HassioAddonDetails, |   HassioAddonDetails, | ||||||
| @@ -29,6 +28,8 @@ class HassioAddonAudio extends LitElement { | |||||||
|  |  | ||||||
|   @property({ attribute: false }) public addon!: HassioAddonDetails; |   @property({ attribute: false }) public addon!: HassioAddonDetails; | ||||||
|  |  | ||||||
|  |   @property({ type: Boolean }) public disabled = false; | ||||||
|  |  | ||||||
|   @state() private _error?: string; |   @state() private _error?: string; | ||||||
|  |  | ||||||
|   @state() private _inputDevices?: HassioHardwareAudioDevice[]; |   @state() private _inputDevices?: HassioHardwareAudioDevice[]; | ||||||
| @@ -48,7 +49,7 @@ class HassioAddonAudio extends LitElement { | |||||||
|         <div class="card-content"> |         <div class="card-content"> | ||||||
|           ${this._error |           ${this._error | ||||||
|             ? html`<ha-alert alert-type="error">${this._error}</ha-alert>` |             ? html`<ha-alert alert-type="error">${this._error}</ha-alert>` | ||||||
|             : ""} |             : nothing} | ||||||
|           ${this._inputDevices && |           ${this._inputDevices && | ||||||
|           html`<ha-select |           html`<ha-select | ||||||
|             .label=${this.supervisor.localize( |             .label=${this.supervisor.localize( | ||||||
| @@ -59,12 +60,13 @@ class HassioAddonAudio extends LitElement { | |||||||
|             fixedMenuPosition |             fixedMenuPosition | ||||||
|             naturalMenuWidth |             naturalMenuWidth | ||||||
|             .value=${this._selectedInput!} |             .value=${this._selectedInput!} | ||||||
|  |             .disabled=${this.disabled} | ||||||
|           > |           > | ||||||
|             ${this._inputDevices.map( |             ${this._inputDevices.map( | ||||||
|               (item) => html` |               (item) => html` | ||||||
|                 <mwc-list-item .value=${item.device || ""}> |                 <ha-list-item .value=${item.device || ""}> | ||||||
|                   ${item.name} |                   ${item.name} | ||||||
|                 </mwc-list-item> |                 </ha-list-item> | ||||||
|               ` |               ` | ||||||
|             )} |             )} | ||||||
|           </ha-select>`} |           </ha-select>`} | ||||||
| @@ -78,18 +80,22 @@ class HassioAddonAudio extends LitElement { | |||||||
|             fixedMenuPosition |             fixedMenuPosition | ||||||
|             naturalMenuWidth |             naturalMenuWidth | ||||||
|             .value=${this._selectedOutput!} |             .value=${this._selectedOutput!} | ||||||
|  |             .disabled=${this.disabled} | ||||||
|           > |           > | ||||||
|             ${this._outputDevices.map( |             ${this._outputDevices.map( | ||||||
|               (item) => html` |               (item) => html` | ||||||
|                 <mwc-list-item .value=${item.device || ""} |                 <ha-list-item .value=${item.device || ""} | ||||||
|                   >${item.name}</mwc-list-item |                   >${item.name}</ha-list-item | ||||||
|                 > |                 > | ||||||
|               ` |               ` | ||||||
|             )} |             )} | ||||||
|           </ha-select>`} |           </ha-select>`} | ||||||
|         </div> |         </div> | ||||||
|         <div class="card-actions"> |         <div class="card-actions"> | ||||||
|           <ha-progress-button @click=${this._saveSettings}> |           <ha-progress-button | ||||||
|  |             .disabled=${this.disabled} | ||||||
|  |             @click=${this._saveSettings} | ||||||
|  |           > | ||||||
|             ${this.supervisor.localize("common.save")} |             ${this.supervisor.localize("common.save")} | ||||||
|           </ha-progress-button> |           </ha-progress-button> | ||||||
|         </div> |         </div> | ||||||
| @@ -171,6 +177,10 @@ class HassioAddonAudio extends LitElement { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   private async _saveSettings(ev: CustomEvent): Promise<void> { |   private async _saveSettings(ev: CustomEvent): Promise<void> { | ||||||
|  |     if (this.disabled) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const button = ev.currentTarget as any; |     const button = ev.currentTarget as any; | ||||||
|     button.progress = true; |     button.progress = true; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import type { CSSResultGroup, TemplateResult } from "lit"; | import type { CSSResultGroup, TemplateResult } from "lit"; | ||||||
| import { css, html, LitElement } from "lit"; | import { css, html, LitElement, nothing } from "lit"; | ||||||
| import { customElement, property } from "lit/decorators"; | import { customElement, property } from "lit/decorators"; | ||||||
| import "../../../../src/components/ha-spinner"; | import "../../../../src/components/ha-spinner"; | ||||||
| import type { HassioAddonDetails } from "../../../../src/data/hassio/addon"; | import type { HassioAddonDetails } from "../../../../src/data/hassio/addon"; | ||||||
| @@ -7,6 +7,7 @@ import type { Supervisor } from "../../../../src/data/supervisor/supervisor"; | |||||||
| import { haStyle } from "../../../../src/resources/styles"; | import { haStyle } from "../../../../src/resources/styles"; | ||||||
| import type { HomeAssistant } from "../../../../src/types"; | import type { HomeAssistant } from "../../../../src/types"; | ||||||
| import { hassioStyle } from "../../resources/hassio-style"; | import { hassioStyle } from "../../resources/hassio-style"; | ||||||
|  | import "../info/hassio-addon-system-managed"; | ||||||
| import "./hassio-addon-audio"; | import "./hassio-addon-audio"; | ||||||
| import "./hassio-addon-config"; | import "./hassio-addon-config"; | ||||||
| import "./hassio-addon-network"; | import "./hassio-addon-network"; | ||||||
| @@ -19,6 +20,11 @@ class HassioAddonConfigDashboard extends LitElement { | |||||||
|  |  | ||||||
|   @property({ attribute: false }) public addon?: HassioAddonDetails; |   @property({ attribute: false }) public addon?: HassioAddonDetails; | ||||||
|  |  | ||||||
|  |   @property({ type: Boolean }) public narrow = false; | ||||||
|  |  | ||||||
|  |   @property({ type: Boolean, attribute: "control-enabled" }) | ||||||
|  |   public controlEnabled = false; | ||||||
|  |  | ||||||
|   protected render(): TemplateResult { |   protected render(): TemplateResult { | ||||||
|     if (!this.addon) { |     if (!this.addon) { | ||||||
|       return html`<ha-spinner></ha-spinner>`; |       return html`<ha-spinner></ha-spinner>`; | ||||||
| @@ -29,6 +35,16 @@ class HassioAddonConfigDashboard extends LitElement { | |||||||
|  |  | ||||||
|     return html` |     return html` | ||||||
|       <div class="content"> |       <div class="content"> | ||||||
|  |         ${this.addon.system_managed && | ||||||
|  |         (hasConfiguration || this.addon.network || this.addon.audio) | ||||||
|  |           ? html` | ||||||
|  |               <hassio-addon-system-managed | ||||||
|  |                 .supervisor=${this.supervisor} | ||||||
|  |                 .narrow=${this.narrow} | ||||||
|  |                 .hideButton=${this.controlEnabled} | ||||||
|  |               ></hassio-addon-system-managed> | ||||||
|  |             ` | ||||||
|  |           : nothing} | ||||||
|         ${hasConfiguration || this.addon.network || this.addon.audio |         ${hasConfiguration || this.addon.network || this.addon.audio | ||||||
|           ? html` |           ? html` | ||||||
|               ${hasConfiguration |               ${hasConfiguration | ||||||
| @@ -37,27 +53,33 @@ class HassioAddonConfigDashboard extends LitElement { | |||||||
|                       .hass=${this.hass} |                       .hass=${this.hass} | ||||||
|                       .addon=${this.addon} |                       .addon=${this.addon} | ||||||
|                       .supervisor=${this.supervisor} |                       .supervisor=${this.supervisor} | ||||||
|  |                       .disabled=${this.addon.system_managed && | ||||||
|  |                       !this.controlEnabled} | ||||||
|                     ></hassio-addon-config> |                     ></hassio-addon-config> | ||||||
|                   ` |                   ` | ||||||
|                 : ""} |                 : nothing} | ||||||
|               ${this.addon.network |               ${this.addon.network | ||||||
|                 ? html` |                 ? html` | ||||||
|                     <hassio-addon-network |                     <hassio-addon-network | ||||||
|                       .hass=${this.hass} |                       .hass=${this.hass} | ||||||
|                       .addon=${this.addon} |                       .addon=${this.addon} | ||||||
|                       .supervisor=${this.supervisor} |                       .supervisor=${this.supervisor} | ||||||
|  |                       .disabled=${this.addon.system_managed && | ||||||
|  |                       !this.controlEnabled} | ||||||
|                     ></hassio-addon-network> |                     ></hassio-addon-network> | ||||||
|                   ` |                   ` | ||||||
|                 : ""} |                 : nothing} | ||||||
|               ${this.addon.audio |               ${this.addon.audio | ||||||
|                 ? html` |                 ? html` | ||||||
|                     <hassio-addon-audio |                     <hassio-addon-audio | ||||||
|                       .hass=${this.hass} |                       .hass=${this.hass} | ||||||
|                       .addon=${this.addon} |                       .addon=${this.addon} | ||||||
|                       .supervisor=${this.supervisor} |                       .supervisor=${this.supervisor} | ||||||
|  |                       .disabled=${this.addon.system_managed && | ||||||
|  |                       !this.controlEnabled} | ||||||
|                     ></hassio-addon-audio> |                     ></hassio-addon-audio> | ||||||
|                   ` |                   ` | ||||||
|                 : ""} |                 : nothing} | ||||||
|             ` |             ` | ||||||
|           : this.supervisor.localize("addon.configuration.no_configuration")} |           : this.supervisor.localize("addon.configuration.no_configuration")} | ||||||
|       </div> |       </div> | ||||||
|   | |||||||
| @@ -1,6 +1,4 @@ | |||||||
| import "@material/mwc-button"; |  | ||||||
| import type { ActionDetail } from "@material/mwc-list"; | import type { ActionDetail } from "@material/mwc-list"; | ||||||
| import "@material/mwc-list/mwc-list-item"; |  | ||||||
| import { mdiDotsVertical } from "@mdi/js"; | import { mdiDotsVertical } from "@mdi/js"; | ||||||
| import { DEFAULT_SCHEMA, Type } from "js-yaml"; | import { DEFAULT_SCHEMA, Type } from "js-yaml"; | ||||||
| import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit"; | import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit"; | ||||||
| @@ -16,6 +14,7 @@ import "../../../../src/components/ha-form/ha-form"; | |||||||
| import type { HaFormSchema } from "../../../../src/components/ha-form/types"; | import type { HaFormSchema } from "../../../../src/components/ha-form/types"; | ||||||
| import "../../../../src/components/ha-formfield"; | import "../../../../src/components/ha-formfield"; | ||||||
| import "../../../../src/components/ha-icon-button"; | import "../../../../src/components/ha-icon-button"; | ||||||
|  | import "../../../../src/components/ha-list-item"; | ||||||
| import "../../../../src/components/ha-switch"; | import "../../../../src/components/ha-switch"; | ||||||
| import "../../../../src/components/ha-yaml-editor"; | import "../../../../src/components/ha-yaml-editor"; | ||||||
| import type { HaYamlEditor } from "../../../../src/components/ha-yaml-editor"; | import type { HaYamlEditor } from "../../../../src/components/ha-yaml-editor"; | ||||||
| @@ -61,6 +60,8 @@ class HassioAddonConfig extends LitElement { | |||||||
|  |  | ||||||
|   @property({ attribute: false }) public supervisor!: Supervisor; |   @property({ attribute: false }) public supervisor!: Supervisor; | ||||||
|  |  | ||||||
|  |   @property({ type: Boolean }) public disabled = false; | ||||||
|  |  | ||||||
|   @state() private _configHasChanged = false; |   @state() private _configHasChanged = false; | ||||||
|  |  | ||||||
|   @state() private _valid = true; |   @state() private _valid = true; | ||||||
| @@ -176,7 +177,7 @@ class HassioAddonConfig extends LitElement { | |||||||
|                 .path=${mdiDotsVertical} |                 .path=${mdiDotsVertical} | ||||||
|                 slot="trigger" |                 slot="trigger" | ||||||
|               ></ha-icon-button> |               ></ha-icon-button> | ||||||
|               <mwc-list-item .disabled=${!this._canShowSchema}> |               <ha-list-item .disabled=${!this._canShowSchema || this.disabled}> | ||||||
|                 ${this._yamlMode |                 ${this._yamlMode | ||||||
|                   ? this.supervisor.localize( |                   ? this.supervisor.localize( | ||||||
|                       "addon.configuration.options.edit_in_ui" |                       "addon.configuration.options.edit_in_ui" | ||||||
| @@ -184,10 +185,13 @@ class HassioAddonConfig extends LitElement { | |||||||
|                   : this.supervisor.localize( |                   : this.supervisor.localize( | ||||||
|                       "addon.configuration.options.edit_in_yaml" |                       "addon.configuration.options.edit_in_yaml" | ||||||
|                     )} |                     )} | ||||||
|               </mwc-list-item> |               </ha-list-item> | ||||||
|               <mwc-list-item class="warning"> |               <ha-list-item | ||||||
|  |                 class=${!this.disabled ? "warning" : ""} | ||||||
|  |                 .disabled=${this.disabled} | ||||||
|  |               > | ||||||
|                 ${this.supervisor.localize("common.reset_defaults")} |                 ${this.supervisor.localize("common.reset_defaults")} | ||||||
|               </mwc-list-item> |               </ha-list-item> | ||||||
|             </ha-button-menu> |             </ha-button-menu> | ||||||
|           </div> |           </div> | ||||||
|         </div> |         </div> | ||||||
| @@ -195,6 +199,7 @@ class HassioAddonConfig extends LitElement { | |||||||
|         <div class="card-content"> |         <div class="card-content"> | ||||||
|           ${showForm |           ${showForm | ||||||
|             ? html`<ha-form |             ? html`<ha-form | ||||||
|  |                 .disabled=${this.disabled} | ||||||
|                 .data=${this._options!} |                 .data=${this._options!} | ||||||
|                 @value-changed=${this._configChanged} |                 @value-changed=${this._configChanged} | ||||||
|                 .computeLabel=${this.computeLabel} |                 .computeLabel=${this.computeLabel} | ||||||
| @@ -244,7 +249,9 @@ class HassioAddonConfig extends LitElement { | |||||||
|         <div class="card-actions right"> |         <div class="card-actions right"> | ||||||
|           <ha-progress-button |           <ha-progress-button | ||||||
|             @click=${this._saveTapped} |             @click=${this._saveTapped} | ||||||
|             .disabled=${!this._configHasChanged || !this._valid} |             .disabled=${this.disabled || | ||||||
|  |             !this._configHasChanged || | ||||||
|  |             !this._valid} | ||||||
|           > |           > | ||||||
|             ${this.supervisor.localize("common.save")} |             ${this.supervisor.localize("common.save")} | ||||||
|           </ha-progress-button> |           </ha-progress-button> | ||||||
| @@ -346,6 +353,10 @@ class HassioAddonConfig extends LitElement { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   private async _saveTapped(ev: CustomEvent): Promise<void> { |   private async _saveTapped(ev: CustomEvent): Promise<void> { | ||||||
|  |     if (this.disabled || !this._configHasChanged || !this._valid) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const button = ev.currentTarget as any; |     const button = ev.currentTarget as any; | ||||||
|     const options: Record<string, unknown> = this._yamlMode |     const options: Record<string, unknown> = this._yamlMode | ||||||
|       ? this._editor?.value |       ? this._editor?.value | ||||||
| @@ -407,7 +418,7 @@ class HassioAddonConfig extends LitElement { | |||||||
|           z-index: 3; |           z-index: 3; | ||||||
|           --mdc-theme-text-primary-on-background: var(--primary-text-color); |           --mdc-theme-text-primary-on-background: var(--primary-text-color); | ||||||
|         } |         } | ||||||
|         mwc-list-item[disabled] { |         ha-list-item[disabled] { | ||||||
|           --mdc-theme-text-primary-on-background: var(--disabled-text-color); |           --mdc-theme-text-primary-on-background: var(--disabled-text-color); | ||||||
|         } |         } | ||||||
|         .header { |         .header { | ||||||
| @@ -417,13 +428,13 @@ class HassioAddonConfig extends LitElement { | |||||||
|         .header h2 { |         .header h2 { | ||||||
|           color: var(--ha-card-header-color, var(--primary-text-color)); |           color: var(--ha-card-header-color, var(--primary-text-color)); | ||||||
|           font-family: var(--ha-card-header-font-family, inherit); |           font-family: var(--ha-card-header-font-family, inherit); | ||||||
|           font-size: var(--ha-card-header-font-size, 24px); |           font-size: var(--ha-card-header-font-size, var(--ha-font-size-2xl)); | ||||||
|           letter-spacing: -0.012em; |           letter-spacing: -0.012em; | ||||||
|           line-height: 48px; |           line-height: var(--ha-line-height-expanded); | ||||||
|           padding: 12px 16px 16px; |           padding: 12px 16px 16px; | ||||||
|           display: block; |           display: block; | ||||||
|           margin-block: 0px; |           margin-block: 0px; | ||||||
|           font-weight: normal; |           font-weight: var(--ha-font-weight-normal); | ||||||
|         } |         } | ||||||
|         .card-actions.right { |         .card-actions.right { | ||||||
|           justify-content: flex-end; |           justify-content: flex-end; | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ import { fireEvent } from "../../../../src/common/dom/fire_event"; | |||||||
| import "../../../../src/components/buttons/ha-progress-button"; | import "../../../../src/components/buttons/ha-progress-button"; | ||||||
| import "../../../../src/components/ha-alert"; | import "../../../../src/components/ha-alert"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
|  | import "../../../../src/components/ha-formfield"; | ||||||
| import "../../../../src/components/ha-form/ha-form"; | import "../../../../src/components/ha-form/ha-form"; | ||||||
| import type { HaFormSchema } from "../../../../src/components/ha-form/types"; | import type { HaFormSchema } from "../../../../src/components/ha-form/types"; | ||||||
| import type { | import type { | ||||||
| @@ -28,6 +29,8 @@ class HassioAddonNetwork extends LitElement { | |||||||
|  |  | ||||||
|   @property({ attribute: false }) public addon!: HassioAddonDetails; |   @property({ attribute: false }) public addon!: HassioAddonDetails; | ||||||
|  |  | ||||||
|  |   @property({ type: Boolean }) public disabled = false; | ||||||
|  |  | ||||||
|   @state() private _showOptional = false; |   @state() private _showOptional = false; | ||||||
|  |  | ||||||
|   @state() private _configHasChanged = false; |   @state() private _configHasChanged = false; | ||||||
| @@ -65,9 +68,10 @@ class HassioAddonNetwork extends LitElement { | |||||||
|           </p> |           </p> | ||||||
|           ${this._error |           ${this._error | ||||||
|             ? html`<ha-alert alert-type="error">${this._error}</ha-alert>` |             ? html`<ha-alert alert-type="error">${this._error}</ha-alert>` | ||||||
|             : ""} |             : nothing} | ||||||
|  |  | ||||||
|           <ha-form |           <ha-form | ||||||
|  |             .disabled=${this.disabled} | ||||||
|             .data=${this._config} |             .data=${this._config} | ||||||
|             @value-changed=${this._configChanged} |             @value-changed=${this._configChanged} | ||||||
|             .computeLabel=${this._computeLabel} |             .computeLabel=${this._computeLabel} | ||||||
| @@ -92,14 +96,18 @@ class HassioAddonNetwork extends LitElement { | |||||||
|               > |               > | ||||||
|               </ha-switch> |               </ha-switch> | ||||||
|             </ha-formfield>` |             </ha-formfield>` | ||||||
|           : ""} |           : nothing} | ||||||
|         <div class="card-actions"> |         <div class="card-actions"> | ||||||
|           <ha-progress-button class="warning" @click=${this._resetTapped}> |           <ha-progress-button | ||||||
|  |             class="warning" | ||||||
|  |             .disabled=${this.disabled} | ||||||
|  |             @click=${this._resetTapped} | ||||||
|  |           > | ||||||
|             ${this.supervisor.localize("common.reset_defaults")} |             ${this.supervisor.localize("common.reset_defaults")} | ||||||
|           </ha-progress-button> |           </ha-progress-button> | ||||||
|           <ha-progress-button |           <ha-progress-button | ||||||
|             @click=${this._saveTapped} |             @click=${this._saveTapped} | ||||||
|             .disabled=${!this._configHasChanged} |             .disabled=${!this._configHasChanged || this.disabled} | ||||||
|           > |           > | ||||||
|             ${this.supervisor.localize("common.save")} |             ${this.supervisor.localize("common.save")} | ||||||
|           </ha-progress-button> |           </ha-progress-button> | ||||||
| @@ -155,6 +163,10 @@ class HassioAddonNetwork extends LitElement { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   private async _resetTapped(ev: CustomEvent): Promise<void> { |   private async _resetTapped(ev: CustomEvent): Promise<void> { | ||||||
|  |     if (this.disabled) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const button = ev.currentTarget as any; |     const button = ev.currentTarget as any; | ||||||
|     const data: HassioAddonSetOptionParams = { |     const data: HassioAddonSetOptionParams = { | ||||||
|       network: null, |       network: null, | ||||||
| @@ -186,6 +198,10 @@ class HassioAddonNetwork extends LitElement { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   private async _saveTapped(ev: CustomEvent): Promise<void> { |   private async _saveTapped(ev: CustomEvent): Promise<void> { | ||||||
|  |     if (!this._configHasChanged || this.disabled) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const button = ev.currentTarget as any; |     const button = ev.currentTarget as any; | ||||||
|  |  | ||||||
|     this._error = undefined; |     this._error = undefined; | ||||||
|   | |||||||
| @@ -52,6 +52,9 @@ class HassioAddonDashboard extends LitElement { | |||||||
|  |  | ||||||
|   @property({ type: Boolean }) public narrow = false; |   @property({ type: Boolean }) public narrow = false; | ||||||
|  |  | ||||||
|  |   @state() | ||||||
|  |   private _controlEnabled = false; | ||||||
|  |  | ||||||
|   @state() private _error?: string; |   @state() private _error?: string; | ||||||
|  |  | ||||||
|   private _backPath = new URLSearchParams(window.parent.location.search).get( |   private _backPath = new URLSearchParams(window.parent.location.search).get( | ||||||
| @@ -134,11 +137,17 @@ class HassioAddonDashboard extends LitElement { | |||||||
|           .hass=${this.hass} |           .hass=${this.hass} | ||||||
|           .supervisor=${this.supervisor} |           .supervisor=${this.supervisor} | ||||||
|           .addon=${this.addon} |           .addon=${this.addon} | ||||||
|  |           .controlEnabled=${this._controlEnabled} | ||||||
|  |           @system-managed-take-control=${this._enableControl} | ||||||
|         ></hassio-addon-router> |         ></hassio-addon-router> | ||||||
|       </hass-tabs-subpage> |       </hass-tabs-subpage> | ||||||
|     `; |     `; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   private _enableControl() { | ||||||
|  |     this._controlEnabled = true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   static get styles(): CSSResultGroup { |   static get styles(): CSSResultGroup { | ||||||
|     return [ |     return [ | ||||||
|       haStyle, |       haStyle, | ||||||
|   | |||||||
| @@ -23,6 +23,9 @@ class HassioAddonRouter extends HassRouterPage { | |||||||
|     | HassioAddonDetails |     | HassioAddonDetails | ||||||
|     | StoreAddonDetails; |     | StoreAddonDetails; | ||||||
|  |  | ||||||
|  |   @property({ type: Boolean, attribute: "control-enabled" }) | ||||||
|  |   public controlEnabled = false; | ||||||
|  |  | ||||||
|   protected routerOptions: RouterOptions = { |   protected routerOptions: RouterOptions = { | ||||||
|     defaultPage: "info", |     defaultPage: "info", | ||||||
|     showLoading: true, |     showLoading: true, | ||||||
| @@ -48,6 +51,7 @@ class HassioAddonRouter extends HassRouterPage { | |||||||
|     el.supervisor = this.supervisor; |     el.supervisor = this.supervisor; | ||||||
|     el.addon = this.addon; |     el.addon = this.addon; | ||||||
|     el.narrow = this.narrow; |     el.narrow = this.narrow; | ||||||
|  |     el.controlEnabled = this.controlEnabled; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,6 +21,9 @@ class HassioAddonInfoDashboard extends LitElement { | |||||||
|  |  | ||||||
|   @property({ attribute: false }) public addon?: HassioAddonDetails; |   @property({ attribute: false }) public addon?: HassioAddonDetails; | ||||||
|  |  | ||||||
|  |   @property({ type: Boolean, attribute: "control-enabled" }) | ||||||
|  |   public controlEnabled = false; | ||||||
|  |  | ||||||
|   protected render(): TemplateResult { |   protected render(): TemplateResult { | ||||||
|     if (!this.addon) { |     if (!this.addon) { | ||||||
|       return html`<ha-spinner></ha-spinner>`; |       return html`<ha-spinner></ha-spinner>`; | ||||||
| @@ -34,6 +37,7 @@ class HassioAddonInfoDashboard extends LitElement { | |||||||
|           .hass=${this.hass} |           .hass=${this.hass} | ||||||
|           .supervisor=${this.supervisor} |           .supervisor=${this.supervisor} | ||||||
|           .addon=${this.addon} |           .addon=${this.addon} | ||||||
|  |           .controlEnabled=${this.controlEnabled} | ||||||
|         ></hassio-addon-info> |         ></hassio-addon-info> | ||||||
|       </div> |       </div> | ||||||
|     `; |     `; | ||||||
|   | |||||||
| @@ -1,8 +1,6 @@ | |||||||
| import "@material/mwc-button"; |  | ||||||
| import { | import { | ||||||
|   mdiCheckCircle, |   mdiCheckCircle, | ||||||
|   mdiChip, |   mdiChip, | ||||||
|   mdiPlayCircle, |  | ||||||
|   mdiCircleOffOutline, |   mdiCircleOffOutline, | ||||||
|   mdiCursorDefaultClickOutline, |   mdiCursorDefaultClickOutline, | ||||||
|   mdiDocker, |   mdiDocker, | ||||||
| @@ -19,27 +17,30 @@ import { | |||||||
|   mdiNumeric6, |   mdiNumeric6, | ||||||
|   mdiNumeric7, |   mdiNumeric7, | ||||||
|   mdiNumeric8, |   mdiNumeric8, | ||||||
|  |   mdiPlayCircle, | ||||||
|   mdiPound, |   mdiPound, | ||||||
|   mdiShield, |   mdiShield, | ||||||
| } from "@mdi/js"; | } from "@mdi/js"; | ||||||
| import type { CSSResultGroup, TemplateResult } from "lit"; | import type { CSSResultGroup, TemplateResult } from "lit"; | ||||||
| import { LitElement, css, html } from "lit"; | import { LitElement, css, html, nothing } from "lit"; | ||||||
| import { customElement, property, state } from "lit/decorators"; | import { customElement, property, state } from "lit/decorators"; | ||||||
| import { classMap } from "lit/directives/class-map"; | import { classMap } from "lit/directives/class-map"; | ||||||
| import memoizeOne from "memoize-one"; | import memoizeOne from "memoize-one"; | ||||||
| import { atLeastVersion } from "../../../../src/common/config/version"; | import { atLeastVersion } from "../../../../src/common/config/version"; | ||||||
| import { fireEvent } from "../../../../src/common/dom/fire_event"; | import { fireEvent } from "../../../../src/common/dom/fire_event"; | ||||||
| import { navigate } from "../../../../src/common/navigate"; | import { navigate } from "../../../../src/common/navigate"; | ||||||
|  | import { capitalizeFirstLetter } from "../../../../src/common/string/capitalize-first-letter"; | ||||||
| import "../../../../src/components/buttons/ha-progress-button"; | import "../../../../src/components/buttons/ha-progress-button"; | ||||||
| import "../../../../src/components/ha-alert"; |  | ||||||
| import "../../../../src/components/ha-card"; |  | ||||||
| import "../../../../src/components/chips/ha-chip-set"; |  | ||||||
| import "../../../../src/components/chips/ha-assist-chip"; | import "../../../../src/components/chips/ha-assist-chip"; | ||||||
|  | import "../../../../src/components/chips/ha-chip-set"; | ||||||
|  | import "../../../../src/components/ha-alert"; | ||||||
|  | import "../../../../src/components/ha-button"; | ||||||
|  | import "../../../../src/components/ha-card"; | ||||||
|  | import "../../../../src/components/ha-formfield"; | ||||||
| import "../../../../src/components/ha-markdown"; | import "../../../../src/components/ha-markdown"; | ||||||
| import "../../../../src/components/ha-settings-row"; | import "../../../../src/components/ha-settings-row"; | ||||||
| import "../../../../src/components/ha-svg-icon"; | import "../../../../src/components/ha-svg-icon"; | ||||||
| import "../../../../src/components/ha-switch"; | import "../../../../src/components/ha-switch"; | ||||||
| import "../../../../src/components/ha-formfield"; |  | ||||||
| import type { HaSwitch } from "../../../../src/components/ha-switch"; | import type { HaSwitch } from "../../../../src/components/ha-switch"; | ||||||
| import type { | import type { | ||||||
|   AddonCapability, |   AddonCapability, | ||||||
| @@ -81,10 +82,11 @@ import { bytesToString } from "../../../../src/util/bytes-to-string"; | |||||||
| import "../../components/hassio-card-content"; | import "../../components/hassio-card-content"; | ||||||
| import "../../components/supervisor-metric"; | import "../../components/supervisor-metric"; | ||||||
| import { showHassioMarkdownDialog } from "../../dialogs/markdown/show-dialog-hassio-markdown"; | import { showHassioMarkdownDialog } from "../../dialogs/markdown/show-dialog-hassio-markdown"; | ||||||
|  | import { showSystemManagedDialog } from "../../dialogs/system-managed/show-dialog-system-managed"; | ||||||
| import { hassioStyle } from "../../resources/hassio-style"; | import { hassioStyle } from "../../resources/hassio-style"; | ||||||
| import "../../update-available/update-available-card"; | import "../../update-available/update-available-card"; | ||||||
| import { addonArchIsSupported, extractChangelog } from "../../util/addon"; | import { addonArchIsSupported, extractChangelog } from "../../util/addon"; | ||||||
| import { capitalizeFirstLetter } from "../../../../src/common/string/capitalize-first-letter"; | import "./hassio-addon-system-managed"; | ||||||
|  |  | ||||||
| const STAGE_ICON = { | const STAGE_ICON = { | ||||||
|   stable: mdiCheckCircle, |   stable: mdiCheckCircle, | ||||||
| @@ -117,6 +119,9 @@ class HassioAddonInfo extends LitElement { | |||||||
|  |  | ||||||
|   @property({ attribute: false }) public supervisor!: Supervisor; |   @property({ attribute: false }) public supervisor!: Supervisor; | ||||||
|  |  | ||||||
|  |   @property({ type: Boolean, attribute: "control-enabled" }) | ||||||
|  |   public controlEnabled = false; | ||||||
|  |  | ||||||
|   @state() private _metrics?: HassioStats; |   @state() private _metrics?: HassioStats; | ||||||
|  |  | ||||||
|   @state() private _error?: string; |   @state() private _error?: string; | ||||||
| @@ -155,6 +160,9 @@ class HassioAddonInfo extends LitElement { | |||||||
|         )}`, |         )}`, | ||||||
|       }, |       }, | ||||||
|     ]; |     ]; | ||||||
|  |  | ||||||
|  |     const systemManaged = this._isSystemManaged(this.addon); | ||||||
|  |  | ||||||
|     return html` |     return html` | ||||||
|       ${this.addon.update_available |       ${this.addon.update_available | ||||||
|         ? html` |         ? html` | ||||||
| @@ -166,7 +174,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|               @update-complete=${this._updateComplete} |               @update-complete=${this._updateComplete} | ||||||
|             ></update-available-card> |             ></update-available-card> | ||||||
|           ` |           ` | ||||||
|         : ""} |         : nothing} | ||||||
|       ${"protected" in this.addon && !this.addon.protected |       ${"protected" in this.addon && !this.addon.protected | ||||||
|         ? html` |         ? html` | ||||||
|             <ha-alert |             <ha-alert | ||||||
| @@ -178,22 +186,31 @@ class HassioAddonInfo extends LitElement { | |||||||
|               ${this.supervisor.localize( |               ${this.supervisor.localize( | ||||||
|                 "addon.dashboard.protection_mode.content" |                 "addon.dashboard.protection_mode.content" | ||||||
|               )} |               )} | ||||||
|               <mwc-button |               <ha-button | ||||||
|                 slot="action" |                 slot="action" | ||||||
|                 .label=${this.supervisor.localize( |                 .label=${this.supervisor.localize( | ||||||
|                   "addon.dashboard.protection_mode.enable" |                   "addon.dashboard.protection_mode.enable" | ||||||
|                 )} |                 )} | ||||||
|                 @click=${this._protectionToggled} |                 @click=${this._protectionToggled} | ||||||
|               > |               > | ||||||
|               </mwc-button> |               </ha-button> | ||||||
|             </ha-alert> |             </ha-alert> | ||||||
|           ` |           ` | ||||||
|         : ""} |         : nothing} | ||||||
|  |       ${systemManaged | ||||||
|  |         ? html` | ||||||
|  |             <hassio-addon-system-managed | ||||||
|  |               .supervisor=${this.supervisor} | ||||||
|  |               .narrow=${this.narrow} | ||||||
|  |               .hideButton=${this.controlEnabled} | ||||||
|  |             ></hassio-addon-system-managed> | ||||||
|  |           ` | ||||||
|  |         : nothing} | ||||||
|  |  | ||||||
|       <ha-card outlined> |       <ha-card outlined> | ||||||
|         <div class="card-content"> |         <div class="card-content"> | ||||||
|           <div class="addon-header"> |           <div class="addon-header"> | ||||||
|             ${!this.narrow ? this.addon.name : ""} |             ${!this.narrow ? this.addon.name : nothing} | ||||||
|             <div class="addon-version light-color"> |             <div class="addon-version light-color"> | ||||||
|               ${this.addon.version |               ${this.addon.version | ||||||
|                 ? html` |                 ? html` | ||||||
| @@ -266,7 +283,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|                     </ha-svg-icon> |                     </ha-svg-icon> | ||||||
|                   </ha-assist-chip> |                   </ha-assist-chip> | ||||||
|                 ` |                 ` | ||||||
|               : ""} |               : nothing} | ||||||
|  |  | ||||||
|             <ha-assist-chip |             <ha-assist-chip | ||||||
|               filled |               filled | ||||||
| @@ -301,7 +318,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|                     <ha-svg-icon slot="icon" .path=${mdiNetwork}> </ha-svg-icon> |                     <ha-svg-icon slot="icon" .path=${mdiNetwork}> </ha-svg-icon> | ||||||
|                   </ha-assist-chip> |                   </ha-assist-chip> | ||||||
|                 ` |                 ` | ||||||
|               : ""} |               : nothing} | ||||||
|             ${this.addon.full_access |             ${this.addon.full_access | ||||||
|               ? html` |               ? html` | ||||||
|                   <ha-assist-chip |                   <ha-assist-chip | ||||||
| @@ -317,7 +334,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|                     <ha-svg-icon slot="icon" .path=${mdiChip}></ha-svg-icon> |                     <ha-svg-icon slot="icon" .path=${mdiChip}></ha-svg-icon> | ||||||
|                   </ha-assist-chip> |                   </ha-assist-chip> | ||||||
|                 ` |                 ` | ||||||
|               : ""} |               : nothing} | ||||||
|             ${this.addon.homeassistant_api |             ${this.addon.homeassistant_api | ||||||
|               ? html` |               ? html` | ||||||
|                   <ha-assist-chip |                   <ha-assist-chip | ||||||
| @@ -336,7 +353,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|                     ></ha-svg-icon> |                     ></ha-svg-icon> | ||||||
|                   </ha-assist-chip> |                   </ha-assist-chip> | ||||||
|                 ` |                 ` | ||||||
|               : ""} |               : nothing} | ||||||
|             ${this._computeHassioApi |             ${this._computeHassioApi | ||||||
|               ? html` |               ? html` | ||||||
|                   <ha-assist-chip |                   <ha-assist-chip | ||||||
| @@ -355,7 +372,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|                     ></ha-svg-icon> |                     ></ha-svg-icon> | ||||||
|                   </ha-assist-chip> |                   </ha-assist-chip> | ||||||
|                 ` |                 ` | ||||||
|               : ""} |               : nothing} | ||||||
|             ${this.addon.docker_api |             ${this.addon.docker_api | ||||||
|               ? html` |               ? html` | ||||||
|                   <ha-assist-chip |                   <ha-assist-chip | ||||||
| @@ -371,7 +388,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|                     <ha-svg-icon slot="icon" .path=${mdiDocker}></ha-svg-icon> |                     <ha-svg-icon slot="icon" .path=${mdiDocker}></ha-svg-icon> | ||||||
|                   </ha-assist-chip> |                   </ha-assist-chip> | ||||||
|                 ` |                 ` | ||||||
|               : ""} |               : nothing} | ||||||
|             ${this.addon.host_pid |             ${this.addon.host_pid | ||||||
|               ? html` |               ? html` | ||||||
|                   <ha-assist-chip |                   <ha-assist-chip | ||||||
| @@ -387,7 +404,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|                     <ha-svg-icon slot="icon" .path=${mdiPound}></ha-svg-icon> |                     <ha-svg-icon slot="icon" .path=${mdiPound}></ha-svg-icon> | ||||||
|                   </ha-assist-chip> |                   </ha-assist-chip> | ||||||
|                 ` |                 ` | ||||||
|               : ""} |               : nothing} | ||||||
|             ${this.addon.apparmor !== "default" |             ${this.addon.apparmor !== "default" | ||||||
|               ? html` |               ? html` | ||||||
|                   <ha-assist-chip |                   <ha-assist-chip | ||||||
| @@ -404,7 +421,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|                     <ha-svg-icon slot="icon" .path=${mdiShield}></ha-svg-icon> |                     <ha-svg-icon slot="icon" .path=${mdiShield}></ha-svg-icon> | ||||||
|                   </ha-assist-chip> |                   </ha-assist-chip> | ||||||
|                 ` |                 ` | ||||||
|               : ""} |               : nothing} | ||||||
|             ${this.addon.auth_api |             ${this.addon.auth_api | ||||||
|               ? html` |               ? html` | ||||||
|                   <ha-assist-chip |                   <ha-assist-chip | ||||||
| @@ -420,7 +437,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|                     <ha-svg-icon slot="icon" .path=${mdiKey}></ha-svg-icon> |                     <ha-svg-icon slot="icon" .path=${mdiKey}></ha-svg-icon> | ||||||
|                   </ha-assist-chip> |                   </ha-assist-chip> | ||||||
|                 ` |                 ` | ||||||
|               : ""} |               : nothing} | ||||||
|             ${this.addon.ingress |             ${this.addon.ingress | ||||||
|               ? html` |               ? html` | ||||||
|                   <ha-assist-chip |                   <ha-assist-chip | ||||||
| @@ -439,7 +456,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|                     ></ha-svg-icon> |                     ></ha-svg-icon> | ||||||
|                   </ha-assist-chip> |                   </ha-assist-chip> | ||||||
|                 ` |                 ` | ||||||
|               : ""} |               : nothing} | ||||||
|             ${this.addon.signed |             ${this.addon.signed | ||||||
|               ? html` |               ? html` | ||||||
|                   <ha-assist-chip |                   <ha-assist-chip | ||||||
| @@ -455,7 +472,24 @@ class HassioAddonInfo extends LitElement { | |||||||
|                     <ha-svg-icon slot="icon" .path=${mdiLinkLock}></ha-svg-icon> |                     <ha-svg-icon slot="icon" .path=${mdiLinkLock}></ha-svg-icon> | ||||||
|                   </ha-assist-chip> |                   </ha-assist-chip> | ||||||
|                 ` |                 ` | ||||||
|               : ""} |               : nothing} | ||||||
|  |             ${systemManaged | ||||||
|  |               ? html` | ||||||
|  |                   <ha-assist-chip | ||||||
|  |                     filled | ||||||
|  |                     @click=${this._showSystemManagedDialog} | ||||||
|  |                     id="system_managed" | ||||||
|  |                     .label=${capitalizeFirstLetter( | ||||||
|  |                       this.supervisor.localize("addon.system_managed.badge") | ||||||
|  |                     )} | ||||||
|  |                   > | ||||||
|  |                     <ha-svg-icon | ||||||
|  |                       slot="icon" | ||||||
|  |                       .path=${mdiHomeAssistant} | ||||||
|  |                     ></ha-svg-icon> | ||||||
|  |                   </ha-assist-chip> | ||||||
|  |                 ` | ||||||
|  |               : nothing} | ||||||
|           </ha-chip-set> |           </ha-chip-set> | ||||||
|  |  | ||||||
|           <div class="description light-color"> |           <div class="description light-color"> | ||||||
| @@ -479,7 +513,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|                       src="/api/hassio/addons/${this.addon.slug}/logo" |                       src="/api/hassio/addons/${this.addon.slug}/logo" | ||||||
|                     /> |                     /> | ||||||
|                   ` |                   ` | ||||||
|                 : ""} |                 : nothing} | ||||||
|               ${this.addon.version |               ${this.addon.version | ||||||
|                 ? html` |                 ? html` | ||||||
|                     <div |                     <div | ||||||
| @@ -500,6 +534,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|                           )} |                           )} | ||||||
|                         </span> |                         </span> | ||||||
|                         <ha-switch |                         <ha-switch | ||||||
|  |                           .disabled=${systemManaged && !this.controlEnabled} | ||||||
|                           @change=${this._startOnBootToggled} |                           @change=${this._startOnBootToggled} | ||||||
|                           .checked=${this.addon.boot === "auto"} |                           .checked=${this.addon.boot === "auto"} | ||||||
|                           haptic |                           haptic | ||||||
| @@ -520,13 +555,15 @@ class HassioAddonInfo extends LitElement { | |||||||
|                                 )} |                                 )} | ||||||
|                               </span> |                               </span> | ||||||
|                               <ha-switch |                               <ha-switch | ||||||
|  |                                 .disabled=${systemManaged && | ||||||
|  |                                 !this.controlEnabled} | ||||||
|                                 @change=${this._watchdogToggled} |                                 @change=${this._watchdogToggled} | ||||||
|                                 .checked=${this.addon.watchdog} |                                 .checked=${this.addon.watchdog || false} | ||||||
|                                 haptic |                                 haptic | ||||||
|                               ></ha-switch> |                               ></ha-switch> | ||||||
|                             </ha-settings-row> |                             </ha-settings-row> | ||||||
|                           ` |                           ` | ||||||
|                         : ""} |                         : nothing} | ||||||
|                       ${this.addon.auto_update || |                       ${this.addon.auto_update || | ||||||
|                       this.hass.userData?.showAdvanced |                       this.hass.userData?.showAdvanced | ||||||
|                         ? html` |                         ? html` | ||||||
| @@ -542,13 +579,15 @@ class HassioAddonInfo extends LitElement { | |||||||
|                                 )} |                                 )} | ||||||
|                               </span> |                               </span> | ||||||
|                               <ha-switch |                               <ha-switch | ||||||
|  |                                 .disabled=${systemManaged && | ||||||
|  |                                 !this.controlEnabled} | ||||||
|                                 @change=${this._autoUpdateToggled} |                                 @change=${this._autoUpdateToggled} | ||||||
|                                 .checked=${this.addon.auto_update} |                                 .checked=${this.addon.auto_update} | ||||||
|                                 haptic |                                 haptic | ||||||
|                               ></ha-switch> |                               ></ha-switch> | ||||||
|                             </ha-settings-row> |                             </ha-settings-row> | ||||||
|                           ` |                           ` | ||||||
|                         : ""} |                         : nothing} | ||||||
|                       ${!this._computeCannotIngressSidebar && this.addon.ingress |                       ${!this._computeCannotIngressSidebar && this.addon.ingress | ||||||
|                         ? html` |                         ? html` | ||||||
|                             <ha-settings-row ?three-line=${this.narrow}> |                             <ha-settings-row ?three-line=${this.narrow}> | ||||||
| @@ -563,13 +602,15 @@ class HassioAddonInfo extends LitElement { | |||||||
|                                 )} |                                 )} | ||||||
|                               </span> |                               </span> | ||||||
|                               <ha-switch |                               <ha-switch | ||||||
|  |                                 .disabled=${systemManaged && | ||||||
|  |                                 !this.controlEnabled} | ||||||
|                                 @change=${this._panelToggled} |                                 @change=${this._panelToggled} | ||||||
|                                 .checked=${this.addon.ingress_panel} |                                 .checked=${this.addon.ingress_panel} | ||||||
|                                 haptic |                                 haptic | ||||||
|                               ></ha-switch> |                               ></ha-switch> | ||||||
|                             </ha-settings-row> |                             </ha-settings-row> | ||||||
|                           ` |                           ` | ||||||
|                         : ""} |                         : nothing} | ||||||
|                       ${this._computeUsesProtectedOptions |                       ${this._computeUsesProtectedOptions | ||||||
|                         ? html` |                         ? html` | ||||||
|                             <ha-settings-row ?three-line=${this.narrow}> |                             <ha-settings-row ?three-line=${this.narrow}> | ||||||
| @@ -584,16 +625,18 @@ class HassioAddonInfo extends LitElement { | |||||||
|                                 )} |                                 )} | ||||||
|                               </span> |                               </span> | ||||||
|                               <ha-switch |                               <ha-switch | ||||||
|  |                                 .disabled=${systemManaged && | ||||||
|  |                                 !this.controlEnabled} | ||||||
|                                 @change=${this._protectionToggled} |                                 @change=${this._protectionToggled} | ||||||
|                                 .checked=${this.addon.protected} |                                 .checked=${this.addon.protected} | ||||||
|                                 haptic |                                 haptic | ||||||
|                               ></ha-switch> |                               ></ha-switch> | ||||||
|                             </ha-settings-row> |                             </ha-settings-row> | ||||||
|                           ` |                           ` | ||||||
|                         : ""} |                         : nothing} | ||||||
|                     </div> |                     </div> | ||||||
|                   ` |                   ` | ||||||
|                 : ""} |                 : nothing} | ||||||
|             </div> |             </div> | ||||||
|             <div> |             <div> | ||||||
|               ${this.addon.version && this.addon.state === "started" |               ${this.addon.version && this.addon.state === "started" | ||||||
| @@ -612,12 +655,12 @@ class HassioAddonInfo extends LitElement { | |||||||
|                         ></supervisor-metric> |                         ></supervisor-metric> | ||||||
|                       ` |                       ` | ||||||
|                     )}` |                     )}` | ||||||
|                 : ""} |                 : nothing} | ||||||
|             </div> |             </div> | ||||||
|           </div> |           </div> | ||||||
|           ${this._error |           ${this._error | ||||||
|             ? html`<ha-alert alert-type="error">${this._error}</ha-alert>` |             ? html`<ha-alert alert-type="error">${this._error}</ha-alert>` | ||||||
|             : ""} |             : nothing} | ||||||
|           ${!this.addon.version && addonStoreInfo && !this.addon.available |           ${!this.addon.version && addonStoreInfo && !this.addon.available | ||||||
|             ? !addonArchIsSupported( |             ? !addonArchIsSupported( | ||||||
|                 this.supervisor.info.supported_arch, |                 this.supervisor.info.supported_arch, | ||||||
| @@ -641,7 +684,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|                     )} |                     )} | ||||||
|                   </ha-alert> |                   </ha-alert> | ||||||
|                 ` |                 ` | ||||||
|             : ""} |             : nothing} | ||||||
|         </div> |         </div> | ||||||
|         <div class="card-actions"> |         <div class="card-actions"> | ||||||
|           <div> |           <div> | ||||||
| @@ -651,6 +694,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|                     <ha-progress-button |                     <ha-progress-button | ||||||
|                       class="warning" |                       class="warning" | ||||||
|                       @click=${this._stopClicked} |                       @click=${this._stopClicked} | ||||||
|  |                       .disabled=${systemManaged && !this.controlEnabled} | ||||||
|                     > |                     > | ||||||
|                       ${this.supervisor.localize("addon.dashboard.stop")} |                       ${this.supervisor.localize("addon.dashboard.stop")} | ||||||
|                     </ha-progress-button> |                     </ha-progress-button> | ||||||
| @@ -688,26 +732,27 @@ class HassioAddonInfo extends LitElement { | |||||||
|                           target="_blank" |                           target="_blank" | ||||||
|                           rel="noopener" |                           rel="noopener" | ||||||
|                         > |                         > | ||||||
|                           <mwc-button> |                           <ha-button> | ||||||
|                             ${this.supervisor.localize( |                             ${this.supervisor.localize( | ||||||
|                               "addon.dashboard.open_web_ui" |                               "addon.dashboard.open_web_ui" | ||||||
|                             )} |                             )} | ||||||
|                           </mwc-button> |                           </ha-button> | ||||||
|                         </a> |                         </a> | ||||||
|                       ` |                       ` | ||||||
|                     : ""} |                     : nothing} | ||||||
|                   ${this._computeShowIngressUI |                   ${this._computeShowIngressUI | ||||||
|                     ? html` |                     ? html` | ||||||
|                         <mwc-button @click=${this._openIngress}> |                         <ha-button @click=${this._openIngress}> | ||||||
|                           ${this.supervisor.localize( |                           ${this.supervisor.localize( | ||||||
|                             "addon.dashboard.open_web_ui" |                             "addon.dashboard.open_web_ui" | ||||||
|                           )} |                           )} | ||||||
|                         </mwc-button> |                         </ha-button> | ||||||
|                       ` |                       ` | ||||||
|                     : ""} |                     : nothing} | ||||||
|                   <ha-progress-button |                   <ha-progress-button | ||||||
|                     class="warning" |                     class="warning" | ||||||
|                     @click=${this._uninstallClicked} |                     @click=${this._uninstallClicked} | ||||||
|  |                     .disabled=${systemManaged && !this.controlEnabled} | ||||||
|                   > |                   > | ||||||
|                     ${this.supervisor.localize("addon.dashboard.uninstall")} |                     ${this.supervisor.localize("addon.dashboard.uninstall")} | ||||||
|                   </ha-progress-button> |                   </ha-progress-button> | ||||||
| @@ -720,8 +765,8 @@ class HassioAddonInfo extends LitElement { | |||||||
|                           ${this.supervisor.localize("addon.dashboard.rebuild")} |                           ${this.supervisor.localize("addon.dashboard.rebuild")} | ||||||
|                         </ha-progress-button> |                         </ha-progress-button> | ||||||
|                       ` |                       ` | ||||||
|                     : ""}` |                     : nothing}` | ||||||
|               : ""} |               : nothing} | ||||||
|           </div> |           </div> | ||||||
|         </div> |         </div> | ||||||
|       </ha-card> |       </ha-card> | ||||||
| @@ -737,7 +782,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|               </div> |               </div> | ||||||
|             </ha-card> |             </ha-card> | ||||||
|           ` |           ` | ||||||
|         : ""} |         : nothing} | ||||||
|     `; |     `; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -822,6 +867,13 @@ class HassioAddonInfo extends LitElement { | |||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   private _showSystemManagedDialog() { | ||||||
|  |     showSystemManagedDialog(this, { | ||||||
|  |       addon: this.addon as HassioAddonDetails, | ||||||
|  |       supervisor: this.supervisor, | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   private get _computeIsRunning(): boolean { |   private get _computeIsRunning(): boolean { | ||||||
|     return (this.addon as HassioAddonDetails)?.state === "started"; |     return (this.addon as HassioAddonDetails)?.state === "started"; | ||||||
|   } |   } | ||||||
| @@ -1014,6 +1066,10 @@ class HassioAddonInfo extends LitElement { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   private async _stopClicked(ev: CustomEvent): Promise<void> { |   private async _stopClicked(ev: CustomEvent): Promise<void> { | ||||||
|  |     if (this._isSystemManaged(this.addon) && !this.controlEnabled) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const button = ev.currentTarget as any; |     const button = ev.currentTarget as any; | ||||||
|     button.progress = true; |     button.progress = true; | ||||||
|  |  | ||||||
| @@ -1125,6 +1181,10 @@ class HassioAddonInfo extends LitElement { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   private async _uninstallClicked(ev: CustomEvent): Promise<void> { |   private async _uninstallClicked(ev: CustomEvent): Promise<void> { | ||||||
|  |     if (this._isSystemManaged(this.addon) && !this.controlEnabled) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const button = ev.currentTarget as any; |     const button = ev.currentTarget as any; | ||||||
|     button.progress = true; |     button.progress = true; | ||||||
|     let removeData = false; |     let removeData = false; | ||||||
| @@ -1179,6 +1239,11 @@ class HassioAddonInfo extends LitElement { | |||||||
|     button.progress = false; |     button.progress = false; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   private _isSystemManaged = memoizeOne( | ||||||
|  |     (addon: HassioAddonDetails | StoreAddonDetails) => | ||||||
|  |       "system_managed" in addon && addon.system_managed | ||||||
|  |   ); | ||||||
|  |  | ||||||
|   static get styles(): CSSResultGroup { |   static get styles(): CSSResultGroup { | ||||||
|     return [ |     return [ | ||||||
|       haStyle, |       haStyle, | ||||||
| @@ -1201,7 +1266,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|         ha-card.warning .card-content { |         ha-card.warning .card-content { | ||||||
|           color: white; |           color: white; | ||||||
|         } |         } | ||||||
|         ha-card.warning mwc-button { |         ha-card.warning ha-button { | ||||||
|           --mdc-theme-primary: white !important; |           --mdc-theme-primary: white !important; | ||||||
|         } |         } | ||||||
|         .warning { |         .warning { | ||||||
| @@ -1215,12 +1280,12 @@ class HassioAddonInfo extends LitElement { | |||||||
|           padding-left: 8px; |           padding-left: 8px; | ||||||
|           padding-inline-start: 8px; |           padding-inline-start: 8px; | ||||||
|           padding-inline-end: initial; |           padding-inline-end: initial; | ||||||
|           font-size: 24px; |           font-size: var(--ha-font-size-2xl); | ||||||
|           color: var(--ha-card-header-color, var(--primary-text-color)); |           color: var(--ha-card-header-color, var(--primary-text-color)); | ||||||
|         } |         } | ||||||
|         .addon-version { |         .addon-version { | ||||||
|           float: var(--float-end); |           float: var(--float-end); | ||||||
|           font-size: 15px; |           font-size: var(--ha-font-size-l); | ||||||
|           vertical-align: middle; |           vertical-align: middle; | ||||||
|         } |         } | ||||||
|         .errors { |         .errors { | ||||||
| @@ -1246,7 +1311,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|         ha-svg-icon.stopped { |         ha-svg-icon.stopped { | ||||||
|           color: var(--error-color); |           color: var(--error-color); | ||||||
|         } |         } | ||||||
|         protection-enable mwc-button { |         protection-enable ha-button { | ||||||
|           --mdc-theme-primary: white; |           --mdc-theme-primary: white; | ||||||
|         } |         } | ||||||
|         .description a { |         .description a { | ||||||
| @@ -1328,7 +1393,7 @@ class HassioAddonInfo extends LitElement { | |||||||
|           align-self: end; |           align-self: end; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         ha-alert mwc-button { |         ha-alert ha-button { | ||||||
|           --mdc-theme-primary: var(--primary-text-color); |           --mdc-theme-primary: var(--primary-text-color); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										60
									
								
								hassio/src/addon-view/info/hassio-addon-system-managed.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								hassio/src/addon-view/info/hassio-addon-system-managed.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | |||||||
|  | import "@material/mwc-button"; | ||||||
|  | import type { TemplateResult } from "lit"; | ||||||
|  | import { LitElement, css, html, nothing } from "lit"; | ||||||
|  | import { customElement, property } from "lit/decorators"; | ||||||
|  | import { fireEvent } from "../../../../src/common/dom/fire_event"; | ||||||
|  | import "../../../../src/components/ha-alert"; | ||||||
|  | import "../../../../src/components/ha-button"; | ||||||
|  | import type { Supervisor } from "../../../../src/data/supervisor/supervisor"; | ||||||
|  |  | ||||||
|  | @customElement("hassio-addon-system-managed") | ||||||
|  | class HassioAddonSystemManaged extends LitElement { | ||||||
|  |   @property({ type: Boolean }) public narrow = false; | ||||||
|  |  | ||||||
|  |   @property({ attribute: false }) public supervisor!: Supervisor; | ||||||
|  |  | ||||||
|  |   @property({ type: Boolean, attribute: "hide-button" }) public hideButton = | ||||||
|  |     false; | ||||||
|  |  | ||||||
|  |   protected render(): TemplateResult { | ||||||
|  |     return html` | ||||||
|  |       <ha-alert | ||||||
|  |         alert-type="warning" | ||||||
|  |         .title=${this.supervisor.localize("addon.system_managed.title")} | ||||||
|  |         .narrow=${this.narrow} | ||||||
|  |       > | ||||||
|  |         ${this.supervisor.localize("addon.system_managed.description")} | ||||||
|  |         ${!this.hideButton | ||||||
|  |           ? html` | ||||||
|  |               <ha-button slot="action" @click=${this._takeControl}> | ||||||
|  |                 ${this.supervisor.localize("addon.system_managed.take_control")} | ||||||
|  |               </ha-button> | ||||||
|  |             ` | ||||||
|  |           : nothing} | ||||||
|  |       </ha-alert> | ||||||
|  |     `; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   private _takeControl() { | ||||||
|  |     fireEvent(this, "system-managed-take-control"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static styles = css` | ||||||
|  |     ha-alert { | ||||||
|  |       display: block; | ||||||
|  |       margin-bottom: 16px; | ||||||
|  |     } | ||||||
|  |     ha-button { | ||||||
|  |       white-space: nowrap; | ||||||
|  |     } | ||||||
|  |   `; | ||||||
|  | } | ||||||
|  | declare global { | ||||||
|  |   interface HTMLElementTagNameMap { | ||||||
|  |     "hassio-addon-system-managed": HassioAddonSystemManaged; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   interface HASSDomEvents { | ||||||
|  |     "system-managed-take-control": undefined; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| import "@material/mwc-button"; | import "@material/mwc-button"; | ||||||
| import type { ActionDetail } from "@material/mwc-list"; | import type { ActionDetail } from "@material/mwc-list"; | ||||||
| import "@material/mwc-list/mwc-list-item"; |  | ||||||
| import { mdiBackupRestore, mdiDelete, mdiDotsVertical, mdiPlus } from "@mdi/js"; | import { mdiBackupRestore, mdiDelete, mdiDotsVertical, mdiPlus } from "@mdi/js"; | ||||||
| import type { CSSResultGroup, PropertyValues } from "lit"; | import type { CSSResultGroup, PropertyValues } from "lit"; | ||||||
| import { LitElement, css, html, nothing } from "lit"; | import { LitElement, css, html, nothing } from "lit"; | ||||||
| @@ -18,6 +18,7 @@ import type { | |||||||
| import "../../../src/components/ha-button-menu"; | import "../../../src/components/ha-button-menu"; | ||||||
| import "../../../src/components/ha-fab"; | import "../../../src/components/ha-fab"; | ||||||
| import "../../../src/components/ha-icon-button"; | import "../../../src/components/ha-icon-button"; | ||||||
|  | import "../../../src/components/ha-list-item"; | ||||||
| import "../../../src/components/ha-svg-icon"; | import "../../../src/components/ha-svg-icon"; | ||||||
| import type { HassioBackup } from "../../../src/data/hassio/backup"; | import type { HassioBackup } from "../../../src/data/hassio/backup"; | ||||||
| import { | import { | ||||||
| @@ -32,6 +33,7 @@ import { | |||||||
|   showAlertDialog, |   showAlertDialog, | ||||||
|   showConfirmationDialog, |   showConfirmationDialog, | ||||||
| } from "../../../src/dialogs/generic/show-dialog-box"; | } from "../../../src/dialogs/generic/show-dialog-box"; | ||||||
|  | import "../../../src/layouts/hass-loading-screen"; | ||||||
| import "../../../src/layouts/hass-tabs-subpage-data-table"; | import "../../../src/layouts/hass-tabs-subpage-data-table"; | ||||||
| import type { HaTabsSubpageDataTable } from "../../../src/layouts/hass-tabs-subpage-data-table"; | import type { HaTabsSubpageDataTable } from "../../../src/layouts/hass-tabs-subpage-data-table"; | ||||||
| import { haStyle } from "../../../src/resources/styles"; | import { haStyle } from "../../../src/resources/styles"; | ||||||
| @@ -42,7 +44,6 @@ import { showHassioBackupDialog } from "../dialogs/backup/show-dialog-hassio-bac | |||||||
| import { showHassioCreateBackupDialog } from "../dialogs/backup/show-dialog-hassio-create-backup"; | import { showHassioCreateBackupDialog } from "../dialogs/backup/show-dialog-hassio-create-backup"; | ||||||
| import { supervisorTabs } from "../hassio-tabs"; | import { supervisorTabs } from "../hassio-tabs"; | ||||||
| import { hassioStyle } from "../resources/hassio-style"; | import { hassioStyle } from "../resources/hassio-style"; | ||||||
| import "../../../src/layouts/hass-loading-screen"; |  | ||||||
|  |  | ||||||
| type BackupItem = HassioBackup & { | type BackupItem = HassioBackup & { | ||||||
|   secondary: string; |   secondary: string; | ||||||
| @@ -211,16 +212,16 @@ export class HassioBackups extends LitElement { | |||||||
|             .path=${mdiDotsVertical} |             .path=${mdiDotsVertical} | ||||||
|             slot="trigger" |             slot="trigger" | ||||||
|           ></ha-icon-button> |           ></ha-icon-button> | ||||||
|           <mwc-list-item> |           <ha-list-item> | ||||||
|             ${this.supervisor.localize("common.reload")} |             ${this.supervisor.localize("common.reload")} | ||||||
|           </mwc-list-item> |           </ha-list-item> | ||||||
|           <mwc-list-item> |           <ha-list-item> | ||||||
|             ${this.supervisor.localize("dialog.backup_location.title")} |             ${this.supervisor.localize("dialog.backup_location.title")} | ||||||
|           </mwc-list-item> |           </ha-list-item> | ||||||
|           ${atLeastVersion(this.hass.config.version, 0, 116) |           ${atLeastVersion(this.hass.config.version, 0, 116) | ||||||
|             ? html`<mwc-list-item> |             ? html`<ha-list-item> | ||||||
|                 ${this.supervisor.localize("backup.upload_backup")} |                 ${this.supervisor.localize("backup.upload_backup")} | ||||||
|               </mwc-list-item>` |               </ha-list-item>` | ||||||
|             : ""} |             : ""} | ||||||
|         </ha-button-menu> |         </ha-button-menu> | ||||||
|  |  | ||||||
| @@ -390,7 +391,7 @@ export class HassioBackups extends LitElement { | |||||||
|           top: -4px; |           top: -4px; | ||||||
|         } |         } | ||||||
|         .selected-txt { |         .selected-txt { | ||||||
|           font-weight: bold; |           font-weight: var(--ha-font-weight-bold); | ||||||
|           padding-left: 16px; |           padding-left: 16px; | ||||||
|           padding-inline-start: 16px; |           padding-inline-start: 16px; | ||||||
|           padding-inline-end: initial; |           padding-inline-end: initial; | ||||||
| @@ -400,7 +401,7 @@ export class HassioBackups extends LitElement { | |||||||
|           margin-top: 20px; |           margin-top: 20px; | ||||||
|         } |         } | ||||||
|         .header-toolbar .selected-txt { |         .header-toolbar .selected-txt { | ||||||
|           font-size: 16px; |           font-size: var(--ha-font-size-l); | ||||||
|         } |         } | ||||||
|         .header-toolbar .header-btns { |         .header-toolbar .header-btns { | ||||||
|           margin-right: -12px; |           margin-right: -12px; | ||||||
|   | |||||||
| @@ -85,7 +85,7 @@ class HassioCardContent extends LitElement { | |||||||
|     } |     } | ||||||
|     ha-svg-icon.hassupdate, |     ha-svg-icon.hassupdate, | ||||||
|     ha-svg-icon.backup { |     ha-svg-icon.backup { | ||||||
|       color: var(--paper-item-icon-color); |       color: var(--state-icon-color); | ||||||
|     } |     } | ||||||
|     ha-svg-icon.not_available { |     ha-svg-icon.not_available { | ||||||
|       color: var(--error-color); |       color: var(--error-color); | ||||||
| @@ -101,7 +101,7 @@ class HassioCardContent extends LitElement { | |||||||
|       overflow: hidden; |       overflow: hidden; | ||||||
|       position: relative; |       position: relative; | ||||||
|       height: 2.4em; |       height: 2.4em; | ||||||
|       line-height: 1.2em; |       line-height: var(--ha-line-height-condensed); | ||||||
|     } |     } | ||||||
|     .icon_image img { |     .icon_image img { | ||||||
|       max-height: 40px; |       max-height: 40px; | ||||||
|   | |||||||
| @@ -132,9 +132,9 @@ class HassioDashboard extends LitElement { | |||||||
|         } |         } | ||||||
|         ha-fab.non-tabs { |         ha-fab.non-tabs { | ||||||
|           position: fixed; |           position: fixed; | ||||||
|           right: calc(16px + env(safe-area-inset-right)); |           right: calc(16px + var(--safe-area-inset-right)); | ||||||
|           bottom: calc(16px + env(safe-area-inset-bottom)); |           bottom: calc(16px + var(--safe-area-inset-bottom)); | ||||||
|           inset-inline-end: calc(16px + env(safe-area-inset-right)); |           inset-inline-end: calc(16px + var(--safe-area-inset-right)); | ||||||
|           inset-inline-start: initial; |           inset-inline-start: initial; | ||||||
|           z-index: 1; |           z-index: 1; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -130,8 +130,8 @@ export class HassioUpdate extends LitElement { | |||||||
|           color: var(--primary-text-color); |           color: var(--primary-text-color); | ||||||
|         } |         } | ||||||
|         .update-heading { |         .update-heading { | ||||||
|           font-size: var(--paper-font-subhead_-_font-size); |           font-size: var(--ha-font-size-l); | ||||||
|           font-weight: 500; |           font-weight: var(--ha-font-weight-medium); | ||||||
|           margin-bottom: 0.5em; |           margin-bottom: 0.5em; | ||||||
|           color: var(--primary-text-color); |           color: var(--primary-text-color); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import type { ActionDetail } from "@material/mwc-list"; | import type { ActionDetail } from "@material/mwc-list"; | ||||||
| import "@material/mwc-list/mwc-list-item"; |  | ||||||
| import { mdiClose, mdiDotsVertical } from "@mdi/js"; | import { mdiClose, mdiDotsVertical } from "@mdi/js"; | ||||||
| import type { CSSResultGroup } from "lit"; | import type { CSSResultGroup } from "lit"; | ||||||
| import { css, html, LitElement, nothing } from "lit"; | import { css, html, LitElement, nothing } from "lit"; | ||||||
| @@ -8,15 +8,17 @@ import { atLeastVersion } from "../../../../src/common/config/version"; | |||||||
| import { fireEvent } from "../../../../src/common/dom/fire_event"; | import { fireEvent } from "../../../../src/common/dom/fire_event"; | ||||||
| import { stopPropagation } from "../../../../src/common/dom/stop_propagation"; | import { stopPropagation } from "../../../../src/common/dom/stop_propagation"; | ||||||
| import { slugify } from "../../../../src/common/string/slugify"; | import { slugify } from "../../../../src/common/string/slugify"; | ||||||
| import "../../../../src/components/ha-md-dialog"; |  | ||||||
| import "../../../../src/components/ha-dialog-header"; |  | ||||||
| import "../../../../src/components/buttons/ha-progress-button"; | import "../../../../src/components/buttons/ha-progress-button"; | ||||||
| import "../../../../src/components/ha-alert"; | import "../../../../src/components/ha-alert"; | ||||||
| import "../../../../src/components/ha-spinner"; |  | ||||||
| import "../../../../src/components/ha-button"; | import "../../../../src/components/ha-button"; | ||||||
| import "../../../../src/components/ha-button-menu"; | import "../../../../src/components/ha-button-menu"; | ||||||
|  | import "../../../../src/components/ha-dialog-header"; | ||||||
| import "../../../../src/components/ha-header-bar"; | import "../../../../src/components/ha-header-bar"; | ||||||
| import "../../../../src/components/ha-icon-button"; | import "../../../../src/components/ha-icon-button"; | ||||||
|  | import "../../../../src/components/ha-list-item"; | ||||||
|  | import "../../../../src/components/ha-md-dialog"; | ||||||
|  | import type { HaMdDialog } from "../../../../src/components/ha-md-dialog"; | ||||||
|  | import "../../../../src/components/ha-spinner"; | ||||||
| import { getSignedPath } from "../../../../src/data/auth"; | import { getSignedPath } from "../../../../src/data/auth"; | ||||||
| import type { HassioBackupDetail } from "../../../../src/data/hassio/backup"; | import type { HassioBackupDetail } from "../../../../src/data/hassio/backup"; | ||||||
| import { | import { | ||||||
| @@ -36,7 +38,6 @@ import { fileDownload } from "../../../../src/util/file_download"; | |||||||
| import "../../components/supervisor-backup-content"; | import "../../components/supervisor-backup-content"; | ||||||
| import type { SupervisorBackupContent } from "../../components/supervisor-backup-content"; | import type { SupervisorBackupContent } from "../../components/supervisor-backup-content"; | ||||||
| import type { HassioBackupDialogParams } from "./show-dialog-hassio-backup"; | import type { HassioBackupDialogParams } from "./show-dialog-hassio-backup"; | ||||||
| import type { HaMdDialog } from "../../../../src/components/ha-md-dialog"; |  | ||||||
|  |  | ||||||
| @customElement("dialog-hassio-backup") | @customElement("dialog-hassio-backup") | ||||||
| class HassioBackupDialog | class HassioBackupDialog | ||||||
| @@ -121,15 +122,15 @@ class HassioBackupDialog | |||||||
|                   .path=${mdiDotsVertical} |                   .path=${mdiDotsVertical} | ||||||
|                   slot="trigger" |                   slot="trigger" | ||||||
|                 ></ha-icon-button> |                 ></ha-icon-button> | ||||||
|                 <mwc-list-item |                 <ha-list-item | ||||||
|                   >${this._dialogParams.supervisor.localize( |                   >${this._dialogParams.supervisor.localize( | ||||||
|                     "backup.download_backup" |                     "backup.download_backup" | ||||||
|                   )}</mwc-list-item |                   )}</ha-list-item | ||||||
|                 > |                 > | ||||||
|                 <mwc-list-item class="error" |                 <ha-list-item class="error" | ||||||
|                   >${this._dialogParams.supervisor.localize( |                   >${this._dialogParams.supervisor.localize( | ||||||
|                     "backup.delete_backup_title" |                     "backup.delete_backup_title" | ||||||
|                   )}</mwc-list-item |                   )}</ha-list-item | ||||||
|                 > |                 > | ||||||
|               </ha-button-menu>` |               </ha-button-menu>` | ||||||
|             : nothing} |             : nothing} | ||||||
|   | |||||||
| @@ -1,12 +1,12 @@ | |||||||
| import "@material/mwc-list/mwc-list-item"; |  | ||||||
| import type { CSSResultGroup } from "lit"; | import type { CSSResultGroup } from "lit"; | ||||||
| import { css, html, LitElement, nothing } from "lit"; | import { css, html, LitElement, nothing } from "lit"; | ||||||
| import { customElement, property, state } from "lit/decorators"; | import { customElement, property, state } from "lit/decorators"; | ||||||
| import memoizeOne from "memoize-one"; | import memoizeOne from "memoize-one"; | ||||||
| import { fireEvent } from "../../../../src/common/dom/fire_event"; | import { fireEvent } from "../../../../src/common/dom/fire_event"; | ||||||
| import "../../../../src/components/ha-spinner"; |  | ||||||
| import "../../../../src/components/ha-select"; |  | ||||||
| import "../../../../src/components/ha-dialog"; | import "../../../../src/components/ha-dialog"; | ||||||
|  | import "../../../../src/components/ha-list-item"; | ||||||
|  | import "../../../../src/components/ha-select"; | ||||||
|  | import "../../../../src/components/ha-spinner"; | ||||||
| import { | import { | ||||||
|   extractApiErrorMessage, |   extractApiErrorMessage, | ||||||
|   ignoreSupervisorError, |   ignoreSupervisorError, | ||||||
| @@ -95,8 +95,8 @@ class HassioDatadiskDialog extends LitElement { | |||||||
|                     > |                     > | ||||||
|                       ${this.devices.map( |                       ${this.devices.map( | ||||||
|                         (device) => |                         (device) => | ||||||
|                           html`<mwc-list-item .value=${device} |                           html`<ha-list-item .value=${device} | ||||||
|                             >${device}</mwc-list-item |                             >${device}</ha-list-item | ||||||
|                           >` |                           >` | ||||||
|                       )} |                       )} | ||||||
|                     </ha-select> |                     </ha-select> | ||||||
|   | |||||||
| @@ -16,23 +16,14 @@ import type { HomeAssistant } from "../../../../src/types"; | |||||||
| import type { HassioHardwareDialogParams } from "./show-dialog-hassio-hardware"; | import type { HassioHardwareDialogParams } from "./show-dialog-hassio-hardware"; | ||||||
|  |  | ||||||
| const _filterDevices = memoizeOne( | const _filterDevices = memoizeOne( | ||||||
|   ( |   (hardware: HassioHardwareInfo, filter: string, language: string) => | ||||||
|     showAdvanced: boolean, |  | ||||||
|     hardware: HassioHardwareInfo, |  | ||||||
|     filter: string, |  | ||||||
|     language: string |  | ||||||
|   ) => |  | ||||||
|     hardware.devices |     hardware.devices | ||||||
|       .filter( |       .filter( | ||||||
|         (device) => |         (device) => | ||||||
|           (showAdvanced || |           device.by_id?.toLowerCase().includes(filter) || | ||||||
|             ["tty", "gpio", "input"].includes(device.subsystem)) && |  | ||||||
|           (device.by_id?.toLowerCase().includes(filter) || |  | ||||||
|           device.name.toLowerCase().includes(filter) || |           device.name.toLowerCase().includes(filter) || | ||||||
|           device.dev_path.toLocaleLowerCase().includes(filter) || |           device.dev_path.toLocaleLowerCase().includes(filter) || | ||||||
|             JSON.stringify(device.attributes) |           JSON.stringify(device.attributes).toLocaleLowerCase().includes(filter) | ||||||
|               .toLocaleLowerCase() |  | ||||||
|               .includes(filter)) |  | ||||||
|       ) |       ) | ||||||
|       .sort((a, b) => stringCompare(a.name, b.name, language)) |       .sort((a, b) => stringCompare(a.name, b.name, language)) | ||||||
| ); | ); | ||||||
| @@ -60,7 +51,6 @@ class HassioHardwareDialog extends LitElement { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     const devices = _filterDevices( |     const devices = _filterDevices( | ||||||
|       this.hass.userData?.showAdvanced || false, |  | ||||||
|       this._dialogParams.hardware, |       this._dialogParams.hardware, | ||||||
|       (this._filter || "").toLowerCase(), |       (this._filter || "").toLowerCase(), | ||||||
|       this.hass.locale.language |       this.hass.locale.language | ||||||
| @@ -180,10 +170,10 @@ class HassioHardwareDialog extends LitElement { | |||||||
|           padding: 16px; |           padding: 16px; | ||||||
|           overflow: auto; |           overflow: auto; | ||||||
|           line-height: 1.45; |           line-height: 1.45; | ||||||
|           font-family: var(--code-font-family, monospace); |           font-family: var(--ha-font-family-code); | ||||||
|         } |         } | ||||||
|         code { |         code { | ||||||
|           font-size: 85%; |           font-size: var(--ha-font-size-s); | ||||||
|           padding: 0.2em 0.4em; |           padding: 0.2em 0.4em; | ||||||
|         } |         } | ||||||
|         search-input { |         search-input { | ||||||
|   | |||||||
| @@ -38,6 +38,7 @@ class HassioMarkdownDialog extends LitElement { | |||||||
|         open |         open | ||||||
|         @closed=${this.closeDialog} |         @closed=${this.closeDialog} | ||||||
|         .heading=${createCloseHeading(this.hass, this.title)} |         .heading=${createCloseHeading(this.hass, this.title)} | ||||||
|  |         hideactions | ||||||
|       > |       > | ||||||
|         <ha-markdown |         <ha-markdown | ||||||
|           .content=${this.content || ""} |           .content=${this.content || ""} | ||||||
|   | |||||||
| @@ -1,8 +1,4 @@ | |||||||
| import "@material/mwc-button/mwc-button"; | import "@material/mwc-button/mwc-button"; | ||||||
| import "@material/mwc-list/mwc-list"; |  | ||||||
| import "@material/mwc-list/mwc-list-item"; |  | ||||||
| import "@material/mwc-tab"; |  | ||||||
| import "@material/mwc-tab-bar"; |  | ||||||
| import { mdiClose } from "@mdi/js"; | import { mdiClose } from "@mdi/js"; | ||||||
| import type { CSSResultGroup } from "lit"; | import type { CSSResultGroup } from "lit"; | ||||||
| import { css, html, LitElement, nothing } from "lit"; | import { css, html, LitElement, nothing } from "lit"; | ||||||
| @@ -10,14 +6,16 @@ import { customElement, property, state } from "lit/decorators"; | |||||||
| import { cache } from "lit/directives/cache"; | import { cache } from "lit/directives/cache"; | ||||||
| import { fireEvent } from "../../../../src/common/dom/fire_event"; | import { fireEvent } from "../../../../src/common/dom/fire_event"; | ||||||
| import "../../../../src/components/ha-alert"; | import "../../../../src/components/ha-alert"; | ||||||
| import "../../../../src/components/ha-spinner"; |  | ||||||
| import "../../../../src/components/ha-dialog"; | import "../../../../src/components/ha-dialog"; | ||||||
| import "../../../../src/components/ha-expansion-panel"; | import "../../../../src/components/ha-expansion-panel"; | ||||||
| import "../../../../src/components/ha-formfield"; | import "../../../../src/components/ha-formfield"; | ||||||
| import "../../../../src/components/ha-header-bar"; | import "../../../../src/components/ha-header-bar"; | ||||||
| import "../../../../src/components/ha-icon-button"; | import "../../../../src/components/ha-icon-button"; | ||||||
|  | import "../../../../src/components/ha-list"; | ||||||
|  | import "../../../../src/components/ha-list-item"; | ||||||
| import "../../../../src/components/ha-password-field"; | import "../../../../src/components/ha-password-field"; | ||||||
| import "../../../../src/components/ha-radio"; | import "../../../../src/components/ha-radio"; | ||||||
|  | import "../../../../src/components/ha-spinner"; | ||||||
| import "../../../../src/components/ha-textfield"; | import "../../../../src/components/ha-textfield"; | ||||||
| import type { HaTextField } from "../../../../src/components/ha-textfield"; | import type { HaTextField } from "../../../../src/components/ha-textfield"; | ||||||
| import { extractApiErrorMessage } from "../../../../src/data/hassio/common"; | import { extractApiErrorMessage } from "../../../../src/data/hassio/common"; | ||||||
| @@ -39,6 +37,7 @@ import type { HassDialog } from "../../../../src/dialogs/make-dialog-manager"; | |||||||
| import { haStyleDialog } from "../../../../src/resources/styles"; | import { haStyleDialog } from "../../../../src/resources/styles"; | ||||||
| import type { HomeAssistant } from "../../../../src/types"; | import type { HomeAssistant } from "../../../../src/types"; | ||||||
| import type { HassioNetworkDialogParams } from "./show-dialog-network"; | import type { HassioNetworkDialogParams } from "./show-dialog-network"; | ||||||
|  | import "../../../../src/components/sl-tab-group"; | ||||||
|  |  | ||||||
| const IP_VERSIONS = ["ipv4", "ipv6"]; | const IP_VERSIONS = ["ipv4", "ipv6"]; | ||||||
|  |  | ||||||
| @@ -116,19 +115,19 @@ export class DialogHassioNetwork | |||||||
|             ></ha-icon-button> |             ></ha-icon-button> | ||||||
|           </ha-header-bar> |           </ha-header-bar> | ||||||
|           ${this._interfaces.length > 1 |           ${this._interfaces.length > 1 | ||||||
|             ? html`<mwc-tab-bar |             ? html`<sl-tab-group @sl-tab-show=${this._handleTabActivated} | ||||||
|                 .activeIndex=${this._curTabIndex} |  | ||||||
|                 @MDCTabBar:activated=${this._handleTabActivated} |  | ||||||
|                 >${this._interfaces.map( |                 >${this._interfaces.map( | ||||||
|                   (device) => |                   (device, index) => | ||||||
|                     html`<mwc-tab |                     html`<sl-tab | ||||||
|  |                       slot="nav" | ||||||
|                       .id=${device.interface} |                       .id=${device.interface} | ||||||
|                       .label=${device.interface} |                       .panel=${index.toString()} | ||||||
|                       dialogInitialFocus |                       .active=${this._curTabIndex === index} | ||||||
|                     > |                     > | ||||||
|                     </mwc-tab>` |                       ${device.interface} | ||||||
|  |                     </sl-tab>` | ||||||
|                 )} |                 )} | ||||||
|               </mwc-tab-bar>` |               </sl-tab-group>` | ||||||
|             : ""} |             : ""} | ||||||
|         </div> |         </div> | ||||||
|         ${cache(this._renderTab())} |         ${cache(this._renderTab())} | ||||||
| @@ -169,12 +168,12 @@ export class DialogHassioNetwork | |||||||
|                 this._accessPoints.accesspoints && |                 this._accessPoints.accesspoints && | ||||||
|                 this._accessPoints.accesspoints.length !== 0 |                 this._accessPoints.accesspoints.length !== 0 | ||||||
|                   ? html` |                   ? html` | ||||||
|                       <mwc-list> |                       <ha-list> | ||||||
|                         ${this._accessPoints.accesspoints |                         ${this._accessPoints.accesspoints | ||||||
|                           .filter((ap) => ap.ssid) |                           .filter((ap) => ap.ssid) | ||||||
|                           .map( |                           .map( | ||||||
|                             (ap) => html` |                             (ap) => html` | ||||||
|                               <mwc-list-item |                               <ha-list-item | ||||||
|                                 twoline |                                 twoline | ||||||
|                                 @click=${this._selectAP} |                                 @click=${this._selectAP} | ||||||
|                                 .activated=${ap.ssid === |                                 .activated=${ap.ssid === | ||||||
| @@ -189,10 +188,10 @@ export class DialogHassioNetwork | |||||||
|                                   )}: |                                   )}: | ||||||
|                                   ${ap.signal} |                                   ${ap.signal} | ||||||
|                                 </span> |                                 </span> | ||||||
|                               </mwc-list-item> |                               </ha-list-item> | ||||||
|                             ` |                             ` | ||||||
|                           )} |                           )} | ||||||
|                       </mwc-list> |                       </ha-list> | ||||||
|                     ` |                     ` | ||||||
|                   : ""} |                   : ""} | ||||||
|                 ${this._wifiConfiguration |                 ${this._wifiConfiguration | ||||||
| @@ -485,8 +484,8 @@ export class DialogHassioNetwork | |||||||
|         return; |         return; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     this._curTabIndex = ev.detail.index; |     this._curTabIndex = Number(ev.detail.name); | ||||||
|     this._interface = { ...this._interfaces[ev.detail.index] }; |     this._interface = { ...this._interfaces[this._curTabIndex] }; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private _handleRadioValueChanged(ev: CustomEvent): void { |   private _handleRadioValueChanged(ev: CustomEvent): void { | ||||||
| @@ -560,11 +559,6 @@ export class DialogHassioNetwork | |||||||
|           flex-shrink: 0; |           flex-shrink: 0; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         mwc-tab-bar { |  | ||||||
|           border-bottom: 1px solid |  | ||||||
|             var(--mdc-dialog-scroll-divider-color, rgba(0, 0, 0, 0.12)); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         ha-dialog { |         ha-dialog { | ||||||
|           --dialog-content-position: static; |           --dialog-content-position: static; | ||||||
|           --dialog-content-padding: 0; |           --dialog-content-padding: 0; | ||||||
| @@ -616,7 +610,7 @@ export class DialogHassioNetwork | |||||||
|           display: flex; |           display: flex; | ||||||
|           justify-content: space-between; |           justify-content: space-between; | ||||||
|           padding: 8px; |           padding: 8px; | ||||||
|           padding-bottom: max(env(safe-area-inset-bottom), 8px); |           padding-bottom: max(var(--safe-area-inset-bottom), 8px); | ||||||
|           background-color: var(--mdc-theme-surface, #fff); |           background-color: var(--mdc-theme-surface, #fff); | ||||||
|         } |         } | ||||||
|         .warning { |         .warning { | ||||||
| @@ -634,9 +628,17 @@ export class DialogHassioNetwork | |||||||
|         ha-textfield { |         ha-textfield { | ||||||
|           padding: 0 14px; |           padding: 0 14px; | ||||||
|         } |         } | ||||||
|         mwc-list-item { |         ha-list-item { | ||||||
|           --mdc-list-side-padding: 10px; |           --mdc-list-side-padding: 10px; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         sl-tab { | ||||||
|  |           flex: 1; | ||||||
|  |         } | ||||||
|  |         sl-tab::part(base) { | ||||||
|  |           width: 100%; | ||||||
|  |           justify-content: center; | ||||||
|  |         } | ||||||
|       `, |       `, | ||||||
|     ]; |     ]; | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -183,9 +183,6 @@ class HassioRepositoriesDialog extends LitElement { | |||||||
|         ha-dialog.button-left { |         ha-dialog.button-left { | ||||||
|           --justify-action-buttons: flex-start; |           --justify-action-buttons: flex-start; | ||||||
|         } |         } | ||||||
|         paper-icon-item { |  | ||||||
|           cursor: pointer; |  | ||||||
|         } |  | ||||||
|         .form { |         .form { | ||||||
|           color: var(--primary-text-color); |           color: var(--primary-text-color); | ||||||
|         } |         } | ||||||
|   | |||||||
							
								
								
									
										192
									
								
								hassio/src/dialogs/system-managed/dialog-system-managed.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								hassio/src/dialogs/system-managed/dialog-system-managed.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,192 @@ | |||||||
|  | import { mdiClose, mdiPuzzle, mdiSwapHorizontal } from "@mdi/js"; | ||||||
|  | import type { CSSResultGroup } from "lit"; | ||||||
|  | import { css, html, LitElement, nothing } from "lit"; | ||||||
|  | import { customElement, property, query, state } from "lit/decorators"; | ||||||
|  | import { atLeastVersion } from "../../../../src/common/config/version"; | ||||||
|  | import "../../../../src/components/ha-dialog-header"; | ||||||
|  | import "../../../../src/components/ha-icon-button"; | ||||||
|  | import "../../../../src/components/ha-icon-next"; | ||||||
|  | import "../../../../src/components/ha-md-dialog"; | ||||||
|  | import type { HaMdDialog } from "../../../../src/components/ha-md-dialog"; | ||||||
|  | import "../../../../src/components/ha-md-list"; | ||||||
|  | import "../../../../src/components/ha-md-list-item"; | ||||||
|  | import "../../../../src/components/ha-svg-icon"; | ||||||
|  | import { | ||||||
|  |   getConfigEntry, | ||||||
|  |   type ConfigEntry, | ||||||
|  | } from "../../../../src/data/config_entries"; | ||||||
|  | import type { HassioAddonDetails } from "../../../../src/data/hassio/addon"; | ||||||
|  | import type { Supervisor } from "../../../../src/data/supervisor/supervisor"; | ||||||
|  | import { mdiHomeAssistant } from "../../../../src/resources/home-assistant-logo-svg"; | ||||||
|  | import { haStyle } from "../../../../src/resources/styles"; | ||||||
|  | import type { HomeAssistant } from "../../../../src/types"; | ||||||
|  | import { brandsUrl } from "../../../../src/util/brands-url"; | ||||||
|  | import type { SystemManagedDialogParams } from "./show-dialog-system-managed"; | ||||||
|  |  | ||||||
|  | @customElement("dialog-system-managed") | ||||||
|  | class HassioSystemManagedDialog extends LitElement { | ||||||
|  |   @property({ attribute: false }) public hass!: HomeAssistant; | ||||||
|  |  | ||||||
|  |   @state() private _supervisor?: Supervisor; | ||||||
|  |  | ||||||
|  |   @state() private _addon?: HassioAddonDetails; | ||||||
|  |  | ||||||
|  |   @state() private _open = false; | ||||||
|  |  | ||||||
|  |   @state() private _configEntry?: ConfigEntry; | ||||||
|  |  | ||||||
|  |   @query("ha-md-dialog") private _dialog?: HaMdDialog; | ||||||
|  |  | ||||||
|  |   public async showDialog( | ||||||
|  |     dialogParams: SystemManagedDialogParams | ||||||
|  |   ): Promise<void> { | ||||||
|  |     this._addon = dialogParams.addon; | ||||||
|  |     this._supervisor = dialogParams.supervisor; | ||||||
|  |     this._open = true; | ||||||
|  |     this._loadConfigEntry(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   private _dialogClosed() { | ||||||
|  |     this._addon = undefined; | ||||||
|  |     this._supervisor = undefined; | ||||||
|  |     this._configEntry = undefined; | ||||||
|  |     this._open = false; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public closeDialog() { | ||||||
|  |     this._dialog?.close(); | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   protected render() { | ||||||
|  |     if (!this._addon || !this._open || !this._supervisor) { | ||||||
|  |       return nothing; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const addonImage = | ||||||
|  |       atLeastVersion(this.hass.config.version, 0, 105) && this._addon.icon | ||||||
|  |         ? `/api/hassio/addons/${this._addon.slug}/icon` | ||||||
|  |         : undefined; | ||||||
|  |  | ||||||
|  |     return html` | ||||||
|  |       <ha-md-dialog open @closed=${this._dialogClosed}> | ||||||
|  |         <ha-dialog-header slot="headline"> | ||||||
|  |           <ha-icon-button | ||||||
|  |             slot="navigationIcon" | ||||||
|  |             .path=${mdiClose} | ||||||
|  |             @click=${this.closeDialog} | ||||||
|  |           ></ha-icon-button> | ||||||
|  |           <span slot="title">${this._addon?.name}</span> | ||||||
|  |         </ha-dialog-header> | ||||||
|  |         <div slot="content"> | ||||||
|  |           <div class="icons"> | ||||||
|  |             <ha-svg-icon | ||||||
|  |               class="primary" | ||||||
|  |               .path=${mdiHomeAssistant} | ||||||
|  |             ></ha-svg-icon> | ||||||
|  |             <ha-svg-icon .path=${mdiSwapHorizontal}></ha-svg-icon> | ||||||
|  |             ${addonImage | ||||||
|  |               ? html`<img src=${addonImage} alt=${this._addon.name} />` | ||||||
|  |               : html`<ha-svg-icon .path=${mdiPuzzle}></ha-svg-icon>`} | ||||||
|  |           </div> | ||||||
|  |           ${this._supervisor.localize("addon.system_managed.title")}.<br /> | ||||||
|  |           ${this._supervisor.localize("addon.system_managed.description")} | ||||||
|  |           ${this._configEntry | ||||||
|  |             ? html` | ||||||
|  |                 <h3> | ||||||
|  |                   ${this._supervisor.localize( | ||||||
|  |                     "addon.system_managed.managed_by" | ||||||
|  |                   )}: | ||||||
|  |                 </h3> | ||||||
|  |                 <ha-md-list> | ||||||
|  |                   <ha-md-list-item | ||||||
|  |                     type="link" | ||||||
|  |                     href=${`/config/integrations/integration/${this._configEntry.domain}`} | ||||||
|  |                   > | ||||||
|  |                     <img | ||||||
|  |                       slot="start" | ||||||
|  |                       class="integration-icon" | ||||||
|  |                       alt=${this._configEntry.title} | ||||||
|  |                       src=${brandsUrl({ | ||||||
|  |                         domain: this._configEntry.domain, | ||||||
|  |                         type: "icon", | ||||||
|  |                         darkOptimized: this.hass.themes?.darkMode, | ||||||
|  |                       })} | ||||||
|  |                       crossorigin="anonymous" | ||||||
|  |                       referrerpolicy="no-referrer" | ||||||
|  |                       @error=${this._onImageError} | ||||||
|  |                       @load=${this._onImageLoad} | ||||||
|  |                     /> | ||||||
|  |                     ${this._configEntry.title} | ||||||
|  |                     <ha-icon-next slot="end"></ha-icon-next> | ||||||
|  |                   </ha-md-list-item> | ||||||
|  |                 </ha-md-list> | ||||||
|  |               ` | ||||||
|  |             : nothing} | ||||||
|  |         </div> | ||||||
|  |       </ha-md-dialog> | ||||||
|  |     `; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   private _onImageLoad(ev) { | ||||||
|  |     ev.target.style.visibility = "initial"; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   private _onImageError(ev) { | ||||||
|  |     ev.target.style.visibility = "hidden"; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   private async _loadConfigEntry() { | ||||||
|  |     if (this._addon?.system_managed_config_entry) { | ||||||
|  |       try { | ||||||
|  |         const { config_entry } = await getConfigEntry( | ||||||
|  |           this.hass, | ||||||
|  |           this._addon.system_managed_config_entry | ||||||
|  |         ); | ||||||
|  |         this._configEntry = config_entry; | ||||||
|  |       } catch (err) { | ||||||
|  |         // eslint-disable-next-line no-console | ||||||
|  |         console.error(err); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static get styles(): CSSResultGroup { | ||||||
|  |     return [ | ||||||
|  |       haStyle, | ||||||
|  |       css` | ||||||
|  |         .icons { | ||||||
|  |           display: flex; | ||||||
|  |           justify-content: center; | ||||||
|  |           align-items: center; | ||||||
|  |           gap: 16px; | ||||||
|  |           --mdc-icon-size: 48px; | ||||||
|  |           margin-bottom: 32px; | ||||||
|  |         } | ||||||
|  |         .icons img { | ||||||
|  |           width: 48px; | ||||||
|  |         } | ||||||
|  |         .icons .primary { | ||||||
|  |           color: var(--primary-color); | ||||||
|  |         } | ||||||
|  |         .actions { | ||||||
|  |           display: flex; | ||||||
|  |           justify-content: space-between; | ||||||
|  |         } | ||||||
|  |         .integration-icon { | ||||||
|  |           width: 24px; | ||||||
|  |         } | ||||||
|  |         ha-md-list-item { | ||||||
|  |           --md-list-item-leading-space: 4px; | ||||||
|  |           --md-list-item-trailing-space: 4px; | ||||||
|  |         } | ||||||
|  |       `, | ||||||
|  |     ]; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | declare global { | ||||||
|  |   interface HTMLElementTagNameMap { | ||||||
|  |     "dialog-system-managed": HassioSystemManagedDialog; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,19 @@ | |||||||
|  | import { fireEvent } from "../../../../src/common/dom/fire_event"; | ||||||
|  | import type { HassioAddonDetails } from "../../../../src/data/hassio/addon"; | ||||||
|  | import type { Supervisor } from "../../../../src/data/supervisor/supervisor"; | ||||||
|  |  | ||||||
|  | export interface SystemManagedDialogParams { | ||||||
|  |   addon: HassioAddonDetails; | ||||||
|  |   supervisor: Supervisor; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export const showSystemManagedDialog = ( | ||||||
|  |   element: HTMLElement, | ||||||
|  |   dialogParams: SystemManagedDialogParams | ||||||
|  | ): void => { | ||||||
|  |   fireEvent(element, "show-dialog", { | ||||||
|  |     dialogTag: "dialog-system-managed", | ||||||
|  |     dialogImport: () => import("./dialog-system-managed"), | ||||||
|  |     dialogParams, | ||||||
|  |   }); | ||||||
|  | }; | ||||||
| @@ -1,17 +1,19 @@ | |||||||
|  | import { | ||||||
|  |   haFontFamilyBody, | ||||||
|  |   haFontSmoothing, | ||||||
|  |   haMozOsxFontSmoothing, | ||||||
|  | } from "../../src/resources/theme/typography.globals"; | ||||||
| import "./hassio-main"; | import "./hassio-main"; | ||||||
|  |  | ||||||
| import("../../src/resources/ha-style"); | import("../../src/resources/append-ha-style"); | ||||||
| import("@polymer/polymer/lib/utils/settings").then( |  | ||||||
|   ({ setCancelSyntheticClickEvents }) => setCancelSyntheticClickEvents(false) |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| const styleEl = document.createElement("style"); | const styleEl = document.createElement("style"); | ||||||
| styleEl.textContent = ` | styleEl.textContent = ` | ||||||
| body { | body { | ||||||
|   font-family: Roboto, sans-serif; |   font-family: ${haFontFamilyBody}; | ||||||
|   -moz-osx-font-smoothing: grayscale; |   -moz-osx-font-smoothing: ${haMozOsxFontSmoothing}; | ||||||
|   -webkit-font-smoothing: antialiased; |   -webkit-font-smoothing: ${haFontSmoothing}; | ||||||
|   font-weight: 400; |   font-weight: var(--ha-font-weight-normal); | ||||||
|   margin: 0; |   margin: 0; | ||||||
|   padding: 0; |   padding: 0; | ||||||
|   height: 100vh; |   height: 100vh; | ||||||
|   | |||||||
| @@ -340,12 +340,12 @@ class HassioIngressView extends LitElement { | |||||||
|     .header { |     .header { | ||||||
|       display: flex; |       display: flex; | ||||||
|       align-items: center; |       align-items: center; | ||||||
|       font-size: 16px; |       font-size: var(--ha-font-size-l); | ||||||
|       height: 40px; |       height: 40px; | ||||||
|       padding: 0 16px; |       padding: 0 16px; | ||||||
|       pointer-events: none; |       pointer-events: none; | ||||||
|       background-color: var(--app-header-background-color); |       background-color: var(--app-header-background-color); | ||||||
|       font-weight: 400; |       font-weight: var(--ha-font-weight-normal); | ||||||
|       color: var(--app-header-text-color, white); |       color: var(--app-header-text-color, white); | ||||||
|       border-bottom: var(--app-header-border-bottom, none); |       border-bottom: var(--app-header-border-bottom, none); | ||||||
|       box-sizing: border-box; |       box-sizing: border-box; | ||||||
| @@ -354,7 +354,7 @@ class HassioIngressView extends LitElement { | |||||||
|  |  | ||||||
|     .main-title { |     .main-title { | ||||||
|       margin: var(--margin-title); |       margin: var(--margin-title); | ||||||
|       line-height: 20px; |       line-height: var(--ha-line-height-condensed); | ||||||
|       flex-grow: 1; |       flex-grow: 1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,12 +12,12 @@ export const hassioStyle = css` | |||||||
|   h1 { |   h1 { | ||||||
|     font-size: 2em; |     font-size: 2em; | ||||||
|     margin-bottom: 8px; |     margin-bottom: 8px; | ||||||
|     font-family: var(--paper-font-headline_-_font-family); |     font-family: var(--ha-font-family-body); | ||||||
|     -webkit-font-smoothing: var(--paper-font-headline_-_-webkit-font-smoothing); |     -webkit-font-smoothing: var(--ha-font-smoothing); | ||||||
|     font-size: var(--paper-font-headline_-_font-size); |     -moz-osx-font-smoothing: var(--ha-moz-osx-font-smoothing); | ||||||
|     font-weight: var(--paper-font-headline_-_font-weight); |     font-size: var(--ha-font-size-2xl); | ||||||
|     letter-spacing: var(--paper-font-headline_-_letter-spacing); |     font-weight: var(--ha-font-weight-normal); | ||||||
|     line-height: var(--paper-font-headline_-_line-height); |     line-height: var(--ha-line-height-condensed); | ||||||
|     padding-left: 8px; |     padding-left: 8px; | ||||||
|     padding-inline-start: 8px; |     padding-inline-start: 8px; | ||||||
|     padding-inline-end: initial; |     padding-inline-end: initial; | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import "@material/mwc-button"; | import "@material/mwc-button"; | ||||||
| import "@material/mwc-list/mwc-list-item"; |  | ||||||
| import type { CSSResultGroup, TemplateResult } from "lit"; | import type { CSSResultGroup, TemplateResult } from "lit"; | ||||||
| import { css, html, LitElement } from "lit"; | import { css, html, LitElement } from "lit"; | ||||||
| import { customElement, property, state } from "lit/decorators"; | import { customElement, property, state } from "lit/decorators"; | ||||||
| @@ -197,9 +197,6 @@ class HassioCoreInfo extends LitElement { | |||||||
|           color: var(--secondary-text-color); |           color: var(--secondary-text-color); | ||||||
|           --mdc-menu-min-width: 200px; |           --mdc-menu-min-width: 200px; | ||||||
|         } |         } | ||||||
|         mwc-list-item ha-svg-icon { |  | ||||||
|           color: var(--secondary-text-color); |  | ||||||
|         } |  | ||||||
|         a { |         a { | ||||||
|           text-decoration: none; |           text-decoration: none; | ||||||
|         } |         } | ||||||
|   | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user