mirror of
				https://github.com/home-assistant/frontend.git
				synced 2025-11-04 00:19:47 +00:00 
			
		
		
		
	Compare commits
	
		
			402 Commits
		
	
	
		
			20250404.0
			...
			auto-jsdoc
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					28e3c75ff4 | ||
| 
						 | 
					b2ec3c8c37 | ||
| 
						 | 
					fe37f8fad5 | ||
| 
						 | 
					785929b370 | ||
| 
						 | 
					55cf7e635d | ||
| 
						 | 
					4b270eb444 | ||
| 
						 | 
					d0e55719d1 | ||
| 
						 | 
					87f9397643 | ||
| 
						 | 
					910e7e10a7 | ||
| 
						 | 
					e1b9b47ac7 | ||
| 
						 | 
					89e04fcc45 | ||
| 
						 | 
					93f2e75fc9 | ||
| 
						 | 
					6c671d398f | ||
| 
						 | 
					2e5c6a4d3f | ||
| 
						 | 
					04e736a51e | ||
| 
						 | 
					ec3fdc0ea7 | ||
| 
						 | 
					a7a8c25d24 | ||
| 
						 | 
					60d457c3d9 | ||
| 
						 | 
					a58b1e636d | ||
| 
						 | 
					c46368b141 | ||
| 
						 | 
					f67e7ae081 | ||
| 
						 | 
					0032c5508e | ||
| 
						 | 
					036df78de8 | ||
| 
						 | 
					617a6ba938 | ||
| 
						 | 
					76b9063aec | ||
| 
						 | 
					60c1d0a556 | ||
| 
						 | 
					193caec2df | ||
| 
						 | 
					42c8d132bf | ||
| 
						 | 
					0311a7c976 | ||
| 
						 | 
					40ffd50b8a | ||
| 
						 | 
					334991902a | ||
| 
						 | 
					c968266065 | ||
| 
						 | 
					d4fc0318f7 | ||
| 
						 | 
					8a0d3baf67 | ||
| 
						 | 
					8fc55cb6e2 | ||
| 
						 | 
					d6ebd9bfc4 | ||
| 
						 | 
					15ae37d077 | ||
| 
						 | 
					461d5eb687 | ||
| 
						 | 
					3058fcad46 | ||
| 
						 | 
					06bd1ae4cd | ||
| 
						 | 
					00733357a1 | ||
| 
						 | 
					665c971822 | ||
| 
						 | 
					eff5471dd1 | ||
| 
						 | 
					4fba9c3c0a | ||
| 
						 | 
					0b32b51e2f | ||
| 
						 | 
					6370b0b8e5 | ||
| 
						 | 
					681518f443 | ||
| 
						 | 
					9f5b89978d | ||
| 
						 | 
					130839ee7b | ||
| 
						 | 
					ba4ec960c8 | ||
| 
						 | 
					6692d9c6aa | ||
| 
						 | 
					4d2d94c54f | ||
| 
						 | 
					d59c6612c6 | ||
| 
						 | 
					498f158253 | ||
| 
						 | 
					b8026ccf46 | ||
| 
						 | 
					84def48222 | ||
| 
						 | 
					cea0ac02fe | ||
| 
						 | 
					e1b099e88b | ||
| 
						 | 
					d571ef3f18 | ||
| 
						 | 
					c8cffef647 | ||
| 
						 | 
					6b568307a4 | ||
| 
						 | 
					1b501907f1 | ||
| 
						 | 
					c7e79998a4 | ||
| 
						 | 
					03ccf014d9 | ||
| 
						 | 
					ab41bdb87d | ||
| 
						 | 
					821a0bc418 | ||
| 
						 | 
					6d931b9e37 | ||
| 
						 | 
					b823a3b139 | ||
| 
						 | 
					47c9a407e6 | ||
| 
						 | 
					c0ba48beb6 | ||
| 
						 | 
					075e1df204 | ||
| 
						 | 
					22c57853b4 | ||
| 
						 | 
					fe824062a5 | ||
| 
						 | 
					92bf9b4979 | ||
| 
						 | 
					ac616a4d3d | ||
| 
						 | 
					1aa1bfda2c | ||
| 
						 | 
					38a5035d68 | ||
| 
						 | 
					042cd0d3a3 | ||
| 
						 | 
					00d708fbd4 | ||
| 
						 | 
					852278e8aa | ||
| 
						 | 
					15dcdffe55 | ||
| 
						 | 
					0729aaacb8 | ||
| 
						 | 
					92b8cd8f45 | ||
| 
						 | 
					ad8d3dd598 | ||
| 
						 | 
					d618c25095 | ||
| 
						 | 
					83289bdd41 | ||
| 
						 | 
					c7882f3926 | ||
| 
						 | 
					7434b12d9f | ||
| 
						 | 
					9081441d95 | ||
| 
						 | 
					d63f610023 | ||
| 
						 | 
					e069875432 | ||
| 
						 | 
					91026b0986 | ||
| 
						 | 
					4ec5fbc9a4 | ||
| 
						 | 
					fb3a59272d | ||
| 
						 | 
					c49b0803cd | ||
| 
						 | 
					9155c85509 | ||
| 
						 | 
					9d74cd7561 | ||
| 
						 | 
					22ddcca954 | ||
| 
						 | 
					8f422357f1 | ||
| 
						 | 
					44f5f7bdb5 | ||
| 
						 | 
					83819a9be0 | ||
| 
						 | 
					3c9dce20e2 | ||
| 
						 | 
					a19e7002ea | ||
| 
						 | 
					75608db9b8 | ||
| 
						 | 
					08f30b714b | ||
| 
						 | 
					9983129e26 | ||
| 
						 | 
					40fe62c2ec | ||
| 
						 | 
					d7660370ab | ||
| 
						 | 
					bdad76937e | ||
| 
						 | 
					d2822308ec | ||
| 
						 | 
					99b94e799d | ||
| 
						 | 
					1fb28df1a6 | ||
| 
						 | 
					b4e8c56f58 | ||
| 
						 | 
					17cc63deba | ||
| 
						 | 
					b4f1c8755d | ||
| 
						 | 
					b0d4c699db | ||
| 
						 | 
					c07bf68161 | ||
| 
						 | 
					d1a0eaece5 | ||
| 
						 | 
					f608783551 | ||
| 
						 | 
					dddba58d38 | ||
| 
						 | 
					ebc16d6520 | ||
| 
						 | 
					4ed8ecad01 | ||
| 
						 | 
					c26fb1713d | ||
| 
						 | 
					2b7b17625e | ||
| 
						 | 
					cd3e4f55e2 | ||
| 
						 | 
					1c12aea8f6 | ||
| 
						 | 
					3722f971ca | ||
| 
						 | 
					409f665641 | ||
| 
						 | 
					5b3b17ef6d | ||
| 
						 | 
					05b49e8c80 | ||
| 
						 | 
					2dbdbb4b64 | ||
| 
						 | 
					a825b632bf | ||
| 
						 | 
					f8d706277d | ||
| 
						 | 
					221bc732fb | ||
| 
						 | 
					055c18463c | ||
| 
						 | 
					ddd51ff097 | ||
| 
						 | 
					55c75096d0 | ||
| 
						 | 
					fd3502f3bc | ||
| 
						 | 
					7d6bec01ae | ||
| 
						 | 
					0aeb8fa75c | ||
| 
						 | 
					456a44fdfd | ||
| 
						 | 
					53a0b311de | ||
| 
						 | 
					ded5ade0f2 | ||
| 
						 | 
					5d2d6dcd6c | ||
| 
						 | 
					92353ebed5 | ||
| 
						 | 
					bc582db7fc | ||
| 
						 | 
					ab415188ba | ||
| 
						 | 
					29c11978b3 | ||
| 
						 | 
					574f9e8936 | ||
| 
						 | 
					fddc00bfab | ||
| 
						 | 
					ff5cbb0613 | ||
| 
						 | 
					498d933c06 | ||
| 
						 | 
					f9fbb254bf | ||
| 
						 | 
					536602580d | ||
| 
						 | 
					c111bf1062 | ||
| 
						 | 
					0242fbc6f8 | ||
| 
						 | 
					f65a0ef4f7 | ||
| 
						 | 
					92521d4565 | ||
| 
						 | 
					66dbafb5f5 | ||
| 
						 | 
					7c46d2d2f4 | ||
| 
						 | 
					ca642d46cc | ||
| 
						 | 
					9a52185e13 | ||
| 
						 | 
					39a73774b0 | ||
| 
						 | 
					b25b170539 | ||
| 
						 | 
					6442606fc5 | ||
| 
						 | 
					1b79869c87 | ||
| 
						 | 
					672fbc6007 | ||
| 
						 | 
					e1899836bf | ||
| 
						 | 
					e90967d200 | ||
| 
						 | 
					631bfe46ba | ||
| 
						 | 
					a5762f07ac | ||
| 
						 | 
					bf7422e4c5 | ||
| 
						 | 
					45994e7989 | ||
| 
						 | 
					995e3f10ad | ||
| 
						 | 
					6464c2b602 | ||
| 
						 | 
					8901c1fb31 | ||
| 
						 | 
					1f5f18f7e7 | ||
| 
						 | 
					51ca3e277c | ||
| 
						 | 
					ee495a432f | ||
| 
						 | 
					d75ea3bb8d | ||
| 
						 | 
					40fbeaae1c | ||
| 
						 | 
					dc2c6cee21 | ||
| 
						 | 
					3b0cd9e3ae | ||
| 
						 | 
					834ece8547 | ||
| 
						 | 
					b7aa296be7 | ||
| 
						 | 
					0cab6c9e2e | ||
| 
						 | 
					94c8665528 | ||
| 
						 | 
					c7ca654926 | ||
| 
						 | 
					488599905b | ||
| 
						 | 
					221e1d9ed8 | ||
| 
						 | 
					0229f67751 | ||
| 
						 | 
					3a0c367f76 | ||
| 
						 | 
					af0854e480 | ||
| 
						 | 
					14f4120926 | ||
| 
						 | 
					e2bd464001 | ||
| 
						 | 
					eb9f81d9a1 | ||
| 
						 | 
					078209d154 | ||
| 
						 | 
					7a617600ad | ||
| 
						 | 
					ae74e3496c | ||
| 
						 | 
					c0f304ad40 | ||
| 
						 | 
					c794a2734b | ||
| 
						 | 
					e156dd36f4 | ||
| 
						 | 
					c40bf8f3cd | ||
| 
						 | 
					93485d8b57 | ||
| 
						 | 
					ce5cdaa496 | ||
| 
						 | 
					dcbaa31c96 | ||
| 
						 | 
					71b2e5f827 | ||
| 
						 | 
					d58590b534 | ||
| 
						 | 
					b2044e88b6 | ||
| 
						 | 
					94b5ed97c6 | ||
| 
						 | 
					11b8f6210f | ||
| 
						 | 
					8e778cfc32 | ||
| 
						 | 
					4c6a5ed2e3 | ||
| 
						 | 
					48c90267df | ||
| 
						 | 
					fcab356639 | ||
| 
						 | 
					a70a0d4b4a | ||
| 
						 | 
					5a34560381 | ||
| 
						 | 
					f71245893a | ||
| 
						 | 
					1e7bfd59f2 | ||
| 
						 | 
					1c15116052 | ||
| 
						 | 
					3647722824 | ||
| 
						 | 
					713dd68089 | ||
| 
						 | 
					53dd0cbaa8 | ||
| 
						 | 
					6bf8faa96a | ||
| 
						 | 
					09a17131ab | ||
| 
						 | 
					7f20b2d6d2 | ||
| 
						 | 
					fa05cd0c90 | ||
| 
						 | 
					0b7fc330b3 | ||
| 
						 | 
					6aa78794a7 | ||
| 
						 | 
					3f17548582 | ||
| 
						 | 
					0cee3c2882 | ||
| 
						 | 
					5753b3e166 | ||
| 
						 | 
					7b78d821f9 | ||
| 
						 | 
					9a4469588c | ||
| 
						 | 
					f9eadf08fd | ||
| 
						 | 
					c630176fcf | ||
| 
						 | 
					0389fbba52 | ||
| 
						 | 
					d56c7c41e2 | ||
| 
						 | 
					e74cac697e | ||
| 
						 | 
					77216e8e76 | ||
| 
						 | 
					02a8924f63 | ||
| 
						 | 
					9fc28e5abb | ||
| 
						 | 
					933fb1327a | ||
| 
						 | 
					c73a9fccb8 | ||
| 
						 | 
					38c11e738e | ||
| 
						 | 
					93c5632ee0 | ||
| 
						 | 
					5459eaff30 | ||
| 
						 | 
					b02f1037fb | ||
| 
						 | 
					3d130b790c | ||
| 
						 | 
					e23d2392d8 | ||
| 
						 | 
					d5a6e16bf8 | ||
| 
						 | 
					91a5497c60 | ||
| 
						 | 
					65dae09a49 | ||
| 
						 | 
					7e0f293d1f | ||
| 
						 | 
					2682011ae6 | ||
| 
						 | 
					1bba103a3d | ||
| 
						 | 
					e425375d55 | ||
| 
						 | 
					a2689eee63 | ||
| 
						 | 
					74741c5d69 | ||
| 
						 | 
					53426d647a | ||
| 
						 | 
					f6e4f4c0d6 | ||
| 
						 | 
					2f086f4d00 | ||
| 
						 | 
					cd91e8c07c | ||
| 
						 | 
					b3a5ea2893 | ||
| 
						 | 
					98ae0295b4 | ||
| 
						 | 
					43bb9d3401 | ||
| 
						 | 
					8ad4385d67 | ||
| 
						 | 
					8fb7c1594a | ||
| 
						 | 
					4fca09f9ae | ||
| 
						 | 
					6793753755 | ||
| 
						 | 
					f4e3fdb98e | ||
| 
						 | 
					63f4cc456c | ||
| 
						 | 
					33735abfb0 | ||
| 
						 | 
					22b59b247e | ||
| 
						 | 
					6d7a40368c | ||
| 
						 | 
					fbeb457c25 | ||
| 
						 | 
					4a6834f0d9 | ||
| 
						 | 
					add417a166 | ||
| 
						 | 
					ae4f43496e | ||
| 
						 | 
					4ce792e5bf | ||
| 
						 | 
					b9433b96dc | ||
| 
						 | 
					1dfd937c94 | ||
| 
						 | 
					6a333a4774 | ||
| 
						 | 
					7742ccf631 | ||
| 
						 | 
					20f2a8d53e | ||
| 
						 | 
					ec9fbe7d77 | ||
| 
						 | 
					6fa226d30a | ||
| 
						 | 
					b76a723fd9 | ||
| 
						 | 
					5237cc72b7 | ||
| 
						 | 
					63d2718f67 | ||
| 
						 | 
					14e0666c3a | ||
| 
						 | 
					929a0b9cd4 | ||
| 
						 | 
					0541270695 | ||
| 
						 | 
					20d357fb13 | ||
| 
						 | 
					6658c10b94 | ||
| 
						 | 
					c2ce02652b | ||
| 
						 | 
					634db1944f | ||
| 
						 | 
					21b3177f95 | ||
| 
						 | 
					7383e3247b | ||
| 
						 | 
					b33e4bf305 | ||
| 
						 | 
					9d9522cade | ||
| 
						 | 
					430e47c0fc | ||
| 
						 | 
					a6c9702ab2 | ||
| 
						 | 
					e3122e8e4d | ||
| 
						 | 
					c8e46bd239 | ||
| 
						 | 
					4fd87a1d7c | ||
| 
						 | 
					80151ff759 | ||
| 
						 | 
					5f187c1bb3 | ||
| 
						 | 
					ddc04dd48a | ||
| 
						 | 
					228acf1fae | ||
| 
						 | 
					74acd7ec38 | ||
| 
						 | 
					9bc867d0dc | ||
| 
						 | 
					590df8dd1a | ||
| 
						 | 
					ccee57f4a5 | ||
| 
						 | 
					828bf977b2 | ||
| 
						 | 
					a2b3ea2ac6 | ||
| 
						 | 
					9c3f77532c | ||
| 
						 | 
					4a1cf250c4 | ||
| 
						 | 
					9df5141aac | ||
| 
						 | 
					13aeb02b53 | ||
| 
						 | 
					f0f60bae78 | ||
| 
						 | 
					d1465a79ae | ||
| 
						 | 
					6fe8af7c75 | ||
| 
						 | 
					21180d066e | ||
| 
						 | 
					dec968af54 | ||
| 
						 | 
					2ccc5355c4 | ||
| 
						 | 
					316c3f4e1f | ||
| 
						 | 
					f88d0ca613 | ||
| 
						 | 
					edd4a3c31f | ||
| 
						 | 
					a7ee98e7de | ||
| 
						 | 
					1b6ed8cdc3 | ||
| 
						 | 
					671049beb2 | ||
| 
						 | 
					daf4158fa0 | ||
| 
						 | 
					848713858f | ||
| 
						 | 
					f0ef7e0c53 | ||
| 
						 | 
					e10b0fad95 | ||
| 
						 | 
					8d50bb1d2b | ||
| 
						 | 
					a15f0c7814 | ||
| 
						 | 
					e37f7219c2 | ||
| 
						 | 
					570076c539 | ||
| 
						 | 
					cfeb0336d1 | ||
| 
						 | 
					b18cc4dcfb | ||
| 
						 | 
					e271989cee | ||
| 
						 | 
					ca223f9d73 | ||
| 
						 | 
					8fb1cf35ad | ||
| 
						 | 
					9f59be492e | ||
| 
						 | 
					8429d114a8 | ||
| 
						 | 
					4fbc155f8b | ||
| 
						 | 
					cd39e2d0f2 | ||
| 
						 | 
					a23f57256c | ||
| 
						 | 
					c279efaa99 | ||
| 
						 | 
					c4389ec119 | ||
| 
						 | 
					50d632f8d4 | ||
| 
						 | 
					dba2fba828 | ||
| 
						 | 
					3890afddb9 | ||
| 
						 | 
					76f187ee2c | ||
| 
						 | 
					488b54cf19 | ||
| 
						 | 
					29d2c29af3 | ||
| 
						 | 
					a2f9101a9f | ||
| 
						 | 
					7893eba7a7 | ||
| 
						 | 
					94ced8af32 | ||
| 
						 | 
					c4b5882b2d | ||
| 
						 | 
					6e8bac2e58 | ||
| 
						 | 
					8a2ab2eab4 | ||
| 
						 | 
					c7e5be185d | ||
| 
						 | 
					e98721aa76 | ||
| 
						 | 
					4c8d661c63 | ||
| 
						 | 
					b7c60ffc74 | ||
| 
						 | 
					db6c728cd6 | ||
| 
						 | 
					34f8335a9d | ||
| 
						 | 
					ecf5068bd0 | ||
| 
						 | 
					0a2a2b8a70 | ||
| 
						 | 
					52f4fe6bc0 | ||
| 
						 | 
					a781bca94b | ||
| 
						 | 
					63b44c25f8 | ||
| 
						 | 
					b96319703a | ||
| 
						 | 
					9e686190f6 | ||
| 
						 | 
					5ca7b1d508 | ||
| 
						 | 
					7c1d74c6c3 | ||
| 
						 | 
					d257f667c1 | ||
| 
						 | 
					842a064682 | ||
| 
						 | 
					3d8e146582 | ||
| 
						 | 
					78e8bd4305 | ||
| 
						 | 
					0152a79bd5 | ||
| 
						 | 
					f5bb72f067 | ||
| 
						 | 
					9ca6a886f5 | ||
| 
						 | 
					f39011f8f4 | ||
| 
						 | 
					8b190867e3 | ||
| 
						 | 
					321b15a270 | ||
| 
						 | 
					6ba235d540 | ||
| 
						 | 
					e34fd8161c | ||
| 
						 | 
					084cda8218 | ||
| 
						 | 
					f06a0fa34c | ||
| 
						 | 
					750c59399b | ||
| 
						 | 
					a6a17cd70c | ||
| 
						 | 
					de1c6a5178 | ||
| 
						 | 
					04c3cd7d68 | ||
| 
						 | 
					17ef74d680 | ||
| 
						 | 
					098c6a2567 | ||
| 
						 | 
					899288ae43 | ||
| 
						 | 
					a9823f30e3 | ||
| 
						 | 
					97966805fa | 
@@ -21,7 +21,8 @@
 | 
			
		||||
        "esbenp.prettier-vscode",
 | 
			
		||||
        "runem.lit-plugin",
 | 
			
		||||
        "github.vscode-pull-request-github",
 | 
			
		||||
        "eamodio.gitlens"
 | 
			
		||||
        "eamodio.gitlens",
 | 
			
		||||
        "yeion7.styled-global-variables-autocomplete"
 | 
			
		||||
      ],
 | 
			
		||||
      "settings": {
 | 
			
		||||
        "files.eol": "\n",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								.github/workflows/cast_deployment.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								.github/workflows/cast_deployment.yaml
									
									
									
									
										vendored
									
									
								
							@@ -26,7 +26,7 @@ jobs:
 | 
			
		||||
          ref: dev
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node
 | 
			
		||||
        uses: actions/setup-node@v4.3.0
 | 
			
		||||
        uses: actions/setup-node@v4.4.0
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: ".nvmrc"
 | 
			
		||||
          cache: yarn
 | 
			
		||||
@@ -41,9 +41,8 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - name: Deploy to Netlify
 | 
			
		||||
        id: deploy
 | 
			
		||||
        uses: netlify/actions/cli@master
 | 
			
		||||
        with:
 | 
			
		||||
          args: deploy --dir=cast/dist --alias dev
 | 
			
		||||
        run: |
 | 
			
		||||
          npx -y netlify-cli deploy --dir=cast/dist --alias dev
 | 
			
		||||
        env:
 | 
			
		||||
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
 | 
			
		||||
          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_CAST_SITE_ID }}
 | 
			
		||||
@@ -62,7 +61,7 @@ jobs:
 | 
			
		||||
          ref: master
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node
 | 
			
		||||
        uses: actions/setup-node@v4.3.0
 | 
			
		||||
        uses: actions/setup-node@v4.4.0
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: ".nvmrc"
 | 
			
		||||
          cache: yarn
 | 
			
		||||
@@ -77,9 +76,8 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - name: Deploy to Netlify
 | 
			
		||||
        id: deploy
 | 
			
		||||
        uses: netlify/actions/cli@master
 | 
			
		||||
        with:
 | 
			
		||||
          args: deploy --dir=cast/dist --prod
 | 
			
		||||
        run: |
 | 
			
		||||
          npx -y netlify-cli deploy --dir=cast/dist --prod
 | 
			
		||||
        env:
 | 
			
		||||
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
 | 
			
		||||
          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
 | 
			
		||||
        uses: actions/checkout@v4.2.2
 | 
			
		||||
      - name: Setup Node
 | 
			
		||||
        uses: actions/setup-node@v4.3.0
 | 
			
		||||
        uses: actions/setup-node@v4.4.0
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: ".nvmrc"
 | 
			
		||||
          cache: yarn
 | 
			
		||||
@@ -60,7 +60,7 @@ jobs:
 | 
			
		||||
      - name: Check out files from GitHub
 | 
			
		||||
        uses: actions/checkout@v4.2.2
 | 
			
		||||
      - name: Setup Node
 | 
			
		||||
        uses: actions/setup-node@v4.3.0
 | 
			
		||||
        uses: actions/setup-node@v4.4.0
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: ".nvmrc"
 | 
			
		||||
          cache: yarn
 | 
			
		||||
@@ -78,7 +78,7 @@ jobs:
 | 
			
		||||
      - name: Check out files from GitHub
 | 
			
		||||
        uses: actions/checkout@v4.2.2
 | 
			
		||||
      - name: Setup Node
 | 
			
		||||
        uses: actions/setup-node@v4.3.0
 | 
			
		||||
        uses: actions/setup-node@v4.4.0
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: ".nvmrc"
 | 
			
		||||
          cache: yarn
 | 
			
		||||
@@ -102,7 +102,7 @@ jobs:
 | 
			
		||||
      - name: Check out files from GitHub
 | 
			
		||||
        uses: actions/checkout@v4.2.2
 | 
			
		||||
      - name: Setup Node
 | 
			
		||||
        uses: actions/setup-node@v4.3.0
 | 
			
		||||
        uses: actions/setup-node@v4.4.0
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: ".nvmrc"
 | 
			
		||||
          cache: yarn
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								.github/workflows/demo_deployment.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								.github/workflows/demo_deployment.yaml
									
									
									
									
										vendored
									
									
								
							@@ -27,7 +27,7 @@ jobs:
 | 
			
		||||
          ref: dev
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node
 | 
			
		||||
        uses: actions/setup-node@v4.3.0
 | 
			
		||||
        uses: actions/setup-node@v4.4.0
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: ".nvmrc"
 | 
			
		||||
          cache: yarn
 | 
			
		||||
@@ -42,9 +42,8 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - name: Deploy to Netlify
 | 
			
		||||
        id: deploy
 | 
			
		||||
        uses: netlify/actions/cli@master
 | 
			
		||||
        with:
 | 
			
		||||
          args: deploy --dir=demo/dist --prod
 | 
			
		||||
        run: |
 | 
			
		||||
          npx -y netlify-cli deploy --dir=demo/dist --prod
 | 
			
		||||
        env:
 | 
			
		||||
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
 | 
			
		||||
          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_DEMO_DEV_SITE_ID }}
 | 
			
		||||
@@ -63,7 +62,7 @@ jobs:
 | 
			
		||||
          ref: master
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node
 | 
			
		||||
        uses: actions/setup-node@v4.3.0
 | 
			
		||||
        uses: actions/setup-node@v4.4.0
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: ".nvmrc"
 | 
			
		||||
          cache: yarn
 | 
			
		||||
@@ -78,9 +77,8 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - name: Deploy to Netlify
 | 
			
		||||
        id: deploy
 | 
			
		||||
        uses: netlify/actions/cli@master
 | 
			
		||||
        with:
 | 
			
		||||
          args: deploy --dir=demo/dist --prod
 | 
			
		||||
        run: |
 | 
			
		||||
          npx -y netlify-cli deploy --dir=demo/dist --prod
 | 
			
		||||
        env:
 | 
			
		||||
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
 | 
			
		||||
          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
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node
 | 
			
		||||
        uses: actions/setup-node@v4.3.0
 | 
			
		||||
        uses: actions/setup-node@v4.4.0
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: ".nvmrc"
 | 
			
		||||
          cache: yarn
 | 
			
		||||
@@ -34,9 +34,8 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - name: Deploy to Netlify
 | 
			
		||||
        id: deploy
 | 
			
		||||
        uses: netlify/actions/cli@master
 | 
			
		||||
        with:
 | 
			
		||||
          args: deploy --dir=gallery/dist --prod
 | 
			
		||||
        run: |
 | 
			
		||||
          npx -y netlify-cli deploy --dir=gallery/dist --prod
 | 
			
		||||
        env:
 | 
			
		||||
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
 | 
			
		||||
          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
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node
 | 
			
		||||
        uses: actions/setup-node@v4.3.0
 | 
			
		||||
        uses: actions/setup-node@v4.4.0
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: ".nvmrc"
 | 
			
		||||
          cache: yarn
 | 
			
		||||
@@ -39,13 +39,14 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - name: Deploy preview to Netlify
 | 
			
		||||
        id: deploy
 | 
			
		||||
        uses: netlify/actions/cli@master
 | 
			
		||||
        with:
 | 
			
		||||
          args: deploy --dir=gallery/dist --alias "deploy-preview-${{ github.event.number }}"
 | 
			
		||||
        run: |
 | 
			
		||||
          npx -y netlify-cli deploy --dir=gallery/dist --alias "deploy-preview-${{ github.event.number }}" \
 | 
			
		||||
            --json > deploy_output.json
 | 
			
		||||
        env:
 | 
			
		||||
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
 | 
			
		||||
          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_GALLERY_SITE_ID }}
 | 
			
		||||
 | 
			
		||||
      - name: Generate summary
 | 
			
		||||
        run: |
 | 
			
		||||
          echo "${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}" >> "$GITHUB_STEP_SUMMARY"
 | 
			
		||||
          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 }}
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node
 | 
			
		||||
        uses: actions/setup-node@v4.3.0
 | 
			
		||||
        uses: actions/setup-node@v4.4.0
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: ".nvmrc"
 | 
			
		||||
          cache: yarn
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node
 | 
			
		||||
        uses: actions/setup-node@v4.3.0
 | 
			
		||||
        uses: actions/setup-node@v4.4.0
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: ".nvmrc"
 | 
			
		||||
          cache: yarn
 | 
			
		||||
@@ -55,7 +55,7 @@ jobs:
 | 
			
		||||
          script/release
 | 
			
		||||
 | 
			
		||||
      - name: Upload release assets
 | 
			
		||||
        uses: softprops/action-gh-release@v2.2.1
 | 
			
		||||
        uses: softprops/action-gh-release@v2.2.2
 | 
			
		||||
        with:
 | 
			
		||||
          files: |
 | 
			
		||||
            dist/*.whl
 | 
			
		||||
@@ -74,7 +74,7 @@ jobs:
 | 
			
		||||
          echo "home-assistant-frontend==$version" > ./requirements.txt
 | 
			
		||||
 | 
			
		||||
      - name: Build wheels
 | 
			
		||||
        uses: home-assistant/wheels@2025.02.0
 | 
			
		||||
        uses: home-assistant/wheels@2025.03.0
 | 
			
		||||
        with:
 | 
			
		||||
          abi: cp313
 | 
			
		||||
          tag: musllinux_1_2
 | 
			
		||||
@@ -92,7 +92,7 @@ jobs:
 | 
			
		||||
      - name: Checkout the repository
 | 
			
		||||
        uses: actions/checkout@v4.2.2
 | 
			
		||||
      - name: Setup Node
 | 
			
		||||
        uses: actions/setup-node@v4.3.0
 | 
			
		||||
        uses: actions/setup-node@v4.4.0
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: ".nvmrc"
 | 
			
		||||
          cache: yarn
 | 
			
		||||
@@ -107,7 +107,7 @@ jobs:
 | 
			
		||||
      - name: Tar folder
 | 
			
		||||
        run: tar -czf landing-page/home_assistant_frontend_landingpage-${{ github.event.release.tag_name }}.tar.gz -C landing-page/dist .
 | 
			
		||||
      - name: Upload release asset
 | 
			
		||||
        uses: softprops/action-gh-release@v2.2.1
 | 
			
		||||
        uses: softprops/action-gh-release@v2.2.2
 | 
			
		||||
        with:
 | 
			
		||||
          files: landing-page/home_assistant_frontend_landingpage-${{ github.event.release.tag_name }}.tar.gz
 | 
			
		||||
 | 
			
		||||
@@ -121,7 +121,7 @@ jobs:
 | 
			
		||||
      - name: Checkout the repository
 | 
			
		||||
        uses: actions/checkout@v4.2.2
 | 
			
		||||
      - name: Setup Node
 | 
			
		||||
        uses: actions/setup-node@v4.3.0
 | 
			
		||||
        uses: actions/setup-node@v4.4.0
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: ".nvmrc"
 | 
			
		||||
          cache: yarn
 | 
			
		||||
@@ -136,6 +136,6 @@ jobs:
 | 
			
		||||
      - name: Tar folder
 | 
			
		||||
        run: tar -czf hassio/home_assistant_frontend_supervisor-${{ github.event.release.tag_name }}.tar.gz -C hassio/build .
 | 
			
		||||
      - name: Upload release asset
 | 
			
		||||
        uses: softprops/action-gh-release@v2.2.1
 | 
			
		||||
        uses: softprops/action-gh-release@v2.2.2
 | 
			
		||||
        with:
 | 
			
		||||
          files: hassio/home_assistant_frontend_supervisor-${{ github.event.release.tag_name }}.tar.gz
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								.vscode/extensions.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.vscode/extensions.json
									
									
									
									
										vendored
									
									
								
							@@ -5,6 +5,7 @@
 | 
			
		||||
    "runem.lit-plugin",
 | 
			
		||||
    "github.vscode-pull-request-github",
 | 
			
		||||
    "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
											
										
									
								
							
							
								
								
									
										948
									
								
								.yarn/releases/yarn-4.9.1.cjs
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										948
									
								
								.yarn/releases/yarn-4.9.1.cjs
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -6,4 +6,4 @@ enableGlobalCache: false
 | 
			
		||||
 | 
			
		||||
nodeLinker: node-modules
 | 
			
		||||
 | 
			
		||||
yarnPath: .yarn/releases/yarn-4.7.0.cjs
 | 
			
		||||
yarnPath: .yarn/releases/yarn-4.9.1.cjs
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ import defineProvider from "@babel/helper-define-polyfill-provider";
 | 
			
		||||
import { join } from "node:path";
 | 
			
		||||
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
 | 
			
		||||
const polyfillSupport = {
 | 
			
		||||
 
 | 
			
		||||
@@ -20,22 +20,16 @@ module.exports.ignorePackages = () => [];
 | 
			
		||||
// Files from NPM packages that we should replace with empty file
 | 
			
		||||
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/font-icons.js"),
 | 
			
		||||
    // Icons in supervisor conflict with icons in HA so we don't load.
 | 
			
		||||
    isHassioBuild &&
 | 
			
		||||
      require.resolve(
 | 
			
		||||
        path.resolve(paths.polymer_dir, "src/components/ha-icon.ts")
 | 
			
		||||
        path.resolve(paths.root_dir, "src/components/ha-icon.ts")
 | 
			
		||||
      ),
 | 
			
		||||
    isHassioBuild &&
 | 
			
		||||
      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);
 | 
			
		||||
 | 
			
		||||
@@ -50,7 +44,8 @@ module.exports.definedVars = ({ isProdBuild, latestBuild, defineOverlay }) => ({
 | 
			
		||||
  __HASS_URL__: `\`${
 | 
			
		||||
    "HASS_URL" in process.env
 | 
			
		||||
      ? 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(
 | 
			
		||||
    isProdBuild ? "production" : "development"
 | 
			
		||||
@@ -78,6 +73,19 @@ module.exports.terserOptions = ({ latestBuild, 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 = ({
 | 
			
		||||
  latestBuild,
 | 
			
		||||
  isProdBuild,
 | 
			
		||||
@@ -102,7 +110,6 @@ module.exports.babelOptions = ({
 | 
			
		||||
        shippedProposals: true,
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
    "@babel/preset-typescript",
 | 
			
		||||
  ],
 | 
			
		||||
  plugins: [
 | 
			
		||||
    [
 | 
			
		||||
@@ -139,12 +146,6 @@ module.exports.babelOptions = ({
 | 
			
		||||
      "@babel/plugin-transform-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-private-methods",
 | 
			
		||||
  ].filter(Boolean),
 | 
			
		||||
@@ -164,7 +165,7 @@ module.exports.babelOptions = ({
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      exclude: [
 | 
			
		||||
        path.join(paths.polymer_dir, "src/resources/polyfills"),
 | 
			
		||||
        path.join(paths.root_dir, "src/resources/polyfills"),
 | 
			
		||||
        ...[
 | 
			
		||||
          "@formatjs/(?:ecma402-abstract|intl-\\w+)",
 | 
			
		||||
          "@lit-labs/virtualizer/polyfills",
 | 
			
		||||
@@ -182,6 +183,7 @@ module.exports.babelOptions = ({
 | 
			
		||||
      include: /\/node_modules\//,
 | 
			
		||||
      exclude: [
 | 
			
		||||
        "element-internals-polyfill",
 | 
			
		||||
        "@shoelace-style",
 | 
			
		||||
        "@?lit(?:-labs|-element|-html)?",
 | 
			
		||||
      ].map((p) => new RegExp(`/node_modules/${p}/`)),
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ module.exports = {
 | 
			
		||||
  },
 | 
			
		||||
  version() {
 | 
			
		||||
    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)?)"/);
 | 
			
		||||
    if (!version) {
 | 
			
		||||
      throw Error("Version not found");
 | 
			
		||||
 
 | 
			
		||||
@@ -169,14 +169,14 @@ const APP_PAGE_ENTRIES = {
 | 
			
		||||
 | 
			
		||||
gulp.task(
 | 
			
		||||
  "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(
 | 
			
		||||
  "gen-pages-app-prod",
 | 
			
		||||
  genPagesProdTask(
 | 
			
		||||
    APP_PAGE_ENTRIES,
 | 
			
		||||
    paths.polymer_dir,
 | 
			
		||||
    paths.root_dir,
 | 
			
		||||
    paths.app_output_root,
 | 
			
		||||
    paths.app_output_latest,
 | 
			
		||||
    paths.app_output_es5
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,9 @@ import { glob } from "glob";
 | 
			
		||||
import gulp from "gulp";
 | 
			
		||||
import yaml from "js-yaml";
 | 
			
		||||
import { marked } from "marked";
 | 
			
		||||
import ts from "typescript";
 | 
			
		||||
import { create } from "@custom-elements-manifest/analyzer";
 | 
			
		||||
import { litPlugin } from "@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/lit.js";
 | 
			
		||||
import path from "path";
 | 
			
		||||
import paths from "../paths.cjs";
 | 
			
		||||
import "./clean.js";
 | 
			
		||||
@@ -13,6 +16,28 @@ import "./service-worker.js";
 | 
			
		||||
import "./translations.js";
 | 
			
		||||
import "./rspack.js";
 | 
			
		||||
 | 
			
		||||
gulp.task("generate-component-docs", async function generateComponentDocs() {
 | 
			
		||||
  const filePaths = ["src/components/ha-alert.ts"];
 | 
			
		||||
 | 
			
		||||
  const modules = await Promise.all(
 | 
			
		||||
    filePaths.map(async (file) => {
 | 
			
		||||
      const filePath = path.resolve(file);
 | 
			
		||||
      console.log(`Reading ${file} -> ${filePath}`);
 | 
			
		||||
      const source = fs.readFileSync(filePath).toString();
 | 
			
		||||
 | 
			
		||||
      return ts.createSourceFile(file, source, ts.ScriptTarget.ES2015, true);
 | 
			
		||||
    })
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const manifest = create({
 | 
			
		||||
    modules,
 | 
			
		||||
    plugins: litPlugin(),
 | 
			
		||||
    context: { dev: true },
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  console.log(manifest);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
gulp.task("gather-gallery-pages", async function gatherPages() {
 | 
			
		||||
  const pageDir = path.resolve(paths.gallery_dir, "src/pages");
 | 
			
		||||
  const files = await glob(path.resolve(pageDir, "**/*"));
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,8 @@ import path from "path";
 | 
			
		||||
import paths from "../paths.cjs";
 | 
			
		||||
 | 
			
		||||
const npmPath = (...parts) =>
 | 
			
		||||
  path.resolve(paths.polymer_dir, "node_modules", ...parts);
 | 
			
		||||
const polyPath = (...parts) => path.resolve(paths.polymer_dir, ...parts);
 | 
			
		||||
  path.resolve(paths.root_dir, "node_modules", ...parts);
 | 
			
		||||
const polyPath = (...parts) => path.resolve(paths.root_dir, ...parts);
 | 
			
		||||
 | 
			
		||||
const copyFileDir = (fromFile, toDir) =>
 | 
			
		||||
  fs.copySync(fromFile, path.join(toDir, path.basename(fromFile)));
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ import gulp from "gulp";
 | 
			
		||||
import { join, resolve } from "node:path";
 | 
			
		||||
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 INTL_POLYFILLS = {
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@ const detailsClose = "</details>\n";
 | 
			
		||||
 | 
			
		||||
const dummyAPI = {
 | 
			
		||||
  version: babelVersion,
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-empty-function
 | 
			
		||||
  assertVersion: () => {},
 | 
			
		||||
  caller: (callback) =>
 | 
			
		||||
    callback({
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
const path = require("path");
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  polymer_dir: path.resolve(__dirname, ".."),
 | 
			
		||||
  root_dir: path.resolve(__dirname, ".."),
 | 
			
		||||
 | 
			
		||||
  build_dir: path.resolve(__dirname, "../build"),
 | 
			
		||||
  app_output_root: path.resolve(__dirname, "../hass_frontend"),
 | 
			
		||||
 
 | 
			
		||||
@@ -65,19 +65,26 @@ const createRspackConfig = ({
 | 
			
		||||
      rules: [
 | 
			
		||||
        {
 | 
			
		||||
          test: /\.m?js$|\.ts$/,
 | 
			
		||||
          use: (info) => ({
 | 
			
		||||
            loader: "babel-loader",
 | 
			
		||||
            options: {
 | 
			
		||||
              ...bundle.babelOptions({
 | 
			
		||||
                latestBuild,
 | 
			
		||||
                isProdBuild,
 | 
			
		||||
                isTestBuild,
 | 
			
		||||
                sw: info.issuerLayer === "sw",
 | 
			
		||||
              }),
 | 
			
		||||
              cacheDirectory: !isProdBuild,
 | 
			
		||||
              cacheCompression: false,
 | 
			
		||||
          exclude: /node_modules[\\/]core-js/,
 | 
			
		||||
          use: (info) => [
 | 
			
		||||
            {
 | 
			
		||||
              loader: "babel-loader",
 | 
			
		||||
              options: {
 | 
			
		||||
                ...bundle.babelOptions({
 | 
			
		||||
                  latestBuild,
 | 
			
		||||
                  isProdBuild,
 | 
			
		||||
                  isTestBuild,
 | 
			
		||||
                  sw: info.issuerLayer === "sw",
 | 
			
		||||
                }),
 | 
			
		||||
                cacheDirectory: !isProdBuild,
 | 
			
		||||
                cacheCompression: false,
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
          }),
 | 
			
		||||
            {
 | 
			
		||||
              loader: "builtin:swc-loader",
 | 
			
		||||
              options: bundle.swcOptions(),
 | 
			
		||||
            },
 | 
			
		||||
          ],
 | 
			
		||||
          resolve: {
 | 
			
		||||
            fullySpecified: false,
 | 
			
		||||
          },
 | 
			
		||||
@@ -136,7 +143,8 @@ const createRspackConfig = ({
 | 
			
		||||
            // calling define.amd will call require("!!webpack amd options")
 | 
			
		||||
            resource.startsWith("!!webpack") ||
 | 
			
		||||
            // loaded by webpack dev server but doesn't exist.
 | 
			
		||||
            resource === "webpack/hot"
 | 
			
		||||
            resource === "webpack/hot" ||
 | 
			
		||||
            resource.startsWith("@swc/helpers")
 | 
			
		||||
          ) {
 | 
			
		||||
            return false;
 | 
			
		||||
          }
 | 
			
		||||
@@ -161,7 +169,7 @@ const createRspackConfig = ({
 | 
			
		||||
      }),
 | 
			
		||||
      new rspack.NormalModuleReplacementPlugin(
 | 
			
		||||
        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 &&
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,3 @@
 | 
			
		||||
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-list/mwc-list";
 | 
			
		||||
 | 
			
		||||
import type { ActionDetail } from "@material/mwc-list/mwc-list";
 | 
			
		||||
import { mdiCast, mdiCastConnected, mdiViewDashboard } from "@mdi/js";
 | 
			
		||||
import type { Auth, Connection } from "home-assistant-js-websocket";
 | 
			
		||||
@@ -19,6 +19,8 @@ import {
 | 
			
		||||
import { atLeastVersion } from "../../../../src/common/config/version";
 | 
			
		||||
import { toggleAttribute } from "../../../../src/common/dom/toggle_attribute";
 | 
			
		||||
import "../../../../src/components/ha-icon";
 | 
			
		||||
import "../../../../src/components/ha-list";
 | 
			
		||||
import "../../../../src/components/ha-list-item";
 | 
			
		||||
import "../../../../src/components/ha-svg-icon";
 | 
			
		||||
import {
 | 
			
		||||
  getLegacyLovelaceCollection,
 | 
			
		||||
@@ -29,7 +31,6 @@ import type { LovelaceViewConfig } from "../../../../src/data/lovelace/config/vi
 | 
			
		||||
import "../../../../src/layouts/hass-loading-screen";
 | 
			
		||||
import { generateDefaultViewConfig } from "../../../../src/panels/lovelace/common/generate-lovelace-config";
 | 
			
		||||
import "./hc-layout";
 | 
			
		||||
import "../../../../src/components/ha-list-item";
 | 
			
		||||
 | 
			
		||||
@customElement("hc-cast")
 | 
			
		||||
class HcCast extends LitElement {
 | 
			
		||||
@@ -85,7 +86,7 @@ class HcCast extends LitElement {
 | 
			
		||||
              `
 | 
			
		||||
            : html`
 | 
			
		||||
                <div class="section-header">PICK A VIEW</div>
 | 
			
		||||
                <mwc-list @action=${this._handlePickView} activatable>
 | 
			
		||||
                <ha-list @action=${this._handlePickView} activatable>
 | 
			
		||||
                  ${(
 | 
			
		||||
                    this.lovelaceViews ?? [
 | 
			
		||||
                      generateDefaultViewConfig({}, {}, {}, {}, () => ""),
 | 
			
		||||
@@ -113,7 +114,7 @@ class HcCast extends LitElement {
 | 
			
		||||
                            ></ha-svg-icon>`}
 | 
			
		||||
                      </ha-list-item>
 | 
			
		||||
                    `
 | 
			
		||||
                  )}</mwc-list
 | 
			
		||||
                  )}</ha-list
 | 
			
		||||
                >
 | 
			
		||||
              `}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -302,7 +302,7 @@ export class HcConnect extends LitElement {
 | 
			
		||||
    }
 | 
			
		||||
    .error {
 | 
			
		||||
      color: red;
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .error a {
 | 
			
		||||
 
 | 
			
		||||
@@ -86,7 +86,7 @@ class HcLayout extends LitElement {
 | 
			
		||||
    .card-header {
 | 
			
		||||
      color: var(--ha-card-header-color, var(--primary-text-color));
 | 
			
		||||
      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;
 | 
			
		||||
      line-height: 32px;
 | 
			
		||||
      padding: 24px 16px 16px;
 | 
			
		||||
@@ -98,7 +98,7 @@ class HcLayout extends LitElement {
 | 
			
		||||
      border-radius: 4px 4px 0 0;
 | 
			
		||||
    }
 | 
			
		||||
    .subtitle {
 | 
			
		||||
      font-size: 14px;
 | 
			
		||||
      font-size: var(--ha-font-size-m);
 | 
			
		||||
      color: var(--secondary-text-color);
 | 
			
		||||
      line-height: initial;
 | 
			
		||||
    }
 | 
			
		||||
@@ -113,7 +113,7 @@ class HcLayout extends LitElement {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    :host ::slotted(.section-header) {
 | 
			
		||||
      font-weight: 500;
 | 
			
		||||
      font-weight: var(--ha-font-weight-medium);
 | 
			
		||||
      padding: 4px 16px;
 | 
			
		||||
      text-transform: uppercase;
 | 
			
		||||
    }
 | 
			
		||||
@@ -135,7 +135,7 @@ class HcLayout extends LitElement {
 | 
			
		||||
 | 
			
		||||
    .footer {
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      font-size: 12px;
 | 
			
		||||
      font-size: var(--ha-font-size-s);
 | 
			
		||||
      padding: 8px 0 24px;
 | 
			
		||||
      color: var(--secondary-text-color);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ class HcLaunchScreen extends LitElement {
 | 
			
		||||
      display: block;
 | 
			
		||||
      height: 100vh;
 | 
			
		||||
      background-color: #f2f4f9;
 | 
			
		||||
      font-size: 24px;
 | 
			
		||||
      font-size: var(--ha-font-size-2xl);
 | 
			
		||||
    }
 | 
			
		||||
    .container {
 | 
			
		||||
      display: flex;
 | 
			
		||||
 
 | 
			
		||||
@@ -109,7 +109,7 @@ export class HcMain extends HassElement {
 | 
			
		||||
  protected firstUpdated(changedProps) {
 | 
			
		||||
    super.firstUpdated(changedProps);
 | 
			
		||||
    import("./hc-lovelace");
 | 
			
		||||
    import("../../../../src/resources/ha-style");
 | 
			
		||||
    import("../../../../src/resources/append-ha-style");
 | 
			
		||||
 | 
			
		||||
    window.addEventListener("location-changed", () => {
 | 
			
		||||
      const panelPath = `/${this._urlPath || "lovelace"}/`;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										186
									
								
								custom-elements.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								custom-elements.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,186 @@
 | 
			
		||||
{
 | 
			
		||||
  "schemaVersion": "1.0.0",
 | 
			
		||||
  "readme": "",
 | 
			
		||||
  "modules": [
 | 
			
		||||
    {
 | 
			
		||||
      "kind": "javascript-module",
 | 
			
		||||
      "path": "src/components/ha-alert.ts",
 | 
			
		||||
      "declarations": [
 | 
			
		||||
        {
 | 
			
		||||
          "kind": "class",
 | 
			
		||||
          "description": "A custom alert component for displaying messages with various alert types.",
 | 
			
		||||
          "name": "HaAlert",
 | 
			
		||||
          "cssProperties": [
 | 
			
		||||
            {
 | 
			
		||||
              "description": "The color used for \"info\" alerts.",
 | 
			
		||||
              "name": "--info-color"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "description": "The color used for \"warning\" alerts.",
 | 
			
		||||
              "name": "--warning-color"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "description": "The color used for \"error\" alerts.",
 | 
			
		||||
              "name": "--error-color"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "description": "The color used for \"success\" alerts.",
 | 
			
		||||
              "name": "--success-color"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "description": "The primary text color used in the alert.",
 | 
			
		||||
              "name": "--primary-text-color"
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          "cssParts": [
 | 
			
		||||
            {
 | 
			
		||||
              "description": "The container for the alert.",
 | 
			
		||||
              "name": "issue-type"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "description": "The container for the alert icon.",
 | 
			
		||||
              "name": "icon"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "description": "The container for the alert content.",
 | 
			
		||||
              "name": "content"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "description": "The container for the alert actions.",
 | 
			
		||||
              "name": "action"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "description": "The container for the alert title.",
 | 
			
		||||
              "name": "title"
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          "slots": [
 | 
			
		||||
            {
 | 
			
		||||
              "description": "The main content of the alert.",
 | 
			
		||||
              "name": ""
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "description": "Slot for providing a custom icon for the alert.",
 | 
			
		||||
              "name": "icon"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "description": "Slot for providing custom actions or buttons for the alert.",
 | 
			
		||||
              "name": "action"
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          "members": [
 | 
			
		||||
            {
 | 
			
		||||
              "kind": "field",
 | 
			
		||||
              "name": "title",
 | 
			
		||||
              "type": {
 | 
			
		||||
                "text": "string"
 | 
			
		||||
              },
 | 
			
		||||
              "privacy": "public",
 | 
			
		||||
              "default": "\"\"",
 | 
			
		||||
              "description": "The title of the alert. Defaults to an empty string.",
 | 
			
		||||
              "attribute": "title"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "kind": "field",
 | 
			
		||||
              "name": "alertType",
 | 
			
		||||
              "type": {
 | 
			
		||||
                "text": "\"info\" | \"warning\" | \"error\" | \"success\""
 | 
			
		||||
              },
 | 
			
		||||
              "privacy": "public",
 | 
			
		||||
              "default": "\"info\"",
 | 
			
		||||
              "description": "The type of alert to display. Defaults to \"info\". Determines the styling and icon used.",
 | 
			
		||||
              "attribute": "alert-type"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "kind": "field",
 | 
			
		||||
              "name": "dismissable",
 | 
			
		||||
              "type": {
 | 
			
		||||
                "text": "boolean"
 | 
			
		||||
              },
 | 
			
		||||
              "privacy": "public",
 | 
			
		||||
              "default": "false",
 | 
			
		||||
              "description": "Whether the alert can be dismissed. Defaults to `false`. If `true`, a dismiss button is displayed.",
 | 
			
		||||
              "attribute": "dismissable"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "kind": "field",
 | 
			
		||||
              "name": "narrow",
 | 
			
		||||
              "type": {
 | 
			
		||||
                "text": "boolean"
 | 
			
		||||
              },
 | 
			
		||||
              "privacy": "public",
 | 
			
		||||
              "default": "false",
 | 
			
		||||
              "description": "Whether the alert should use a narrow layout. Defaults to `false`.",
 | 
			
		||||
              "attribute": "narrow"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "kind": "method",
 | 
			
		||||
              "name": "_dismissClicked",
 | 
			
		||||
              "privacy": "private"
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          "events": [
 | 
			
		||||
            {
 | 
			
		||||
              "description": "Fired when the dismiss button is clicked.",
 | 
			
		||||
              "name": "alert-dismissed-clicked"
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          "attributes": [
 | 
			
		||||
            {
 | 
			
		||||
              "name": "title",
 | 
			
		||||
              "type": {
 | 
			
		||||
                "text": "string"
 | 
			
		||||
              },
 | 
			
		||||
              "default": "\"\"",
 | 
			
		||||
              "description": "The title of the alert. Defaults to an empty string.",
 | 
			
		||||
              "fieldName": "title"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "name": "alert-type",
 | 
			
		||||
              "type": {
 | 
			
		||||
                "text": "\"info\" | \"warning\" | \"error\" | \"success\""
 | 
			
		||||
              },
 | 
			
		||||
              "default": "\"info\"",
 | 
			
		||||
              "description": "The type of alert to display. Defaults to \"info\". Determines the styling and icon used.",
 | 
			
		||||
              "fieldName": "alertType"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "name": "dismissable",
 | 
			
		||||
              "type": {
 | 
			
		||||
                "text": "boolean"
 | 
			
		||||
              },
 | 
			
		||||
              "default": "false",
 | 
			
		||||
              "description": "Whether the alert can be dismissed. Defaults to `false`. If `true`, a dismiss button is displayed.",
 | 
			
		||||
              "fieldName": "dismissable"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "name": "narrow",
 | 
			
		||||
              "type": {
 | 
			
		||||
                "text": "boolean"
 | 
			
		||||
              },
 | 
			
		||||
              "default": "false",
 | 
			
		||||
              "description": "Whether the alert should use a narrow layout. Defaults to `false`.",
 | 
			
		||||
              "fieldName": "narrow"
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          "superclass": {
 | 
			
		||||
            "name": "LitElement",
 | 
			
		||||
            "package": "lit"
 | 
			
		||||
          },
 | 
			
		||||
          "tagName": "ha-alert",
 | 
			
		||||
          "customElement": true
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      "exports": [
 | 
			
		||||
        {
 | 
			
		||||
          "kind": "custom-element-definition",
 | 
			
		||||
          "name": "ha-alert",
 | 
			
		||||
          "declaration": {
 | 
			
		||||
            "name": "HaAlert",
 | 
			
		||||
            "module": "src/components/ha-alert.ts"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
@@ -1,37 +1,28 @@
 | 
			
		||||
export const demoThemeJimpower = () => ({
 | 
			
		||||
  "text-primary-color": "var(--primary-text-color)",
 | 
			
		||||
  "paper-item-icon-color": "var(--primary-text-color)",
 | 
			
		||||
  "primary-color": "#5294E2",
 | 
			
		||||
  "label-badge-red": "var(--accent-color)",
 | 
			
		||||
  "paper-tabs-selection-bar-color": "green",
 | 
			
		||||
  "light-primary-color": "var(--accent-color)",
 | 
			
		||||
  "primary-background-color": "#383C45",
 | 
			
		||||
  "primary-text-color": "#FFFFFF",
 | 
			
		||||
  "paper-item-selected_-_background-color": "#434954",
 | 
			
		||||
  "secondary-background-color": "#383C45",
 | 
			
		||||
  "disabled-text-color": "#7F848E",
 | 
			
		||||
  "paper-item-icon_-_color": "green",
 | 
			
		||||
  "paper-grey-200": "#414A59",
 | 
			
		||||
  "label-badge-background-color": "#2E333A",
 | 
			
		||||
  "paper-card-header-color": "var(--accent-color)",
 | 
			
		||||
  "sidebar-icon-color": "var(--paper-item-icon-color)",
 | 
			
		||||
  "paper-listbox-background-color": "#2E333A",
 | 
			
		||||
  "sidebar-icon-color": "var(--state-icon-color)",
 | 
			
		||||
  "table-row-background-color": "#353840",
 | 
			
		||||
  "paper-grey-50": "var(--primary-text-color)",
 | 
			
		||||
  "switch-checked-color": "var(--accent-color)",
 | 
			
		||||
  "paper-dialog-background-color": "#434954",
 | 
			
		||||
  "secondary-text-color": "#5294E2",
 | 
			
		||||
  "error-color": "#E45E65",
 | 
			
		||||
  "divider-color": "rgba(0, 0, 0, .12)",
 | 
			
		||||
  "success-color": "#39E949",
 | 
			
		||||
  "switch-unchecked-button-color": "var(--disabled-text-color)",
 | 
			
		||||
  "label-badge-border-color": "green",
 | 
			
		||||
  "paper-listbox-color": "var(--primary-color)",
 | 
			
		||||
  "card-background-color": "#434954",
 | 
			
		||||
  "label-badge-text-color": "var(--primary-text-color)",
 | 
			
		||||
  "switch-unchecked-track-color": "var(--disabled-text-color)",
 | 
			
		||||
  "dark-primary-color": "var(--accent-color)",
 | 
			
		||||
  "paper-item-icon-active-color": "#F9C536",
 | 
			
		||||
  "accent-color": "#E45E65",
 | 
			
		||||
  "table-row-alternative-background-color": "#3E424B",
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,38 +1,29 @@
 | 
			
		||||
// https://community.home-assistant.io/t/slate-a-new-dark-theme/86410
 | 
			
		||||
export const demoThemeKernehed = () => ({
 | 
			
		||||
  "text-primary-color": "var(--primary-text-color)",
 | 
			
		||||
  "paper-item-icon-color": "var(--primary-text-color)",
 | 
			
		||||
  "primary-color": "#2980b9",
 | 
			
		||||
  "label-badge-red": "var(--accent-color)",
 | 
			
		||||
  "paper-tabs-selection-bar-color": "green",
 | 
			
		||||
  "primary-text-color": "#FFFFFF",
 | 
			
		||||
  "light-primary-color": "var(--accent-color)",
 | 
			
		||||
  "primary-background-color": "#222222",
 | 
			
		||||
  "sidebar-icon-color": "#777777",
 | 
			
		||||
  "paper-item-selected_-_background-color": "#292929",
 | 
			
		||||
  "secondary-background-color": "#222222",
 | 
			
		||||
  "disabled-text-color": "#777777",
 | 
			
		||||
  "paper-item-icon_-_color": "green",
 | 
			
		||||
  "paper-grey-200": "#222222",
 | 
			
		||||
  "label-badge-background-color": "#222222",
 | 
			
		||||
  "paper-card-header-color": "var(--accent-color)",
 | 
			
		||||
  "paper-listbox-background-color": "#141414",
 | 
			
		||||
  "table-row-background-color": "#292929",
 | 
			
		||||
  "paper-grey-50": "var(--primary-text-color)",
 | 
			
		||||
  "switch-checked-color": "var(--accent-color)",
 | 
			
		||||
  "paper-dialog-background-color": "#292929",
 | 
			
		||||
  "secondary-text-color": "#b58e31",
 | 
			
		||||
  "error-color": "#b58e31",
 | 
			
		||||
  "divider-color": "rgba(0, 0, 0, .12)",
 | 
			
		||||
  "success-color": "#2980b9",
 | 
			
		||||
  "switch-unchecked-button-color": "var(--disabled-text-color)",
 | 
			
		||||
  "label-badge-border-color": "green",
 | 
			
		||||
  "paper-listbox-color": "#777777",
 | 
			
		||||
  "card-background-color": "#292929",
 | 
			
		||||
  "label-badge-text-color": "var(--primary-text-color)",
 | 
			
		||||
  "switch-unchecked-track-color": "var(--disabled-text-color)",
 | 
			
		||||
  "dark-primary-color": "var(--accent-color)",
 | 
			
		||||
  "paper-item-icon-active-color": "#b58e31",
 | 
			
		||||
  "accent-color": "#2980b9",
 | 
			
		||||
  "table-row-alternative-background-color": "#292929",
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,26 +1,18 @@
 | 
			
		||||
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-item-icon-color": "#d3d3d3",
 | 
			
		||||
  "divider-color": "rgba(255, 255, 255, 0.12)",
 | 
			
		||||
  "primary-color": "#389638",
 | 
			
		||||
  "light-primary-color": "#6f956f",
 | 
			
		||||
  "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)",
 | 
			
		||||
  "card-background-color": "#4e4e4e",
 | 
			
		||||
  "label-badge-text-color": "var(--text-primary-color)",
 | 
			
		||||
  "primary-background-color": "#303030",
 | 
			
		||||
  "sidebar-icon-color": "var(--paper-item-icon-color)",
 | 
			
		||||
  "sidebar-icon-color": "#d3d3d3",
 | 
			
		||||
  "secondary-background-color": "#2b2b2b",
 | 
			
		||||
  "paper-item-icon-active-color": "#d8bf50",
 | 
			
		||||
  "switch-checked-color": "var(--primary-color)",
 | 
			
		||||
  "secondary-text-color": "#389638",
 | 
			
		||||
  "disabled-text-color": "#545454",
 | 
			
		||||
  "paper-item-icon_-_color": "var(--primary-text-color)",
 | 
			
		||||
  "paper-grey-200": "#191919",
 | 
			
		||||
  "primary-text-color": "#cfcfcf",
 | 
			
		||||
  "label-badge-background-color": "var(--secondary-background-color)",
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -73,7 +73,7 @@ class CastDemoRow extends LitElement implements LovelaceRow {
 | 
			
		||||
    }
 | 
			
		||||
    ha-svg-icon {
 | 
			
		||||
      padding: 8px;
 | 
			
		||||
      color: var(--paper-item-icon-color);
 | 
			
		||||
      color: var(--state-icon-color);
 | 
			
		||||
    }
 | 
			
		||||
    .flex {
 | 
			
		||||
      flex: 1;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import "./util/is_frontpage";
 | 
			
		||||
import "./ha-demo";
 | 
			
		||||
 | 
			
		||||
import("../../src/resources/ha-style");
 | 
			
		||||
import("../../src/resources/append-ha-style");
 | 
			
		||||
 
 | 
			
		||||
@@ -2,26 +2,36 @@ import type { TodoItem } from "../../../src/data/todo";
 | 
			
		||||
import { TodoItemStatus } from "../../../src/data/todo";
 | 
			
		||||
import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
 | 
			
		||||
 | 
			
		||||
export const mockTodo = (hass: MockHomeAssistant) => {
 | 
			
		||||
  hass.mockWS("todo/item/list", () => ({
 | 
			
		||||
    items: [
 | 
			
		||||
      {
 | 
			
		||||
        uid: "12",
 | 
			
		||||
        summary: "Milk",
 | 
			
		||||
        status: TodoItemStatus.NeedsAction,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        uid: "13",
 | 
			
		||||
        summary: "Eggs",
 | 
			
		||||
        status: TodoItemStatus.NeedsAction,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        uid: "14",
 | 
			
		||||
        summary: "Oranges",
 | 
			
		||||
        status: TodoItemStatus.Completed,
 | 
			
		||||
      },
 | 
			
		||||
    ] as TodoItem[],
 | 
			
		||||
  }));
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-empty-function
 | 
			
		||||
  hass.mockWS("todo/item/subscribe", (_msg, _hass) => () => {});
 | 
			
		||||
const items = {
 | 
			
		||||
  items: [
 | 
			
		||||
    {
 | 
			
		||||
      uid: "12",
 | 
			
		||||
      summary: "Milk",
 | 
			
		||||
      status: TodoItemStatus.NeedsAction,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      uid: "13",
 | 
			
		||||
      summary: "Eggs",
 | 
			
		||||
      status: TodoItemStatus.NeedsAction,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      uid: "14",
 | 
			
		||||
      summary: "Oranges",
 | 
			
		||||
      status: TodoItemStatus.Completed,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      uid: "15",
 | 
			
		||||
      summary: "Beer",
 | 
			
		||||
    },
 | 
			
		||||
  ] as TodoItem[],
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
        __STATIC_PATH__: false,
 | 
			
		||||
        __SUPERVISOR__: false,
 | 
			
		||||
        Polymer: true,
 | 
			
		||||
      },
 | 
			
		||||
 | 
			
		||||
      parser: tseslint.parser,
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@ class PageDescription extends HaMarkdown {
 | 
			
		||||
        padding-bottom: 8px;
 | 
			
		||||
      }
 | 
			
		||||
      .subtitle {
 | 
			
		||||
        font-size: 18px;
 | 
			
		||||
        font-size: var(--ha-font-size-l);
 | 
			
		||||
        line-height: 24px;
 | 
			
		||||
      }
 | 
			
		||||
      .root {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import "./ha-gallery";
 | 
			
		||||
 | 
			
		||||
import("../../src/resources/ha-style");
 | 
			
		||||
import("../../src/resources/append-ha-style");
 | 
			
		||||
 | 
			
		||||
document.body.appendChild(document.createElement("ha-gallery"));
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,7 @@ class HaDemoOptions extends LitElement {
 | 
			
		||||
        height: 64px;
 | 
			
		||||
        padding: 0 16px;
 | 
			
		||||
        pointer-events: none;
 | 
			
		||||
        font-size: 20px;
 | 
			
		||||
        font-size: var(--ha-font-size-xl);
 | 
			
		||||
      }
 | 
			
		||||
    `,
 | 
			
		||||
  ];
 | 
			
		||||
 
 | 
			
		||||
@@ -250,8 +250,8 @@ class HaGallery extends LitElement {
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .page-footer .header {
 | 
			
		||||
        font-size: 16px;
 | 
			
		||||
        font-weight: 500;
 | 
			
		||||
        font-size: var(--ha-font-size-l);
 | 
			
		||||
        font-weight: var(--ha-font-weight-medium);
 | 
			
		||||
        line-height: 28px;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,29 +1,30 @@
 | 
			
		||||
import type { TemplateResult } from "lit";
 | 
			
		||||
import { LitElement, html, css } from "lit";
 | 
			
		||||
import { LitElement, css, html } from "lit";
 | 
			
		||||
import { customElement, state } from "lit/decorators";
 | 
			
		||||
import "../../../../src/components/ha-formfield";
 | 
			
		||||
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 { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry";
 | 
			
		||||
import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry";
 | 
			
		||||
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 { 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 { 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 { 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 { 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 { 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 { 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[] }[] = [
 | 
			
		||||
  { name: "Event", actions: [HaEventAction.defaultConfig] },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,26 +1,27 @@
 | 
			
		||||
import type { TemplateResult } from "lit";
 | 
			
		||||
import { LitElement, html, css } from "lit";
 | 
			
		||||
import { LitElement, css, html } from "lit";
 | 
			
		||||
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 { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry";
 | 
			
		||||
import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry";
 | 
			
		||||
import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor";
 | 
			
		||||
import "../../../../src/components/ha-formfield";
 | 
			
		||||
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 { 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 { 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 { 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 { 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 { 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 { 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 { HaOrCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-or";
 | 
			
		||||
import { HaNotCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-not";
 | 
			
		||||
import type { HomeAssistant } from "../../../../src/types";
 | 
			
		||||
import "../../components/demo-black-white-row";
 | 
			
		||||
 | 
			
		||||
const SCHEMAS: { name: string; conditions: ConditionWithShorthand[] }[] = [
 | 
			
		||||
  {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,35 +1,36 @@
 | 
			
		||||
import type { TemplateResult } from "lit";
 | 
			
		||||
import { LitElement, html, css } from "lit";
 | 
			
		||||
import { LitElement, css, html } from "lit";
 | 
			
		||||
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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { HaDeviceTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-device";
 | 
			
		||||
import { HaStateTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-state";
 | 
			
		||||
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";
 | 
			
		||||
import type { HomeAssistant } from "../../../../src/types";
 | 
			
		||||
import "../../components/demo-black-white-row";
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
    }
 | 
			
		||||
    label {
 | 
			
		||||
      font-weight: 600;
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
    }
 | 
			
		||||
    .custom {
 | 
			
		||||
      --control-button-icon-color: var(--primary-color);
 | 
			
		||||
 
 | 
			
		||||
@@ -86,7 +86,7 @@ export class DemoHarControlNumberButtons extends LitElement {
 | 
			
		||||
      margin: 0;
 | 
			
		||||
    }
 | 
			
		||||
    label {
 | 
			
		||||
      font-weight: 600;
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
    }
 | 
			
		||||
    .custom {
 | 
			
		||||
      color: #2196f3;
 | 
			
		||||
 
 | 
			
		||||
@@ -125,7 +125,7 @@ export class DemoHaControlSelectMenu extends LitElement {
 | 
			
		||||
      margin: 0;
 | 
			
		||||
    }
 | 
			
		||||
    label {
 | 
			
		||||
      font-weight: 600;
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
    }
 | 
			
		||||
    .custom {
 | 
			
		||||
      --control-button-icon-color: var(--primary-color);
 | 
			
		||||
 
 | 
			
		||||
@@ -181,7 +181,7 @@ export class DemoHaControlSelect extends LitElement {
 | 
			
		||||
      margin: 0;
 | 
			
		||||
    }
 | 
			
		||||
    label {
 | 
			
		||||
      font-weight: 600;
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
    }
 | 
			
		||||
    .custom {
 | 
			
		||||
      --mdc-icon-size: 24px;
 | 
			
		||||
 
 | 
			
		||||
@@ -144,7 +144,7 @@ export class DemoHaBarSlider extends LitElement {
 | 
			
		||||
      margin: 0;
 | 
			
		||||
    }
 | 
			
		||||
    label {
 | 
			
		||||
      font-weight: 600;
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
    }
 | 
			
		||||
    .custom {
 | 
			
		||||
      --control-slider-color: #ffcf4c;
 | 
			
		||||
 
 | 
			
		||||
@@ -112,7 +112,7 @@ export class DemoHaControlSwitch extends LitElement {
 | 
			
		||||
      margin: 0;
 | 
			
		||||
    }
 | 
			
		||||
    label {
 | 
			
		||||
      font-weight: 600;
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
    }
 | 
			
		||||
    .custom {
 | 
			
		||||
      --control-switch-on-color: var(--green-color);
 | 
			
		||||
 
 | 
			
		||||
@@ -105,8 +105,8 @@ export class DemoHaHsColorPicker extends LitElement {
 | 
			
		||||
      width: 400px;
 | 
			
		||||
    }
 | 
			
		||||
    .value {
 | 
			
		||||
      font-size: 22px;
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
      font-size: var(--ha-font-size-xl);
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
      margin: 0 0 12px 0;
 | 
			
		||||
    }
 | 
			
		||||
  `;
 | 
			
		||||
 
 | 
			
		||||
@@ -123,7 +123,7 @@ export class DemoHaSelectBox extends LitElement {
 | 
			
		||||
      margin: 0;
 | 
			
		||||
    }
 | 
			
		||||
    label {
 | 
			
		||||
      font-weight: 600;
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
      margin-bottom: 8px;
 | 
			
		||||
      display: block;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -6,22 +6,23 @@ import { mockAreaRegistry } from "../../../../demo/src/stubs/area_registry";
 | 
			
		||||
import { mockConfigEntries } from "../../../../demo/src/stubs/config_entries";
 | 
			
		||||
import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_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 { mockLabelRegistry } from "../../../../demo/src/stubs/label_registry";
 | 
			
		||||
import "../../../../src/components/ha-formfield";
 | 
			
		||||
import "../../../../src/components/ha-selector/ha-selector";
 | 
			
		||||
import "../../../../src/components/ha-settings-row";
 | 
			
		||||
import type { AreaRegistryEntry } from "../../../../src/data/area_registry";
 | 
			
		||||
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 { getEntity } from "../../../../src/fake_data/entity";
 | 
			
		||||
import { provideHass } from "../../../../src/fake_data/provide_hass";
 | 
			
		||||
import type { ProvideHassElement } from "../../../../src/mixins/provide-hass-lit-mixin";
 | 
			
		||||
import type { HomeAssistant } from "../../../../src/types";
 | 
			
		||||
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 = [
 | 
			
		||||
  getEntity("alarm_control_panel", "alarm", "disarmed", {
 | 
			
		||||
@@ -643,9 +644,6 @@ class DemoHaSelector extends LitElement implements ProvideHassElement {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static styles = css`
 | 
			
		||||
    ha-settings-row {
 | 
			
		||||
      --paper-item-body-two-line-min-height: 0;
 | 
			
		||||
    }
 | 
			
		||||
    .options {
 | 
			
		||||
      max-width: 800px;
 | 
			
		||||
      margin: 16px auto;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
import type { TemplateResult } from "lit";
 | 
			
		||||
import { html, css, LitElement } from "lit";
 | 
			
		||||
import { css, html, LitElement } from "lit";
 | 
			
		||||
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-card";
 | 
			
		||||
import "../../../../src/components/ha-spinner";
 | 
			
		||||
@@ -11,29 +12,66 @@ export class DemoHaSpinner extends LitElement {
 | 
			
		||||
  @property({ attribute: false }) hass!: HomeAssistant;
 | 
			
		||||
 | 
			
		||||
  protected render(): TemplateResult {
 | 
			
		||||
    return html`<ha-card header="Basic spinner">
 | 
			
		||||
        <div class="card-content">
 | 
			
		||||
          <ha-spinner></ha-spinner></div
 | 
			
		||||
      ></ha-card>
 | 
			
		||||
      <ha-card header="Different spinner sizes">
 | 
			
		||||
        <div class="card-content">
 | 
			
		||||
          <ha-spinner size="tiny"></ha-spinner>
 | 
			
		||||
          <ha-spinner size="small"></ha-spinner>
 | 
			
		||||
          <ha-spinner size="medium"></ha-spinner>
 | 
			
		||||
          <ha-spinner size="large"></ha-spinner></div
 | 
			
		||||
      ></ha-card>
 | 
			
		||||
      <ha-card header="Spinner with an aria-label">
 | 
			
		||||
        <div class="card-content">
 | 
			
		||||
          <ha-spinner aria-label="Doing something..."></ha-spinner>
 | 
			
		||||
          <ha-spinner .ariaLabel=${"Doing something..."}></ha-spinner></div
 | 
			
		||||
      ></ha-card>`;
 | 
			
		||||
    return html`
 | 
			
		||||
      ${["light", "dark"].map(
 | 
			
		||||
        (mode) => html`
 | 
			
		||||
          <div class=${mode}>
 | 
			
		||||
            <ha-card header="ha-badge ${mode} demo">
 | 
			
		||||
              <div class="card-content">
 | 
			
		||||
                <ha-spinner></ha-spinner>
 | 
			
		||||
                <ha-spinner size="tiny"></ha-spinner>
 | 
			
		||||
                <ha-spinner size="small"></ha-spinner>
 | 
			
		||||
                <ha-spinner size="medium"></ha-spinner>
 | 
			
		||||
                <ha-spinner size="large"></ha-spinner>
 | 
			
		||||
                <ha-spinner aria-label="Doing something..."></ha-spinner>
 | 
			
		||||
                <ha-spinner .ariaLabel=${"Doing something..."}></ha-spinner>
 | 
			
		||||
              </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;
 | 
			
		||||
      margin: 16px;
 | 
			
		||||
      border-radius: 8px;
 | 
			
		||||
    }
 | 
			
		||||
    ha-card {
 | 
			
		||||
      max-width: 600px;
 | 
			
		||||
      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
 | 
			
		||||
 | 
			
		||||
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>
 | 
			
		||||
 | 
			
		||||
@@ -28,3 +28,7 @@ In your theme settings use this without the prefixed `--`.
 | 
			
		||||
 | 
			
		||||
- `--ha-tooltip-border-radius` (Default: 4px)
 | 
			
		||||
- `--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 { customElement, state } from "lit/decorators";
 | 
			
		||||
import { formatDateTimeNumeric } from "../../../../src/common/datetime/format_date_time";
 | 
			
		||||
import "../../../../src/components/ha-card";
 | 
			
		||||
import "../../../../src/components/ha-control-select";
 | 
			
		||||
import "../../../../src/components/ha-list";
 | 
			
		||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
 | 
			
		||||
import {
 | 
			
		||||
  DateFormat,
 | 
			
		||||
@@ -49,7 +49,7 @@ export class DemoDateTimeDateTimeNumeric extends LitElement {
 | 
			
		||||
        @value-changed=${this.handleValueChanged}
 | 
			
		||||
      >
 | 
			
		||||
      </ha-control-select>
 | 
			
		||||
      <mwc-list>
 | 
			
		||||
      <ha-list>
 | 
			
		||||
        <div class="container header">
 | 
			
		||||
          <div>Language</div>
 | 
			
		||||
          <div class="center">Default (lang)</div>
 | 
			
		||||
@@ -96,7 +96,7 @@ export class DemoDateTimeDateTimeNumeric extends LitElement {
 | 
			
		||||
            </div>
 | 
			
		||||
          `
 | 
			
		||||
        )}
 | 
			
		||||
      </mwc-list>
 | 
			
		||||
      </ha-list>
 | 
			
		||||
    `;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -106,7 +106,7 @@ export class DemoDateTimeDateTimeNumeric extends LitElement {
 | 
			
		||||
      margin: 12px auto;
 | 
			
		||||
    }
 | 
			
		||||
    .header {
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
    }
 | 
			
		||||
    .center {
 | 
			
		||||
      text-align: center;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
import "@material/mwc-list/mwc-list";
 | 
			
		||||
import { LitElement, css, html } from "lit";
 | 
			
		||||
import { customElement, state } from "lit/decorators";
 | 
			
		||||
import { formatDateTimeWithSeconds } from "../../../../src/common/datetime/format_date_time";
 | 
			
		||||
import "../../../../src/components/ha-card";
 | 
			
		||||
import "../../../../src/components/ha-control-select";
 | 
			
		||||
import "../../../../src/components/ha-list";
 | 
			
		||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
 | 
			
		||||
import {
 | 
			
		||||
  DateFormat,
 | 
			
		||||
@@ -49,7 +49,7 @@ export class DemoDateTimeDateTimeSeconds extends LitElement {
 | 
			
		||||
        @value-changed=${this.handleValueChanged}
 | 
			
		||||
      >
 | 
			
		||||
      </ha-control-select>
 | 
			
		||||
      <mwc-list>
 | 
			
		||||
      <ha-list>
 | 
			
		||||
        <div class="container header">
 | 
			
		||||
          <div>Language</div>
 | 
			
		||||
          <div class="center">Default (lang)</div>
 | 
			
		||||
@@ -96,7 +96,7 @@ export class DemoDateTimeDateTimeSeconds extends LitElement {
 | 
			
		||||
            </div>
 | 
			
		||||
          `
 | 
			
		||||
        )}
 | 
			
		||||
      </mwc-list>
 | 
			
		||||
      </ha-list>
 | 
			
		||||
    `;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -106,7 +106,7 @@ export class DemoDateTimeDateTimeSeconds extends LitElement {
 | 
			
		||||
      margin: 12px auto;
 | 
			
		||||
    }
 | 
			
		||||
    .header {
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
    }
 | 
			
		||||
    .center {
 | 
			
		||||
      text-align: center;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
import "@material/mwc-list/mwc-list";
 | 
			
		||||
import { LitElement, css, html } from "lit";
 | 
			
		||||
import { customElement, state } from "lit/decorators";
 | 
			
		||||
import { formatShortDateTimeWithYear } from "../../../../src/common/datetime/format_date_time";
 | 
			
		||||
import "../../../../src/components/ha-card";
 | 
			
		||||
import "../../../../src/components/ha-control-select";
 | 
			
		||||
import "../../../../src/components/ha-list";
 | 
			
		||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
 | 
			
		||||
import {
 | 
			
		||||
  DateFormat,
 | 
			
		||||
@@ -49,7 +49,7 @@ export class DemoDateTimeDateTimeShortYear extends LitElement {
 | 
			
		||||
        @value-changed=${this.handleValueChanged}
 | 
			
		||||
      >
 | 
			
		||||
      </ha-control-select>
 | 
			
		||||
      <mwc-list>
 | 
			
		||||
      <ha-list>
 | 
			
		||||
        <div class="container header">
 | 
			
		||||
          <div>Language</div>
 | 
			
		||||
          <div class="center">Default (lang)</div>
 | 
			
		||||
@@ -96,7 +96,7 @@ export class DemoDateTimeDateTimeShortYear extends LitElement {
 | 
			
		||||
            </div>
 | 
			
		||||
          `
 | 
			
		||||
        )}
 | 
			
		||||
      </mwc-list>
 | 
			
		||||
      </ha-list>
 | 
			
		||||
    `;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -106,7 +106,7 @@ export class DemoDateTimeDateTimeShortYear extends LitElement {
 | 
			
		||||
      margin: 12px auto;
 | 
			
		||||
    }
 | 
			
		||||
    .header {
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
    }
 | 
			
		||||
    .center {
 | 
			
		||||
      text-align: center;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
import "@material/mwc-list/mwc-list";
 | 
			
		||||
import { LitElement, css, html } from "lit";
 | 
			
		||||
import { customElement, state } from "lit/decorators";
 | 
			
		||||
import { formatShortDateTime } from "../../../../src/common/datetime/format_date_time";
 | 
			
		||||
import "../../../../src/components/ha-card";
 | 
			
		||||
import "../../../../src/components/ha-control-select";
 | 
			
		||||
import "../../../../src/components/ha-list";
 | 
			
		||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
 | 
			
		||||
import {
 | 
			
		||||
  DateFormat,
 | 
			
		||||
@@ -49,7 +49,7 @@ export class DemoDateTimeDateTimeShort extends LitElement {
 | 
			
		||||
        @value-changed=${this.handleValueChanged}
 | 
			
		||||
      >
 | 
			
		||||
      </ha-control-select>
 | 
			
		||||
      <mwc-list>
 | 
			
		||||
      <ha-list>
 | 
			
		||||
        <div class="container header">
 | 
			
		||||
          <div>Language</div>
 | 
			
		||||
          <div class="center">Default (lang)</div>
 | 
			
		||||
@@ -96,7 +96,7 @@ export class DemoDateTimeDateTimeShort extends LitElement {
 | 
			
		||||
            </div>
 | 
			
		||||
          `
 | 
			
		||||
        )}
 | 
			
		||||
      </mwc-list>
 | 
			
		||||
      </ha-list>
 | 
			
		||||
    `;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -106,7 +106,7 @@ export class DemoDateTimeDateTimeShort extends LitElement {
 | 
			
		||||
      margin: 12px auto;
 | 
			
		||||
    }
 | 
			
		||||
    .header {
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
    }
 | 
			
		||||
    .center {
 | 
			
		||||
      text-align: center;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
import "@material/mwc-list/mwc-list";
 | 
			
		||||
import { LitElement, css, html } from "lit";
 | 
			
		||||
import { customElement, state } from "lit/decorators";
 | 
			
		||||
import { formatDateTime } from "../../../../src/common/datetime/format_date_time";
 | 
			
		||||
import "../../../../src/components/ha-card";
 | 
			
		||||
import "../../../../src/components/ha-control-select";
 | 
			
		||||
import "../../../../src/components/ha-list";
 | 
			
		||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
 | 
			
		||||
import {
 | 
			
		||||
  DateFormat,
 | 
			
		||||
@@ -49,7 +49,7 @@ export class DemoDateTimeDateTime extends LitElement {
 | 
			
		||||
        @value-changed=${this.handleValueChanged}
 | 
			
		||||
      >
 | 
			
		||||
      </ha-control-select>
 | 
			
		||||
      <mwc-list>
 | 
			
		||||
      <ha-list>
 | 
			
		||||
        <div class="container header">
 | 
			
		||||
          <div>Language</div>
 | 
			
		||||
          <div class="center">Default (lang)</div>
 | 
			
		||||
@@ -96,7 +96,7 @@ export class DemoDateTimeDateTime extends LitElement {
 | 
			
		||||
            </div>
 | 
			
		||||
          `
 | 
			
		||||
        )}
 | 
			
		||||
      </mwc-list>
 | 
			
		||||
      </ha-list>
 | 
			
		||||
    `;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -106,7 +106,7 @@ export class DemoDateTimeDateTime extends LitElement {
 | 
			
		||||
      margin: 12px auto;
 | 
			
		||||
    }
 | 
			
		||||
    .header {
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
    }
 | 
			
		||||
    .center {
 | 
			
		||||
      text-align: center;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
import "@material/mwc-list/mwc-list";
 | 
			
		||||
import { css, html, LitElement } from "lit";
 | 
			
		||||
import { customElement } from "lit/decorators";
 | 
			
		||||
import { formatDateNumeric } from "../../../../src/common/datetime/format_date";
 | 
			
		||||
import "../../../../src/components/ha-card";
 | 
			
		||||
import "../../../../src/components/ha-list";
 | 
			
		||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
 | 
			
		||||
import {
 | 
			
		||||
  DateFormat,
 | 
			
		||||
@@ -27,7 +27,7 @@ export class DemoDateTimeDate extends LitElement {
 | 
			
		||||
    };
 | 
			
		||||
    const date = new Date();
 | 
			
		||||
    return html`
 | 
			
		||||
      <mwc-list>
 | 
			
		||||
      <ha-list>
 | 
			
		||||
        <div class="container header">
 | 
			
		||||
          <div>Language</div>
 | 
			
		||||
          <div class="center">Default (lang)</div>
 | 
			
		||||
@@ -86,13 +86,13 @@ export class DemoDateTimeDate extends LitElement {
 | 
			
		||||
            </div>
 | 
			
		||||
          `
 | 
			
		||||
        )}
 | 
			
		||||
      </mwc-list>
 | 
			
		||||
      </ha-list>
 | 
			
		||||
    `;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static styles = css`
 | 
			
		||||
    .header {
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
    }
 | 
			
		||||
    .center {
 | 
			
		||||
      text-align: center;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
import "@material/mwc-list/mwc-list";
 | 
			
		||||
import { LitElement, css, html } from "lit";
 | 
			
		||||
import { customElement, state } from "lit/decorators";
 | 
			
		||||
import { formatTimeWithSeconds } from "../../../../src/common/datetime/format_time";
 | 
			
		||||
import "../../../../src/components/ha-card";
 | 
			
		||||
import "../../../../src/components/ha-control-select";
 | 
			
		||||
import "../../../../src/components/ha-list";
 | 
			
		||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
 | 
			
		||||
import {
 | 
			
		||||
  DateFormat,
 | 
			
		||||
@@ -49,7 +49,7 @@ export class DemoDateTimeTimeSeconds extends LitElement {
 | 
			
		||||
        @value-changed=${this.handleValueChanged}
 | 
			
		||||
      >
 | 
			
		||||
      </ha-control-select>
 | 
			
		||||
      <mwc-list>
 | 
			
		||||
      <ha-list>
 | 
			
		||||
        <div class="container header">
 | 
			
		||||
          <div>Language</div>
 | 
			
		||||
          <div class="center">Default (lang)</div>
 | 
			
		||||
@@ -96,7 +96,7 @@ export class DemoDateTimeTimeSeconds extends LitElement {
 | 
			
		||||
            </div>
 | 
			
		||||
          `
 | 
			
		||||
        )}
 | 
			
		||||
      </mwc-list>
 | 
			
		||||
      </ha-list>
 | 
			
		||||
    `;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -106,7 +106,7 @@ export class DemoDateTimeTimeSeconds extends LitElement {
 | 
			
		||||
      margin: 12px auto;
 | 
			
		||||
    }
 | 
			
		||||
    .header {
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
    }
 | 
			
		||||
    .center {
 | 
			
		||||
      text-align: center;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
import "@material/mwc-list/mwc-list";
 | 
			
		||||
import { LitElement, css, html } from "lit";
 | 
			
		||||
import { customElement, state } from "lit/decorators";
 | 
			
		||||
import { formatTimeWeekday } from "../../../../src/common/datetime/format_time";
 | 
			
		||||
import "../../../../src/components/ha-card";
 | 
			
		||||
import "../../../../src/components/ha-control-select";
 | 
			
		||||
import "../../../../src/components/ha-list";
 | 
			
		||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
 | 
			
		||||
import {
 | 
			
		||||
  DateFormat,
 | 
			
		||||
@@ -49,7 +49,7 @@ export class DemoDateTimeTimeWeekday extends LitElement {
 | 
			
		||||
        @value-changed=${this.handleValueChanged}
 | 
			
		||||
      >
 | 
			
		||||
      </ha-control-select>
 | 
			
		||||
      <mwc-list>
 | 
			
		||||
      <ha-list>
 | 
			
		||||
        <div class="container header">
 | 
			
		||||
          <div>Language</div>
 | 
			
		||||
          <div class="center">Default (lang)</div>
 | 
			
		||||
@@ -96,7 +96,7 @@ export class DemoDateTimeTimeWeekday extends LitElement {
 | 
			
		||||
            </div>
 | 
			
		||||
          `
 | 
			
		||||
        )}
 | 
			
		||||
      </mwc-list>
 | 
			
		||||
      </ha-list>
 | 
			
		||||
    `;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -106,7 +106,7 @@ export class DemoDateTimeTimeWeekday extends LitElement {
 | 
			
		||||
      margin: 12px auto;
 | 
			
		||||
    }
 | 
			
		||||
    .header {
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
    }
 | 
			
		||||
    .center {
 | 
			
		||||
      text-align: center;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
import "@material/mwc-list/mwc-list";
 | 
			
		||||
import { LitElement, css, html } from "lit";
 | 
			
		||||
import { customElement, state } from "lit/decorators";
 | 
			
		||||
import { formatTime } from "../../../../src/common/datetime/format_time";
 | 
			
		||||
import "../../../../src/components/ha-card";
 | 
			
		||||
import "../../../../src/components/ha-control-select";
 | 
			
		||||
import "../../../../src/components/ha-list";
 | 
			
		||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
 | 
			
		||||
import {
 | 
			
		||||
  DateFormat,
 | 
			
		||||
@@ -49,7 +49,7 @@ export class DemoDateTimeTime extends LitElement {
 | 
			
		||||
        @value-changed=${this.handleValueChanged}
 | 
			
		||||
      >
 | 
			
		||||
      </ha-control-select>
 | 
			
		||||
      <mwc-list>
 | 
			
		||||
      <ha-list>
 | 
			
		||||
        <div class="container header">
 | 
			
		||||
          <div>Language</div>
 | 
			
		||||
          <div class="center">Default (lang)</div>
 | 
			
		||||
@@ -96,7 +96,7 @@ export class DemoDateTimeTime extends LitElement {
 | 
			
		||||
            </div>
 | 
			
		||||
          `
 | 
			
		||||
        )}
 | 
			
		||||
      </mwc-list>
 | 
			
		||||
      </ha-list>
 | 
			
		||||
    `;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -106,7 +106,7 @@ export class DemoDateTimeTime extends LitElement {
 | 
			
		||||
      margin: 12px auto;
 | 
			
		||||
    }
 | 
			
		||||
    .header {
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
      font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
    }
 | 
			
		||||
    .center {
 | 
			
		||||
      text-align: center;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
import type { PropertyValues, TemplateResult } from "lit";
 | 
			
		||||
import { html, LitElement } from "lit";
 | 
			
		||||
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 "../../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 = [
 | 
			
		||||
  getEntity("todo", "shopping_list", "2", {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import type { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
 | 
			
		||||
import "@material/mwc-list/mwc-list-item";
 | 
			
		||||
 | 
			
		||||
import { mdiDotsVertical } from "@mdi/js";
 | 
			
		||||
import type { PropertyValues, TemplateResult } 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 "../../../src/components/ha-button-menu";
 | 
			
		||||
import "../../../src/components/ha-icon-button";
 | 
			
		||||
import "../../../src/components/ha-list-item";
 | 
			
		||||
import "../../../src/components/search-input";
 | 
			
		||||
import type { HassioAddonRepository } from "../../../src/data/hassio/addon";
 | 
			
		||||
import { reloadHassioAddons } from "../../../src/data/hassio/addon";
 | 
			
		||||
@@ -89,17 +90,17 @@ export class HassioAddonStore extends LitElement {
 | 
			
		||||
            .path=${mdiDotsVertical}
 | 
			
		||||
            slot="trigger"
 | 
			
		||||
          ></ha-icon-button>
 | 
			
		||||
          <mwc-list-item>
 | 
			
		||||
          <ha-list-item>
 | 
			
		||||
            ${this.supervisor.localize("store.check_updates")}
 | 
			
		||||
          </mwc-list-item>
 | 
			
		||||
          <mwc-list-item>
 | 
			
		||||
          </ha-list-item>
 | 
			
		||||
          <ha-list-item>
 | 
			
		||||
            ${this.supervisor.localize("store.repositories")}
 | 
			
		||||
          </mwc-list-item>
 | 
			
		||||
          </ha-list-item>
 | 
			
		||||
          ${this.hass.userData?.showAdvanced &&
 | 
			
		||||
          atLeastVersion(this.hass.config.version, 0, 117)
 | 
			
		||||
            ? html`<mwc-list-item>
 | 
			
		||||
            ? html`<ha-list-item>
 | 
			
		||||
                ${this.supervisor.localize("store.registries")}
 | 
			
		||||
              </mwc-list-item>`
 | 
			
		||||
              </ha-list-item>`
 | 
			
		||||
            : ""}
 | 
			
		||||
        </ha-button-menu>
 | 
			
		||||
        ${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 { css, html, LitElement } from "lit";
 | 
			
		||||
import { css, html, LitElement, nothing } from "lit";
 | 
			
		||||
import { customElement, property, state } from "lit/decorators";
 | 
			
		||||
import { stopPropagation } from "../../../../src/common/dom/stop_propagation";
 | 
			
		||||
import "../../../../src/components/buttons/ha-progress-button";
 | 
			
		||||
import "../../../../src/components/ha-alert";
 | 
			
		||||
import "../../../../src/components/ha-card";
 | 
			
		||||
import "../../../../src/components/ha-list-item";
 | 
			
		||||
import "../../../../src/components/ha-select";
 | 
			
		||||
import type {
 | 
			
		||||
  HassioAddonDetails,
 | 
			
		||||
@@ -29,6 +28,8 @@ class HassioAddonAudio extends LitElement {
 | 
			
		||||
 | 
			
		||||
  @property({ attribute: false }) public addon!: HassioAddonDetails;
 | 
			
		||||
 | 
			
		||||
  @property({ type: Boolean }) public disabled = false;
 | 
			
		||||
 | 
			
		||||
  @state() private _error?: string;
 | 
			
		||||
 | 
			
		||||
  @state() private _inputDevices?: HassioHardwareAudioDevice[];
 | 
			
		||||
@@ -48,7 +49,7 @@ class HassioAddonAudio extends LitElement {
 | 
			
		||||
        <div class="card-content">
 | 
			
		||||
          ${this._error
 | 
			
		||||
            ? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
 | 
			
		||||
            : ""}
 | 
			
		||||
            : nothing}
 | 
			
		||||
          ${this._inputDevices &&
 | 
			
		||||
          html`<ha-select
 | 
			
		||||
            .label=${this.supervisor.localize(
 | 
			
		||||
@@ -59,12 +60,13 @@ class HassioAddonAudio extends LitElement {
 | 
			
		||||
            fixedMenuPosition
 | 
			
		||||
            naturalMenuWidth
 | 
			
		||||
            .value=${this._selectedInput!}
 | 
			
		||||
            .disabled=${this.disabled}
 | 
			
		||||
          >
 | 
			
		||||
            ${this._inputDevices.map(
 | 
			
		||||
              (item) => html`
 | 
			
		||||
                <mwc-list-item .value=${item.device || ""}>
 | 
			
		||||
                <ha-list-item .value=${item.device || ""}>
 | 
			
		||||
                  ${item.name}
 | 
			
		||||
                </mwc-list-item>
 | 
			
		||||
                </ha-list-item>
 | 
			
		||||
              `
 | 
			
		||||
            )}
 | 
			
		||||
          </ha-select>`}
 | 
			
		||||
@@ -78,18 +80,22 @@ class HassioAddonAudio extends LitElement {
 | 
			
		||||
            fixedMenuPosition
 | 
			
		||||
            naturalMenuWidth
 | 
			
		||||
            .value=${this._selectedOutput!}
 | 
			
		||||
            .disabled=${this.disabled}
 | 
			
		||||
          >
 | 
			
		||||
            ${this._outputDevices.map(
 | 
			
		||||
              (item) => html`
 | 
			
		||||
                <mwc-list-item .value=${item.device || ""}
 | 
			
		||||
                  >${item.name}</mwc-list-item
 | 
			
		||||
                <ha-list-item .value=${item.device || ""}
 | 
			
		||||
                  >${item.name}</ha-list-item
 | 
			
		||||
                >
 | 
			
		||||
              `
 | 
			
		||||
            )}
 | 
			
		||||
          </ha-select>`}
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="card-actions">
 | 
			
		||||
          <ha-progress-button @click=${this._saveSettings}>
 | 
			
		||||
          <ha-progress-button
 | 
			
		||||
            .disabled=${this.disabled}
 | 
			
		||||
            @click=${this._saveSettings}
 | 
			
		||||
          >
 | 
			
		||||
            ${this.supervisor.localize("common.save")}
 | 
			
		||||
          </ha-progress-button>
 | 
			
		||||
        </div>
 | 
			
		||||
@@ -171,6 +177,10 @@ class HassioAddonAudio extends LitElement {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async _saveSettings(ev: CustomEvent): Promise<void> {
 | 
			
		||||
    if (this.disabled) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const button = ev.currentTarget as any;
 | 
			
		||||
    button.progress = true;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
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 "../../../../src/components/ha-spinner";
 | 
			
		||||
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 type { HomeAssistant } from "../../../../src/types";
 | 
			
		||||
import { hassioStyle } from "../../resources/hassio-style";
 | 
			
		||||
import "../info/hassio-addon-system-managed";
 | 
			
		||||
import "./hassio-addon-audio";
 | 
			
		||||
import "./hassio-addon-config";
 | 
			
		||||
import "./hassio-addon-network";
 | 
			
		||||
@@ -19,6 +20,11 @@ class HassioAddonConfigDashboard extends LitElement {
 | 
			
		||||
 | 
			
		||||
  @property({ attribute: false }) public addon?: HassioAddonDetails;
 | 
			
		||||
 | 
			
		||||
  @property({ type: Boolean }) public narrow = false;
 | 
			
		||||
 | 
			
		||||
  @property({ type: Boolean, attribute: "control-enabled" })
 | 
			
		||||
  public controlEnabled = false;
 | 
			
		||||
 | 
			
		||||
  protected render(): TemplateResult {
 | 
			
		||||
    if (!this.addon) {
 | 
			
		||||
      return html`<ha-spinner></ha-spinner>`;
 | 
			
		||||
@@ -29,6 +35,16 @@ class HassioAddonConfigDashboard extends LitElement {
 | 
			
		||||
 | 
			
		||||
    return html`
 | 
			
		||||
      <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
 | 
			
		||||
          ? html`
 | 
			
		||||
              ${hasConfiguration
 | 
			
		||||
@@ -37,27 +53,33 @@ class HassioAddonConfigDashboard extends LitElement {
 | 
			
		||||
                      .hass=${this.hass}
 | 
			
		||||
                      .addon=${this.addon}
 | 
			
		||||
                      .supervisor=${this.supervisor}
 | 
			
		||||
                      .disabled=${this.addon.system_managed &&
 | 
			
		||||
                      !this.controlEnabled}
 | 
			
		||||
                    ></hassio-addon-config>
 | 
			
		||||
                  `
 | 
			
		||||
                : ""}
 | 
			
		||||
                : nothing}
 | 
			
		||||
              ${this.addon.network
 | 
			
		||||
                ? html`
 | 
			
		||||
                    <hassio-addon-network
 | 
			
		||||
                      .hass=${this.hass}
 | 
			
		||||
                      .addon=${this.addon}
 | 
			
		||||
                      .supervisor=${this.supervisor}
 | 
			
		||||
                      .disabled=${this.addon.system_managed &&
 | 
			
		||||
                      !this.controlEnabled}
 | 
			
		||||
                    ></hassio-addon-network>
 | 
			
		||||
                  `
 | 
			
		||||
                : ""}
 | 
			
		||||
                : nothing}
 | 
			
		||||
              ${this.addon.audio
 | 
			
		||||
                ? html`
 | 
			
		||||
                    <hassio-addon-audio
 | 
			
		||||
                      .hass=${this.hass}
 | 
			
		||||
                      .addon=${this.addon}
 | 
			
		||||
                      .supervisor=${this.supervisor}
 | 
			
		||||
                      .disabled=${this.addon.system_managed &&
 | 
			
		||||
                      !this.controlEnabled}
 | 
			
		||||
                    ></hassio-addon-audio>
 | 
			
		||||
                  `
 | 
			
		||||
                : ""}
 | 
			
		||||
                : nothing}
 | 
			
		||||
            `
 | 
			
		||||
          : this.supervisor.localize("addon.configuration.no_configuration")}
 | 
			
		||||
      </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,4 @@
 | 
			
		||||
import "@material/mwc-button";
 | 
			
		||||
import type { ActionDetail } from "@material/mwc-list";
 | 
			
		||||
import "@material/mwc-list/mwc-list-item";
 | 
			
		||||
import { mdiDotsVertical } from "@mdi/js";
 | 
			
		||||
import { DEFAULT_SCHEMA, Type } from "js-yaml";
 | 
			
		||||
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 "../../../../src/components/ha-formfield";
 | 
			
		||||
import "../../../../src/components/ha-icon-button";
 | 
			
		||||
import "../../../../src/components/ha-list-item";
 | 
			
		||||
import "../../../../src/components/ha-switch";
 | 
			
		||||
import "../../../../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({ type: Boolean }) public disabled = false;
 | 
			
		||||
 | 
			
		||||
  @state() private _configHasChanged = false;
 | 
			
		||||
 | 
			
		||||
  @state() private _valid = true;
 | 
			
		||||
@@ -176,7 +177,7 @@ class HassioAddonConfig extends LitElement {
 | 
			
		||||
                .path=${mdiDotsVertical}
 | 
			
		||||
                slot="trigger"
 | 
			
		||||
              ></ha-icon-button>
 | 
			
		||||
              <mwc-list-item .disabled=${!this._canShowSchema}>
 | 
			
		||||
              <ha-list-item .disabled=${!this._canShowSchema || this.disabled}>
 | 
			
		||||
                ${this._yamlMode
 | 
			
		||||
                  ? this.supervisor.localize(
 | 
			
		||||
                      "addon.configuration.options.edit_in_ui"
 | 
			
		||||
@@ -184,10 +185,13 @@ class HassioAddonConfig extends LitElement {
 | 
			
		||||
                  : this.supervisor.localize(
 | 
			
		||||
                      "addon.configuration.options.edit_in_yaml"
 | 
			
		||||
                    )}
 | 
			
		||||
              </mwc-list-item>
 | 
			
		||||
              <mwc-list-item class="warning">
 | 
			
		||||
              </ha-list-item>
 | 
			
		||||
              <ha-list-item
 | 
			
		||||
                class=${!this.disabled ? "warning" : ""}
 | 
			
		||||
                .disabled=${this.disabled}
 | 
			
		||||
              >
 | 
			
		||||
                ${this.supervisor.localize("common.reset_defaults")}
 | 
			
		||||
              </mwc-list-item>
 | 
			
		||||
              </ha-list-item>
 | 
			
		||||
            </ha-button-menu>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
@@ -195,6 +199,7 @@ class HassioAddonConfig extends LitElement {
 | 
			
		||||
        <div class="card-content">
 | 
			
		||||
          ${showForm
 | 
			
		||||
            ? html`<ha-form
 | 
			
		||||
                .disabled=${this.disabled}
 | 
			
		||||
                .data=${this._options!}
 | 
			
		||||
                @value-changed=${this._configChanged}
 | 
			
		||||
                .computeLabel=${this.computeLabel}
 | 
			
		||||
@@ -208,7 +213,7 @@ class HassioAddonConfig extends LitElement {
 | 
			
		||||
                      )
 | 
			
		||||
                )}
 | 
			
		||||
              ></ha-form>`
 | 
			
		||||
            : html` <ha-yaml-editor
 | 
			
		||||
            : html`<ha-yaml-editor
 | 
			
		||||
                @value-changed=${this._configChanged}
 | 
			
		||||
                .yamlSchema=${ADDON_YAML_SCHEMA}
 | 
			
		||||
              ></ha-yaml-editor>`}
 | 
			
		||||
@@ -244,7 +249,9 @@ class HassioAddonConfig extends LitElement {
 | 
			
		||||
        <div class="card-actions right">
 | 
			
		||||
          <ha-progress-button
 | 
			
		||||
            @click=${this._saveTapped}
 | 
			
		||||
            .disabled=${!this._configHasChanged || !this._valid}
 | 
			
		||||
            .disabled=${this.disabled ||
 | 
			
		||||
            !this._configHasChanged ||
 | 
			
		||||
            !this._valid}
 | 
			
		||||
          >
 | 
			
		||||
            ${this.supervisor.localize("common.save")}
 | 
			
		||||
          </ha-progress-button>
 | 
			
		||||
@@ -346,6 +353,10 @@ class HassioAddonConfig extends LitElement {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async _saveTapped(ev: CustomEvent): Promise<void> {
 | 
			
		||||
    if (this.disabled || !this._configHasChanged || !this._valid) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const button = ev.currentTarget as any;
 | 
			
		||||
    const options: Record<string, unknown> = this._yamlMode
 | 
			
		||||
      ? this._editor?.value
 | 
			
		||||
@@ -407,7 +418,7 @@ class HassioAddonConfig extends LitElement {
 | 
			
		||||
          z-index: 3;
 | 
			
		||||
          --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);
 | 
			
		||||
        }
 | 
			
		||||
        .header {
 | 
			
		||||
@@ -417,13 +428,13 @@ class HassioAddonConfig extends LitElement {
 | 
			
		||||
        .header h2 {
 | 
			
		||||
          color: var(--ha-card-header-color, var(--primary-text-color));
 | 
			
		||||
          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;
 | 
			
		||||
          line-height: 48px;
 | 
			
		||||
          padding: 12px 16px 16px;
 | 
			
		||||
          display: block;
 | 
			
		||||
          margin-block: 0px;
 | 
			
		||||
          font-weight: normal;
 | 
			
		||||
          font-weight: var(--ha-font-weight-normal);
 | 
			
		||||
        }
 | 
			
		||||
        .card-actions.right {
 | 
			
		||||
          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/ha-alert";
 | 
			
		||||
import "../../../../src/components/ha-card";
 | 
			
		||||
import "../../../../src/components/ha-formfield";
 | 
			
		||||
import "../../../../src/components/ha-form/ha-form";
 | 
			
		||||
import type { HaFormSchema } from "../../../../src/components/ha-form/types";
 | 
			
		||||
import type {
 | 
			
		||||
@@ -28,6 +29,8 @@ class HassioAddonNetwork extends LitElement {
 | 
			
		||||
 | 
			
		||||
  @property({ attribute: false }) public addon!: HassioAddonDetails;
 | 
			
		||||
 | 
			
		||||
  @property({ type: Boolean }) public disabled = false;
 | 
			
		||||
 | 
			
		||||
  @state() private _showOptional = false;
 | 
			
		||||
 | 
			
		||||
  @state() private _configHasChanged = false;
 | 
			
		||||
@@ -65,9 +68,10 @@ class HassioAddonNetwork extends LitElement {
 | 
			
		||||
          </p>
 | 
			
		||||
          ${this._error
 | 
			
		||||
            ? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
 | 
			
		||||
            : ""}
 | 
			
		||||
            : nothing}
 | 
			
		||||
 | 
			
		||||
          <ha-form
 | 
			
		||||
            .disabled=${this.disabled}
 | 
			
		||||
            .data=${this._config}
 | 
			
		||||
            @value-changed=${this._configChanged}
 | 
			
		||||
            .computeLabel=${this._computeLabel}
 | 
			
		||||
@@ -92,14 +96,18 @@ class HassioAddonNetwork extends LitElement {
 | 
			
		||||
              >
 | 
			
		||||
              </ha-switch>
 | 
			
		||||
            </ha-formfield>`
 | 
			
		||||
          : ""}
 | 
			
		||||
          : nothing}
 | 
			
		||||
        <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")}
 | 
			
		||||
          </ha-progress-button>
 | 
			
		||||
          <ha-progress-button
 | 
			
		||||
            @click=${this._saveTapped}
 | 
			
		||||
            .disabled=${!this._configHasChanged}
 | 
			
		||||
            .disabled=${!this._configHasChanged || this.disabled}
 | 
			
		||||
          >
 | 
			
		||||
            ${this.supervisor.localize("common.save")}
 | 
			
		||||
          </ha-progress-button>
 | 
			
		||||
@@ -155,6 +163,10 @@ class HassioAddonNetwork extends LitElement {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async _resetTapped(ev: CustomEvent): Promise<void> {
 | 
			
		||||
    if (this.disabled) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const button = ev.currentTarget as any;
 | 
			
		||||
    const data: HassioAddonSetOptionParams = {
 | 
			
		||||
      network: null,
 | 
			
		||||
@@ -186,6 +198,10 @@ class HassioAddonNetwork extends LitElement {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async _saveTapped(ev: CustomEvent): Promise<void> {
 | 
			
		||||
    if (!this._configHasChanged || this.disabled) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const button = ev.currentTarget as any;
 | 
			
		||||
 | 
			
		||||
    this._error = undefined;
 | 
			
		||||
 
 | 
			
		||||
@@ -52,6 +52,9 @@ class HassioAddonDashboard extends LitElement {
 | 
			
		||||
 | 
			
		||||
  @property({ type: Boolean }) public narrow = false;
 | 
			
		||||
 | 
			
		||||
  @state()
 | 
			
		||||
  private _controlEnabled = false;
 | 
			
		||||
 | 
			
		||||
  @state() private _error?: string;
 | 
			
		||||
 | 
			
		||||
  private _backPath = new URLSearchParams(window.parent.location.search).get(
 | 
			
		||||
@@ -134,11 +137,17 @@ class HassioAddonDashboard extends LitElement {
 | 
			
		||||
          .hass=${this.hass}
 | 
			
		||||
          .supervisor=${this.supervisor}
 | 
			
		||||
          .addon=${this.addon}
 | 
			
		||||
          .controlEnabled=${this._controlEnabled}
 | 
			
		||||
          @system-managed-take-control=${this._enableControl}
 | 
			
		||||
        ></hassio-addon-router>
 | 
			
		||||
      </hass-tabs-subpage>
 | 
			
		||||
    `;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private _enableControl() {
 | 
			
		||||
    this._controlEnabled = true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static get styles(): CSSResultGroup {
 | 
			
		||||
    return [
 | 
			
		||||
      haStyle,
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,9 @@ class HassioAddonRouter extends HassRouterPage {
 | 
			
		||||
    | HassioAddonDetails
 | 
			
		||||
    | StoreAddonDetails;
 | 
			
		||||
 | 
			
		||||
  @property({ type: Boolean, attribute: "control-enabled" })
 | 
			
		||||
  public controlEnabled = false;
 | 
			
		||||
 | 
			
		||||
  protected routerOptions: RouterOptions = {
 | 
			
		||||
    defaultPage: "info",
 | 
			
		||||
    showLoading: true,
 | 
			
		||||
@@ -48,6 +51,7 @@ class HassioAddonRouter extends HassRouterPage {
 | 
			
		||||
    el.supervisor = this.supervisor;
 | 
			
		||||
    el.addon = this.addon;
 | 
			
		||||
    el.narrow = this.narrow;
 | 
			
		||||
    el.controlEnabled = this.controlEnabled;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,9 @@ class HassioAddonInfoDashboard extends LitElement {
 | 
			
		||||
 | 
			
		||||
  @property({ attribute: false }) public addon?: HassioAddonDetails;
 | 
			
		||||
 | 
			
		||||
  @property({ type: Boolean, attribute: "control-enabled" })
 | 
			
		||||
  public controlEnabled = false;
 | 
			
		||||
 | 
			
		||||
  protected render(): TemplateResult {
 | 
			
		||||
    if (!this.addon) {
 | 
			
		||||
      return html`<ha-spinner></ha-spinner>`;
 | 
			
		||||
@@ -34,6 +37,7 @@ class HassioAddonInfoDashboard extends LitElement {
 | 
			
		||||
          .hass=${this.hass}
 | 
			
		||||
          .supervisor=${this.supervisor}
 | 
			
		||||
          .addon=${this.addon}
 | 
			
		||||
          .controlEnabled=${this.controlEnabled}
 | 
			
		||||
        ></hassio-addon-info>
 | 
			
		||||
      </div>
 | 
			
		||||
    `;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,6 @@
 | 
			
		||||
import "@material/mwc-button";
 | 
			
		||||
import {
 | 
			
		||||
  mdiCheckCircle,
 | 
			
		||||
  mdiChip,
 | 
			
		||||
  mdiPlayCircle,
 | 
			
		||||
  mdiCircleOffOutline,
 | 
			
		||||
  mdiCursorDefaultClickOutline,
 | 
			
		||||
  mdiDocker,
 | 
			
		||||
@@ -19,27 +17,30 @@ import {
 | 
			
		||||
  mdiNumeric6,
 | 
			
		||||
  mdiNumeric7,
 | 
			
		||||
  mdiNumeric8,
 | 
			
		||||
  mdiPlayCircle,
 | 
			
		||||
  mdiPound,
 | 
			
		||||
  mdiShield,
 | 
			
		||||
} from "@mdi/js";
 | 
			
		||||
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 { classMap } from "lit/directives/class-map";
 | 
			
		||||
import memoizeOne from "memoize-one";
 | 
			
		||||
import { atLeastVersion } from "../../../../src/common/config/version";
 | 
			
		||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
 | 
			
		||||
import { navigate } from "../../../../src/common/navigate";
 | 
			
		||||
import { capitalizeFirstLetter } from "../../../../src/common/string/capitalize-first-letter";
 | 
			
		||||
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-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-settings-row";
 | 
			
		||||
import "../../../../src/components/ha-svg-icon";
 | 
			
		||||
import "../../../../src/components/ha-switch";
 | 
			
		||||
import "../../../../src/components/ha-formfield";
 | 
			
		||||
import type { HaSwitch } from "../../../../src/components/ha-switch";
 | 
			
		||||
import type {
 | 
			
		||||
  AddonCapability,
 | 
			
		||||
@@ -81,10 +82,11 @@ import { bytesToString } from "../../../../src/util/bytes-to-string";
 | 
			
		||||
import "../../components/hassio-card-content";
 | 
			
		||||
import "../../components/supervisor-metric";
 | 
			
		||||
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 "../../update-available/update-available-card";
 | 
			
		||||
import { addonArchIsSupported, extractChangelog } from "../../util/addon";
 | 
			
		||||
import { capitalizeFirstLetter } from "../../../../src/common/string/capitalize-first-letter";
 | 
			
		||||
import "./hassio-addon-system-managed";
 | 
			
		||||
 | 
			
		||||
const STAGE_ICON = {
 | 
			
		||||
  stable: mdiCheckCircle,
 | 
			
		||||
@@ -117,6 +119,9 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
 | 
			
		||||
  @property({ attribute: false }) public supervisor!: Supervisor;
 | 
			
		||||
 | 
			
		||||
  @property({ type: Boolean, attribute: "control-enabled" })
 | 
			
		||||
  public controlEnabled = false;
 | 
			
		||||
 | 
			
		||||
  @state() private _metrics?: HassioStats;
 | 
			
		||||
 | 
			
		||||
  @state() private _error?: string;
 | 
			
		||||
@@ -155,6 +160,9 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
        )}`,
 | 
			
		||||
      },
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    const systemManaged = this._isSystemManaged(this.addon);
 | 
			
		||||
 | 
			
		||||
    return html`
 | 
			
		||||
      ${this.addon.update_available
 | 
			
		||||
        ? html`
 | 
			
		||||
@@ -166,7 +174,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
              @update-complete=${this._updateComplete}
 | 
			
		||||
            ></update-available-card>
 | 
			
		||||
          `
 | 
			
		||||
        : ""}
 | 
			
		||||
        : nothing}
 | 
			
		||||
      ${"protected" in this.addon && !this.addon.protected
 | 
			
		||||
        ? html`
 | 
			
		||||
            <ha-alert
 | 
			
		||||
@@ -178,22 +186,31 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
              ${this.supervisor.localize(
 | 
			
		||||
                "addon.dashboard.protection_mode.content"
 | 
			
		||||
              )}
 | 
			
		||||
              <mwc-button
 | 
			
		||||
              <ha-button
 | 
			
		||||
                slot="action"
 | 
			
		||||
                .label=${this.supervisor.localize(
 | 
			
		||||
                  "addon.dashboard.protection_mode.enable"
 | 
			
		||||
                )}
 | 
			
		||||
                @click=${this._protectionToggled}
 | 
			
		||||
              >
 | 
			
		||||
              </mwc-button>
 | 
			
		||||
              </ha-button>
 | 
			
		||||
            </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>
 | 
			
		||||
        <div class="card-content">
 | 
			
		||||
          <div class="addon-header">
 | 
			
		||||
            ${!this.narrow ? this.addon.name : ""}
 | 
			
		||||
            ${!this.narrow ? this.addon.name : nothing}
 | 
			
		||||
            <div class="addon-version light-color">
 | 
			
		||||
              ${this.addon.version
 | 
			
		||||
                ? html`
 | 
			
		||||
@@ -266,7 +283,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                    </ha-svg-icon>
 | 
			
		||||
                  </ha-assist-chip>
 | 
			
		||||
                `
 | 
			
		||||
              : ""}
 | 
			
		||||
              : nothing}
 | 
			
		||||
 | 
			
		||||
            <ha-assist-chip
 | 
			
		||||
              filled
 | 
			
		||||
@@ -301,7 +318,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                    <ha-svg-icon slot="icon" .path=${mdiNetwork}> </ha-svg-icon>
 | 
			
		||||
                  </ha-assist-chip>
 | 
			
		||||
                `
 | 
			
		||||
              : ""}
 | 
			
		||||
              : nothing}
 | 
			
		||||
            ${this.addon.full_access
 | 
			
		||||
              ? html`
 | 
			
		||||
                  <ha-assist-chip
 | 
			
		||||
@@ -317,7 +334,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                    <ha-svg-icon slot="icon" .path=${mdiChip}></ha-svg-icon>
 | 
			
		||||
                  </ha-assist-chip>
 | 
			
		||||
                `
 | 
			
		||||
              : ""}
 | 
			
		||||
              : nothing}
 | 
			
		||||
            ${this.addon.homeassistant_api
 | 
			
		||||
              ? html`
 | 
			
		||||
                  <ha-assist-chip
 | 
			
		||||
@@ -336,7 +353,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                    ></ha-svg-icon>
 | 
			
		||||
                  </ha-assist-chip>
 | 
			
		||||
                `
 | 
			
		||||
              : ""}
 | 
			
		||||
              : nothing}
 | 
			
		||||
            ${this._computeHassioApi
 | 
			
		||||
              ? html`
 | 
			
		||||
                  <ha-assist-chip
 | 
			
		||||
@@ -355,7 +372,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                    ></ha-svg-icon>
 | 
			
		||||
                  </ha-assist-chip>
 | 
			
		||||
                `
 | 
			
		||||
              : ""}
 | 
			
		||||
              : nothing}
 | 
			
		||||
            ${this.addon.docker_api
 | 
			
		||||
              ? html`
 | 
			
		||||
                  <ha-assist-chip
 | 
			
		||||
@@ -371,7 +388,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                    <ha-svg-icon slot="icon" .path=${mdiDocker}></ha-svg-icon>
 | 
			
		||||
                  </ha-assist-chip>
 | 
			
		||||
                `
 | 
			
		||||
              : ""}
 | 
			
		||||
              : nothing}
 | 
			
		||||
            ${this.addon.host_pid
 | 
			
		||||
              ? html`
 | 
			
		||||
                  <ha-assist-chip
 | 
			
		||||
@@ -387,7 +404,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                    <ha-svg-icon slot="icon" .path=${mdiPound}></ha-svg-icon>
 | 
			
		||||
                  </ha-assist-chip>
 | 
			
		||||
                `
 | 
			
		||||
              : ""}
 | 
			
		||||
              : nothing}
 | 
			
		||||
            ${this.addon.apparmor !== "default"
 | 
			
		||||
              ? html`
 | 
			
		||||
                  <ha-assist-chip
 | 
			
		||||
@@ -404,7 +421,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                    <ha-svg-icon slot="icon" .path=${mdiShield}></ha-svg-icon>
 | 
			
		||||
                  </ha-assist-chip>
 | 
			
		||||
                `
 | 
			
		||||
              : ""}
 | 
			
		||||
              : nothing}
 | 
			
		||||
            ${this.addon.auth_api
 | 
			
		||||
              ? html`
 | 
			
		||||
                  <ha-assist-chip
 | 
			
		||||
@@ -420,7 +437,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                    <ha-svg-icon slot="icon" .path=${mdiKey}></ha-svg-icon>
 | 
			
		||||
                  </ha-assist-chip>
 | 
			
		||||
                `
 | 
			
		||||
              : ""}
 | 
			
		||||
              : nothing}
 | 
			
		||||
            ${this.addon.ingress
 | 
			
		||||
              ? html`
 | 
			
		||||
                  <ha-assist-chip
 | 
			
		||||
@@ -439,7 +456,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                    ></ha-svg-icon>
 | 
			
		||||
                  </ha-assist-chip>
 | 
			
		||||
                `
 | 
			
		||||
              : ""}
 | 
			
		||||
              : nothing}
 | 
			
		||||
            ${this.addon.signed
 | 
			
		||||
              ? html`
 | 
			
		||||
                  <ha-assist-chip
 | 
			
		||||
@@ -455,7 +472,24 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                    <ha-svg-icon slot="icon" .path=${mdiLinkLock}></ha-svg-icon>
 | 
			
		||||
                  </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>
 | 
			
		||||
 | 
			
		||||
          <div class="description light-color">
 | 
			
		||||
@@ -479,7 +513,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                      src="/api/hassio/addons/${this.addon.slug}/logo"
 | 
			
		||||
                    />
 | 
			
		||||
                  `
 | 
			
		||||
                : ""}
 | 
			
		||||
                : nothing}
 | 
			
		||||
              ${this.addon.version
 | 
			
		||||
                ? html`
 | 
			
		||||
                    <div
 | 
			
		||||
@@ -500,6 +534,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                          )}
 | 
			
		||||
                        </span>
 | 
			
		||||
                        <ha-switch
 | 
			
		||||
                          .disabled=${systemManaged && !this.controlEnabled}
 | 
			
		||||
                          @change=${this._startOnBootToggled}
 | 
			
		||||
                          .checked=${this.addon.boot === "auto"}
 | 
			
		||||
                          haptic
 | 
			
		||||
@@ -520,13 +555,15 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                                )}
 | 
			
		||||
                              </span>
 | 
			
		||||
                              <ha-switch
 | 
			
		||||
                                .disabled=${systemManaged &&
 | 
			
		||||
                                !this.controlEnabled}
 | 
			
		||||
                                @change=${this._watchdogToggled}
 | 
			
		||||
                                .checked=${this.addon.watchdog}
 | 
			
		||||
                                .checked=${this.addon.watchdog || false}
 | 
			
		||||
                                haptic
 | 
			
		||||
                              ></ha-switch>
 | 
			
		||||
                            </ha-settings-row>
 | 
			
		||||
                          `
 | 
			
		||||
                        : ""}
 | 
			
		||||
                        : nothing}
 | 
			
		||||
                      ${this.addon.auto_update ||
 | 
			
		||||
                      this.hass.userData?.showAdvanced
 | 
			
		||||
                        ? html`
 | 
			
		||||
@@ -542,13 +579,15 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                                )}
 | 
			
		||||
                              </span>
 | 
			
		||||
                              <ha-switch
 | 
			
		||||
                                .disabled=${systemManaged &&
 | 
			
		||||
                                !this.controlEnabled}
 | 
			
		||||
                                @change=${this._autoUpdateToggled}
 | 
			
		||||
                                .checked=${this.addon.auto_update}
 | 
			
		||||
                                haptic
 | 
			
		||||
                              ></ha-switch>
 | 
			
		||||
                            </ha-settings-row>
 | 
			
		||||
                          `
 | 
			
		||||
                        : ""}
 | 
			
		||||
                        : nothing}
 | 
			
		||||
                      ${!this._computeCannotIngressSidebar && this.addon.ingress
 | 
			
		||||
                        ? html`
 | 
			
		||||
                            <ha-settings-row ?three-line=${this.narrow}>
 | 
			
		||||
@@ -563,13 +602,15 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                                )}
 | 
			
		||||
                              </span>
 | 
			
		||||
                              <ha-switch
 | 
			
		||||
                                .disabled=${systemManaged &&
 | 
			
		||||
                                !this.controlEnabled}
 | 
			
		||||
                                @change=${this._panelToggled}
 | 
			
		||||
                                .checked=${this.addon.ingress_panel}
 | 
			
		||||
                                haptic
 | 
			
		||||
                              ></ha-switch>
 | 
			
		||||
                            </ha-settings-row>
 | 
			
		||||
                          `
 | 
			
		||||
                        : ""}
 | 
			
		||||
                        : nothing}
 | 
			
		||||
                      ${this._computeUsesProtectedOptions
 | 
			
		||||
                        ? html`
 | 
			
		||||
                            <ha-settings-row ?three-line=${this.narrow}>
 | 
			
		||||
@@ -584,16 +625,18 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                                )}
 | 
			
		||||
                              </span>
 | 
			
		||||
                              <ha-switch
 | 
			
		||||
                                .disabled=${systemManaged &&
 | 
			
		||||
                                !this.controlEnabled}
 | 
			
		||||
                                @change=${this._protectionToggled}
 | 
			
		||||
                                .checked=${this.addon.protected}
 | 
			
		||||
                                haptic
 | 
			
		||||
                              ></ha-switch>
 | 
			
		||||
                            </ha-settings-row>
 | 
			
		||||
                          `
 | 
			
		||||
                        : ""}
 | 
			
		||||
                        : nothing}
 | 
			
		||||
                    </div>
 | 
			
		||||
                  `
 | 
			
		||||
                : ""}
 | 
			
		||||
                : nothing}
 | 
			
		||||
            </div>
 | 
			
		||||
            <div>
 | 
			
		||||
              ${this.addon.version && this.addon.state === "started"
 | 
			
		||||
@@ -612,12 +655,12 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                        ></supervisor-metric>
 | 
			
		||||
                      `
 | 
			
		||||
                    )}`
 | 
			
		||||
                : ""}
 | 
			
		||||
                : nothing}
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          ${this._error
 | 
			
		||||
            ? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
 | 
			
		||||
            : ""}
 | 
			
		||||
            : nothing}
 | 
			
		||||
          ${!this.addon.version && addonStoreInfo && !this.addon.available
 | 
			
		||||
            ? !addonArchIsSupported(
 | 
			
		||||
                this.supervisor.info.supported_arch,
 | 
			
		||||
@@ -641,7 +684,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                    )}
 | 
			
		||||
                  </ha-alert>
 | 
			
		||||
                `
 | 
			
		||||
            : ""}
 | 
			
		||||
            : nothing}
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="card-actions">
 | 
			
		||||
          <div>
 | 
			
		||||
@@ -651,6 +694,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                    <ha-progress-button
 | 
			
		||||
                      class="warning"
 | 
			
		||||
                      @click=${this._stopClicked}
 | 
			
		||||
                      .disabled=${systemManaged && !this.controlEnabled}
 | 
			
		||||
                    >
 | 
			
		||||
                      ${this.supervisor.localize("addon.dashboard.stop")}
 | 
			
		||||
                    </ha-progress-button>
 | 
			
		||||
@@ -688,26 +732,27 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                          target="_blank"
 | 
			
		||||
                          rel="noopener"
 | 
			
		||||
                        >
 | 
			
		||||
                          <mwc-button>
 | 
			
		||||
                          <ha-button>
 | 
			
		||||
                            ${this.supervisor.localize(
 | 
			
		||||
                              "addon.dashboard.open_web_ui"
 | 
			
		||||
                            )}
 | 
			
		||||
                          </mwc-button>
 | 
			
		||||
                          </ha-button>
 | 
			
		||||
                        </a>
 | 
			
		||||
                      `
 | 
			
		||||
                    : ""}
 | 
			
		||||
                    : nothing}
 | 
			
		||||
                  ${this._computeShowIngressUI
 | 
			
		||||
                    ? html`
 | 
			
		||||
                        <mwc-button @click=${this._openIngress}>
 | 
			
		||||
                        <ha-button @click=${this._openIngress}>
 | 
			
		||||
                          ${this.supervisor.localize(
 | 
			
		||||
                            "addon.dashboard.open_web_ui"
 | 
			
		||||
                          )}
 | 
			
		||||
                        </mwc-button>
 | 
			
		||||
                        </ha-button>
 | 
			
		||||
                      `
 | 
			
		||||
                    : ""}
 | 
			
		||||
                    : nothing}
 | 
			
		||||
                  <ha-progress-button
 | 
			
		||||
                    class="warning"
 | 
			
		||||
                    @click=${this._uninstallClicked}
 | 
			
		||||
                    .disabled=${systemManaged && !this.controlEnabled}
 | 
			
		||||
                  >
 | 
			
		||||
                    ${this.supervisor.localize("addon.dashboard.uninstall")}
 | 
			
		||||
                  </ha-progress-button>
 | 
			
		||||
@@ -720,8 +765,8 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
                          ${this.supervisor.localize("addon.dashboard.rebuild")}
 | 
			
		||||
                        </ha-progress-button>
 | 
			
		||||
                      `
 | 
			
		||||
                    : ""}`
 | 
			
		||||
              : ""}
 | 
			
		||||
                    : nothing}`
 | 
			
		||||
              : nothing}
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </ha-card>
 | 
			
		||||
@@ -737,7 +782,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
              </div>
 | 
			
		||||
            </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 {
 | 
			
		||||
    return (this.addon as HassioAddonDetails)?.state === "started";
 | 
			
		||||
  }
 | 
			
		||||
@@ -1014,6 +1066,10 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async _stopClicked(ev: CustomEvent): Promise<void> {
 | 
			
		||||
    if (this._isSystemManaged(this.addon) && !this.controlEnabled) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const button = ev.currentTarget as any;
 | 
			
		||||
    button.progress = true;
 | 
			
		||||
 | 
			
		||||
@@ -1125,6 +1181,10 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async _uninstallClicked(ev: CustomEvent): Promise<void> {
 | 
			
		||||
    if (this._isSystemManaged(this.addon) && !this.controlEnabled) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const button = ev.currentTarget as any;
 | 
			
		||||
    button.progress = true;
 | 
			
		||||
    let removeData = false;
 | 
			
		||||
@@ -1179,6 +1239,11 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
    button.progress = false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private _isSystemManaged = memoizeOne(
 | 
			
		||||
    (addon: HassioAddonDetails | StoreAddonDetails) =>
 | 
			
		||||
      "system_managed" in addon && addon.system_managed
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  static get styles(): CSSResultGroup {
 | 
			
		||||
    return [
 | 
			
		||||
      haStyle,
 | 
			
		||||
@@ -1201,7 +1266,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
        ha-card.warning .card-content {
 | 
			
		||||
          color: white;
 | 
			
		||||
        }
 | 
			
		||||
        ha-card.warning mwc-button {
 | 
			
		||||
        ha-card.warning ha-button {
 | 
			
		||||
          --mdc-theme-primary: white !important;
 | 
			
		||||
        }
 | 
			
		||||
        .warning {
 | 
			
		||||
@@ -1215,12 +1280,12 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
          padding-left: 8px;
 | 
			
		||||
          padding-inline-start: 8px;
 | 
			
		||||
          padding-inline-end: initial;
 | 
			
		||||
          font-size: 24px;
 | 
			
		||||
          font-size: var(--ha-font-size-2xl);
 | 
			
		||||
          color: var(--ha-card-header-color, var(--primary-text-color));
 | 
			
		||||
        }
 | 
			
		||||
        .addon-version {
 | 
			
		||||
          float: var(--float-end);
 | 
			
		||||
          font-size: 15px;
 | 
			
		||||
          font-size: var(--ha-font-size-l);
 | 
			
		||||
          vertical-align: middle;
 | 
			
		||||
        }
 | 
			
		||||
        .errors {
 | 
			
		||||
@@ -1246,7 +1311,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
        ha-svg-icon.stopped {
 | 
			
		||||
          color: var(--error-color);
 | 
			
		||||
        }
 | 
			
		||||
        protection-enable mwc-button {
 | 
			
		||||
        protection-enable ha-button {
 | 
			
		||||
          --mdc-theme-primary: white;
 | 
			
		||||
        }
 | 
			
		||||
        .description a {
 | 
			
		||||
@@ -1328,7 +1393,7 @@ class HassioAddonInfo extends LitElement {
 | 
			
		||||
          align-self: end;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ha-alert mwc-button {
 | 
			
		||||
        ha-alert ha-button {
 | 
			
		||||
          --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 type { ActionDetail } from "@material/mwc-list";
 | 
			
		||||
import "@material/mwc-list/mwc-list-item";
 | 
			
		||||
 | 
			
		||||
import { mdiBackupRestore, mdiDelete, mdiDotsVertical, mdiPlus } from "@mdi/js";
 | 
			
		||||
import type { CSSResultGroup, PropertyValues } 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-fab";
 | 
			
		||||
import "../../../src/components/ha-icon-button";
 | 
			
		||||
import "../../../src/components/ha-list-item";
 | 
			
		||||
import "../../../src/components/ha-svg-icon";
 | 
			
		||||
import type { HassioBackup } from "../../../src/data/hassio/backup";
 | 
			
		||||
import {
 | 
			
		||||
@@ -32,6 +33,7 @@ import {
 | 
			
		||||
  showAlertDialog,
 | 
			
		||||
  showConfirmationDialog,
 | 
			
		||||
} from "../../../src/dialogs/generic/show-dialog-box";
 | 
			
		||||
import "../../../src/layouts/hass-loading-screen";
 | 
			
		||||
import "../../../src/layouts/hass-tabs-subpage-data-table";
 | 
			
		||||
import type { HaTabsSubpageDataTable } from "../../../src/layouts/hass-tabs-subpage-data-table";
 | 
			
		||||
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 { supervisorTabs } from "../hassio-tabs";
 | 
			
		||||
import { hassioStyle } from "../resources/hassio-style";
 | 
			
		||||
import "../../../src/layouts/hass-loading-screen";
 | 
			
		||||
 | 
			
		||||
type BackupItem = HassioBackup & {
 | 
			
		||||
  secondary: string;
 | 
			
		||||
@@ -211,16 +212,16 @@ export class HassioBackups extends LitElement {
 | 
			
		||||
            .path=${mdiDotsVertical}
 | 
			
		||||
            slot="trigger"
 | 
			
		||||
          ></ha-icon-button>
 | 
			
		||||
          <mwc-list-item>
 | 
			
		||||
          <ha-list-item>
 | 
			
		||||
            ${this.supervisor.localize("common.reload")}
 | 
			
		||||
          </mwc-list-item>
 | 
			
		||||
          <mwc-list-item>
 | 
			
		||||
          </ha-list-item>
 | 
			
		||||
          <ha-list-item>
 | 
			
		||||
            ${this.supervisor.localize("dialog.backup_location.title")}
 | 
			
		||||
          </mwc-list-item>
 | 
			
		||||
          </ha-list-item>
 | 
			
		||||
          ${atLeastVersion(this.hass.config.version, 0, 116)
 | 
			
		||||
            ? html`<mwc-list-item>
 | 
			
		||||
            ? html`<ha-list-item>
 | 
			
		||||
                ${this.supervisor.localize("backup.upload_backup")}
 | 
			
		||||
              </mwc-list-item>`
 | 
			
		||||
              </ha-list-item>`
 | 
			
		||||
            : ""}
 | 
			
		||||
        </ha-button-menu>
 | 
			
		||||
 | 
			
		||||
@@ -390,7 +391,7 @@ export class HassioBackups extends LitElement {
 | 
			
		||||
          top: -4px;
 | 
			
		||||
        }
 | 
			
		||||
        .selected-txt {
 | 
			
		||||
          font-weight: bold;
 | 
			
		||||
          font-weight: var(--ha-font-weight-bold);
 | 
			
		||||
          padding-left: 16px;
 | 
			
		||||
          padding-inline-start: 16px;
 | 
			
		||||
          padding-inline-end: initial;
 | 
			
		||||
@@ -400,7 +401,7 @@ export class HassioBackups extends LitElement {
 | 
			
		||||
          margin-top: 20px;
 | 
			
		||||
        }
 | 
			
		||||
        .header-toolbar .selected-txt {
 | 
			
		||||
          font-size: 16px;
 | 
			
		||||
          font-size: var(--ha-font-size-l);
 | 
			
		||||
        }
 | 
			
		||||
        .header-toolbar .header-btns {
 | 
			
		||||
          margin-right: -12px;
 | 
			
		||||
 
 | 
			
		||||
@@ -85,7 +85,7 @@ class HassioCardContent extends LitElement {
 | 
			
		||||
    }
 | 
			
		||||
    ha-svg-icon.hassupdate,
 | 
			
		||||
    ha-svg-icon.backup {
 | 
			
		||||
      color: var(--paper-item-icon-color);
 | 
			
		||||
      color: var(--state-icon-color);
 | 
			
		||||
    }
 | 
			
		||||
    ha-svg-icon.not_available {
 | 
			
		||||
      color: var(--error-color);
 | 
			
		||||
 
 | 
			
		||||
@@ -130,8 +130,8 @@ export class HassioUpdate extends LitElement {
 | 
			
		||||
          color: var(--primary-text-color);
 | 
			
		||||
        }
 | 
			
		||||
        .update-heading {
 | 
			
		||||
          font-size: var(--paper-font-subhead_-_font-size);
 | 
			
		||||
          font-weight: 500;
 | 
			
		||||
          font-size: var(--ha-font-size-l);
 | 
			
		||||
          font-weight: var(--ha-font-weight-medium);
 | 
			
		||||
          margin-bottom: 0.5em;
 | 
			
		||||
          color: var(--primary-text-color);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import type { ActionDetail } from "@material/mwc-list";
 | 
			
		||||
import "@material/mwc-list/mwc-list-item";
 | 
			
		||||
 | 
			
		||||
import { mdiClose, mdiDotsVertical } from "@mdi/js";
 | 
			
		||||
import type { CSSResultGroup } 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 { stopPropagation } from "../../../../src/common/dom/stop_propagation";
 | 
			
		||||
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/ha-alert";
 | 
			
		||||
import "../../../../src/components/ha-spinner";
 | 
			
		||||
import "../../../../src/components/ha-button";
 | 
			
		||||
import "../../../../src/components/ha-button-menu";
 | 
			
		||||
import "../../../../src/components/ha-dialog-header";
 | 
			
		||||
import "../../../../src/components/ha-header-bar";
 | 
			
		||||
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 type { HassioBackupDetail } from "../../../../src/data/hassio/backup";
 | 
			
		||||
import {
 | 
			
		||||
@@ -36,7 +38,6 @@ import { fileDownload } from "../../../../src/util/file_download";
 | 
			
		||||
import "../../components/supervisor-backup-content";
 | 
			
		||||
import type { SupervisorBackupContent } from "../../components/supervisor-backup-content";
 | 
			
		||||
import type { HassioBackupDialogParams } from "./show-dialog-hassio-backup";
 | 
			
		||||
import type { HaMdDialog } from "../../../../src/components/ha-md-dialog";
 | 
			
		||||
 | 
			
		||||
@customElement("dialog-hassio-backup")
 | 
			
		||||
class HassioBackupDialog
 | 
			
		||||
@@ -121,15 +122,15 @@ class HassioBackupDialog
 | 
			
		||||
                  .path=${mdiDotsVertical}
 | 
			
		||||
                  slot="trigger"
 | 
			
		||||
                ></ha-icon-button>
 | 
			
		||||
                <mwc-list-item
 | 
			
		||||
                <ha-list-item
 | 
			
		||||
                  >${this._dialogParams.supervisor.localize(
 | 
			
		||||
                    "backup.download_backup"
 | 
			
		||||
                  )}</mwc-list-item
 | 
			
		||||
                  )}</ha-list-item
 | 
			
		||||
                >
 | 
			
		||||
                <mwc-list-item class="error"
 | 
			
		||||
                <ha-list-item class="error"
 | 
			
		||||
                  >${this._dialogParams.supervisor.localize(
 | 
			
		||||
                    "backup.delete_backup_title"
 | 
			
		||||
                  )}</mwc-list-item
 | 
			
		||||
                  )}</ha-list-item
 | 
			
		||||
                >
 | 
			
		||||
              </ha-button-menu>`
 | 
			
		||||
            : nothing}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,12 @@
 | 
			
		||||
import "@material/mwc-list/mwc-list-item";
 | 
			
		||||
import type { CSSResultGroup } from "lit";
 | 
			
		||||
import { css, html, LitElement, nothing } from "lit";
 | 
			
		||||
import { customElement, property, state } from "lit/decorators";
 | 
			
		||||
import memoizeOne from "memoize-one";
 | 
			
		||||
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-list-item";
 | 
			
		||||
import "../../../../src/components/ha-select";
 | 
			
		||||
import "../../../../src/components/ha-spinner";
 | 
			
		||||
import {
 | 
			
		||||
  extractApiErrorMessage,
 | 
			
		||||
  ignoreSupervisorError,
 | 
			
		||||
@@ -95,8 +95,8 @@ class HassioDatadiskDialog extends LitElement {
 | 
			
		||||
                    >
 | 
			
		||||
                      ${this.devices.map(
 | 
			
		||||
                        (device) =>
 | 
			
		||||
                          html`<mwc-list-item .value=${device}
 | 
			
		||||
                            >${device}</mwc-list-item
 | 
			
		||||
                          html`<ha-list-item .value=${device}
 | 
			
		||||
                            >${device}</ha-list-item
 | 
			
		||||
                          >`
 | 
			
		||||
                      )}
 | 
			
		||||
                    </ha-select>
 | 
			
		||||
 
 | 
			
		||||
@@ -16,23 +16,14 @@ import type { HomeAssistant } from "../../../../src/types";
 | 
			
		||||
import type { HassioHardwareDialogParams } from "./show-dialog-hassio-hardware";
 | 
			
		||||
 | 
			
		||||
const _filterDevices = memoizeOne(
 | 
			
		||||
  (
 | 
			
		||||
    showAdvanced: boolean,
 | 
			
		||||
    hardware: HassioHardwareInfo,
 | 
			
		||||
    filter: string,
 | 
			
		||||
    language: string
 | 
			
		||||
  ) =>
 | 
			
		||||
  (hardware: HassioHardwareInfo, filter: string, language: string) =>
 | 
			
		||||
    hardware.devices
 | 
			
		||||
      .filter(
 | 
			
		||||
        (device) =>
 | 
			
		||||
          (showAdvanced ||
 | 
			
		||||
            ["tty", "gpio", "input"].includes(device.subsystem)) &&
 | 
			
		||||
          (device.by_id?.toLowerCase().includes(filter) ||
 | 
			
		||||
            device.name.toLowerCase().includes(filter) ||
 | 
			
		||||
            device.dev_path.toLocaleLowerCase().includes(filter) ||
 | 
			
		||||
            JSON.stringify(device.attributes)
 | 
			
		||||
              .toLocaleLowerCase()
 | 
			
		||||
              .includes(filter))
 | 
			
		||||
          device.by_id?.toLowerCase().includes(filter) ||
 | 
			
		||||
          device.name.toLowerCase().includes(filter) ||
 | 
			
		||||
          device.dev_path.toLocaleLowerCase().includes(filter) ||
 | 
			
		||||
          JSON.stringify(device.attributes).toLocaleLowerCase().includes(filter)
 | 
			
		||||
      )
 | 
			
		||||
      .sort((a, b) => stringCompare(a.name, b.name, language))
 | 
			
		||||
);
 | 
			
		||||
@@ -60,7 +51,6 @@ class HassioHardwareDialog extends LitElement {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const devices = _filterDevices(
 | 
			
		||||
      this.hass.userData?.showAdvanced || false,
 | 
			
		||||
      this._dialogParams.hardware,
 | 
			
		||||
      (this._filter || "").toLowerCase(),
 | 
			
		||||
      this.hass.locale.language
 | 
			
		||||
@@ -180,10 +170,10 @@ class HassioHardwareDialog extends LitElement {
 | 
			
		||||
          padding: 16px;
 | 
			
		||||
          overflow: auto;
 | 
			
		||||
          line-height: 1.45;
 | 
			
		||||
          font-family: var(--code-font-family, monospace);
 | 
			
		||||
          font-family: var(--ha-font-family-code);
 | 
			
		||||
        }
 | 
			
		||||
        code {
 | 
			
		||||
          font-size: 85%;
 | 
			
		||||
          font-size: var(--ha-font-size-s);
 | 
			
		||||
          padding: 0.2em 0.4em;
 | 
			
		||||
        }
 | 
			
		||||
        search-input {
 | 
			
		||||
 
 | 
			
		||||
@@ -38,6 +38,7 @@ class HassioMarkdownDialog extends LitElement {
 | 
			
		||||
        open
 | 
			
		||||
        @closed=${this.closeDialog}
 | 
			
		||||
        .heading=${createCloseHeading(this.hass, this.title)}
 | 
			
		||||
        hideactions
 | 
			
		||||
      >
 | 
			
		||||
        <ha-markdown
 | 
			
		||||
          .content=${this.content || ""}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,4 @@
 | 
			
		||||
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 type { CSSResultGroup } 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 { fireEvent } from "../../../../src/common/dom/fire_event";
 | 
			
		||||
import "../../../../src/components/ha-alert";
 | 
			
		||||
import "../../../../src/components/ha-spinner";
 | 
			
		||||
import "../../../../src/components/ha-dialog";
 | 
			
		||||
import "../../../../src/components/ha-expansion-panel";
 | 
			
		||||
import "../../../../src/components/ha-formfield";
 | 
			
		||||
import "../../../../src/components/ha-header-bar";
 | 
			
		||||
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-radio";
 | 
			
		||||
import "../../../../src/components/ha-spinner";
 | 
			
		||||
import "../../../../src/components/ha-textfield";
 | 
			
		||||
import type { HaTextField } from "../../../../src/components/ha-textfield";
 | 
			
		||||
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 type { HomeAssistant } from "../../../../src/types";
 | 
			
		||||
import type { HassioNetworkDialogParams } from "./show-dialog-network";
 | 
			
		||||
import "../../../../src/components/sl-tab-group";
 | 
			
		||||
 | 
			
		||||
const IP_VERSIONS = ["ipv4", "ipv6"];
 | 
			
		||||
 | 
			
		||||
@@ -116,19 +115,19 @@ export class DialogHassioNetwork
 | 
			
		||||
            ></ha-icon-button>
 | 
			
		||||
          </ha-header-bar>
 | 
			
		||||
          ${this._interfaces.length > 1
 | 
			
		||||
            ? html`<mwc-tab-bar
 | 
			
		||||
                .activeIndex=${this._curTabIndex}
 | 
			
		||||
                @MDCTabBar:activated=${this._handleTabActivated}
 | 
			
		||||
            ? html`<sl-tab-group @sl-tab-show=${this._handleTabActivated}
 | 
			
		||||
                >${this._interfaces.map(
 | 
			
		||||
                  (device) =>
 | 
			
		||||
                    html`<mwc-tab
 | 
			
		||||
                  (device, index) =>
 | 
			
		||||
                    html`<sl-tab
 | 
			
		||||
                      slot="nav"
 | 
			
		||||
                      .id=${device.interface}
 | 
			
		||||
                      .label=${device.interface}
 | 
			
		||||
                      dialogInitialFocus
 | 
			
		||||
                      .panel=${index.toString()}
 | 
			
		||||
                      .active=${this._curTabIndex === index}
 | 
			
		||||
                    >
 | 
			
		||||
                    </mwc-tab>`
 | 
			
		||||
                      ${device.interface}
 | 
			
		||||
                    </sl-tab>`
 | 
			
		||||
                )}
 | 
			
		||||
              </mwc-tab-bar>`
 | 
			
		||||
              </sl-tab-group>`
 | 
			
		||||
            : ""}
 | 
			
		||||
        </div>
 | 
			
		||||
        ${cache(this._renderTab())}
 | 
			
		||||
@@ -169,12 +168,12 @@ export class DialogHassioNetwork
 | 
			
		||||
                this._accessPoints.accesspoints &&
 | 
			
		||||
                this._accessPoints.accesspoints.length !== 0
 | 
			
		||||
                  ? html`
 | 
			
		||||
                      <mwc-list>
 | 
			
		||||
                      <ha-list>
 | 
			
		||||
                        ${this._accessPoints.accesspoints
 | 
			
		||||
                          .filter((ap) => ap.ssid)
 | 
			
		||||
                          .map(
 | 
			
		||||
                            (ap) => html`
 | 
			
		||||
                              <mwc-list-item
 | 
			
		||||
                              <ha-list-item
 | 
			
		||||
                                twoline
 | 
			
		||||
                                @click=${this._selectAP}
 | 
			
		||||
                                .activated=${ap.ssid ===
 | 
			
		||||
@@ -189,10 +188,10 @@ export class DialogHassioNetwork
 | 
			
		||||
                                  )}:
 | 
			
		||||
                                  ${ap.signal}
 | 
			
		||||
                                </span>
 | 
			
		||||
                              </mwc-list-item>
 | 
			
		||||
                              </ha-list-item>
 | 
			
		||||
                            `
 | 
			
		||||
                          )}
 | 
			
		||||
                      </mwc-list>
 | 
			
		||||
                      </ha-list>
 | 
			
		||||
                    `
 | 
			
		||||
                  : ""}
 | 
			
		||||
                ${this._wifiConfiguration
 | 
			
		||||
@@ -485,8 +484,8 @@ export class DialogHassioNetwork
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    this._curTabIndex = ev.detail.index;
 | 
			
		||||
    this._interface = { ...this._interfaces[ev.detail.index] };
 | 
			
		||||
    this._curTabIndex = Number(ev.detail.name);
 | 
			
		||||
    this._interface = { ...this._interfaces[this._curTabIndex] };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private _handleRadioValueChanged(ev: CustomEvent): void {
 | 
			
		||||
@@ -560,11 +559,6 @@ export class DialogHassioNetwork
 | 
			
		||||
          flex-shrink: 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mwc-tab-bar {
 | 
			
		||||
          border-bottom: 1px solid
 | 
			
		||||
            var(--mdc-dialog-scroll-divider-color, rgba(0, 0, 0, 0.12));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ha-dialog {
 | 
			
		||||
          --dialog-content-position: static;
 | 
			
		||||
          --dialog-content-padding: 0;
 | 
			
		||||
@@ -634,9 +628,17 @@ export class DialogHassioNetwork
 | 
			
		||||
        ha-textfield {
 | 
			
		||||
          padding: 0 14px;
 | 
			
		||||
        }
 | 
			
		||||
        mwc-list-item {
 | 
			
		||||
        ha-list-item {
 | 
			
		||||
          --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 {
 | 
			
		||||
          --justify-action-buttons: flex-start;
 | 
			
		||||
        }
 | 
			
		||||
        paper-icon-item {
 | 
			
		||||
          cursor: pointer;
 | 
			
		||||
        }
 | 
			
		||||
        .form {
 | 
			
		||||
          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("../../src/resources/ha-style");
 | 
			
		||||
import("@polymer/polymer/lib/utils/settings").then(
 | 
			
		||||
  ({ setCancelSyntheticClickEvents }) => setCancelSyntheticClickEvents(false)
 | 
			
		||||
);
 | 
			
		||||
import("../../src/resources/append-ha-style");
 | 
			
		||||
 | 
			
		||||
const styleEl = document.createElement("style");
 | 
			
		||||
styleEl.textContent = `
 | 
			
		||||
body {
 | 
			
		||||
  font-family: Roboto, sans-serif;
 | 
			
		||||
  -moz-osx-font-smoothing: grayscale;
 | 
			
		||||
  -webkit-font-smoothing: antialiased;
 | 
			
		||||
  font-weight: 400;
 | 
			
		||||
  font-family: ${haFontFamilyBody};
 | 
			
		||||
  -moz-osx-font-smoothing: ${haMozOsxFontSmoothing};
 | 
			
		||||
  -webkit-font-smoothing: ${haFontSmoothing};
 | 
			
		||||
  font-weight: var(--ha-font-weight-normal);
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  height: 100vh;
 | 
			
		||||
 
 | 
			
		||||
@@ -340,12 +340,12 @@ class HassioIngressView extends LitElement {
 | 
			
		||||
    .header {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      font-size: 16px;
 | 
			
		||||
      font-size: var(--ha-font-size-l);
 | 
			
		||||
      height: 40px;
 | 
			
		||||
      padding: 0 16px;
 | 
			
		||||
      pointer-events: none;
 | 
			
		||||
      background-color: var(--app-header-background-color);
 | 
			
		||||
      font-weight: 400;
 | 
			
		||||
      font-weight: var(--ha-font-weight-normal);
 | 
			
		||||
      color: var(--app-header-text-color, white);
 | 
			
		||||
      border-bottom: var(--app-header-border-bottom, none);
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
 
 | 
			
		||||
@@ -12,12 +12,12 @@ export const hassioStyle = css`
 | 
			
		||||
  h1 {
 | 
			
		||||
    font-size: 2em;
 | 
			
		||||
    margin-bottom: 8px;
 | 
			
		||||
    font-family: var(--paper-font-headline_-_font-family);
 | 
			
		||||
    -webkit-font-smoothing: var(--paper-font-headline_-_-webkit-font-smoothing);
 | 
			
		||||
    font-size: var(--paper-font-headline_-_font-size);
 | 
			
		||||
    font-weight: var(--paper-font-headline_-_font-weight);
 | 
			
		||||
    letter-spacing: var(--paper-font-headline_-_letter-spacing);
 | 
			
		||||
    line-height: var(--paper-font-headline_-_line-height);
 | 
			
		||||
    font-family: var(--ha-font-family-body);
 | 
			
		||||
    -webkit-font-smoothing: var(--ha-font-smoothing);
 | 
			
		||||
    -moz-osx-font-smoothing: var(--ha-moz-osx-font-smoothing);
 | 
			
		||||
    font-size: var(--ha-font-size-2xl);
 | 
			
		||||
    font-weight: var(--ha-font-weight-normal);
 | 
			
		||||
    line-height: var(--ha-line-height-condensed);
 | 
			
		||||
    padding-left: 8px;
 | 
			
		||||
    padding-inline-start: 8px;
 | 
			
		||||
    padding-inline-end: initial;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import "@material/mwc-button";
 | 
			
		||||
import "@material/mwc-list/mwc-list-item";
 | 
			
		||||
 | 
			
		||||
import type { CSSResultGroup, TemplateResult } from "lit";
 | 
			
		||||
import { css, html, LitElement } from "lit";
 | 
			
		||||
import { customElement, property, state } from "lit/decorators";
 | 
			
		||||
@@ -197,9 +197,6 @@ class HassioCoreInfo extends LitElement {
 | 
			
		||||
          color: var(--secondary-text-color);
 | 
			
		||||
          --mdc-menu-min-width: 200px;
 | 
			
		||||
        }
 | 
			
		||||
        mwc-list-item ha-svg-icon {
 | 
			
		||||
          color: var(--secondary-text-color);
 | 
			
		||||
        }
 | 
			
		||||
        a {
 | 
			
		||||
          text-decoration: none;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import "@material/mwc-button";
 | 
			
		||||
import "@material/mwc-list/mwc-list-item";
 | 
			
		||||
 | 
			
		||||
import { mdiDotsVertical } from "@mdi/js";
 | 
			
		||||
import type { CSSResultGroup, TemplateResult } from "lit";
 | 
			
		||||
import { css, html, LitElement } from "lit";
 | 
			
		||||
@@ -10,6 +10,7 @@ import { fireEvent } from "../../../src/common/dom/fire_event";
 | 
			
		||||
import "../../../src/components/buttons/ha-progress-button";
 | 
			
		||||
import "../../../src/components/ha-button-menu";
 | 
			
		||||
import "../../../src/components/ha-card";
 | 
			
		||||
import "../../../src/components/ha-list-item";
 | 
			
		||||
import "../../../src/components/ha-icon-button";
 | 
			
		||||
import "../../../src/components/ha-settings-row";
 | 
			
		||||
import {
 | 
			
		||||
@@ -188,31 +189,31 @@ class HassioHostInfo extends LitElement {
 | 
			
		||||
              .path=${mdiDotsVertical}
 | 
			
		||||
              slot="trigger"
 | 
			
		||||
            ></ha-icon-button>
 | 
			
		||||
            <mwc-list-item
 | 
			
		||||
            <ha-list-item
 | 
			
		||||
              .action=${"hardware"}
 | 
			
		||||
              @click=${this._handleMenuAction}
 | 
			
		||||
            >
 | 
			
		||||
              ${this.supervisor.localize("system.host.hardware")}
 | 
			
		||||
            </mwc-list-item>
 | 
			
		||||
            </ha-list-item>
 | 
			
		||||
            ${this.supervisor.host.features.includes("haos")
 | 
			
		||||
              ? html`
 | 
			
		||||
                  <mwc-list-item
 | 
			
		||||
                  <ha-list-item
 | 
			
		||||
                    .action=${"import_from_usb"}
 | 
			
		||||
                    @click=${this._handleMenuAction}
 | 
			
		||||
                  >
 | 
			
		||||
                    ${this.supervisor.localize("system.host.import_from_usb")}
 | 
			
		||||
                  </mwc-list-item>
 | 
			
		||||
                  </ha-list-item>
 | 
			
		||||
                  ${this.supervisor.host.features.includes("os_agent") &&
 | 
			
		||||
                  atLeastVersion(this.supervisor.host.agent_version, 1, 2, 0)
 | 
			
		||||
                    ? html`
 | 
			
		||||
                        <mwc-list-item
 | 
			
		||||
                        <ha-list-item
 | 
			
		||||
                          .action=${"move_datadisk"}
 | 
			
		||||
                          @click=${this._handleMenuAction}
 | 
			
		||||
                        >
 | 
			
		||||
                          ${this.supervisor.localize(
 | 
			
		||||
                            "system.host.move_datadisk"
 | 
			
		||||
                          )}
 | 
			
		||||
                        </mwc-list-item>
 | 
			
		||||
                        </ha-list-item>
 | 
			
		||||
                      `
 | 
			
		||||
                    : ""}
 | 
			
		||||
                `
 | 
			
		||||
@@ -438,7 +439,7 @@ class HassioHostInfo extends LitElement {
 | 
			
		||||
          color: var(--secondary-text-color);
 | 
			
		||||
          --mdc-menu-min-width: 200px;
 | 
			
		||||
        }
 | 
			
		||||
        mwc-list-item ha-svg-icon {
 | 
			
		||||
        ha-list-item ha-svg-icon {
 | 
			
		||||
          color: var(--secondary-text-color);
 | 
			
		||||
        }
 | 
			
		||||
        a {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import "@material/mwc-button";
 | 
			
		||||
import "@material/mwc-list/mwc-list-item";
 | 
			
		||||
 | 
			
		||||
import type { CSSResultGroup, TemplateResult } from "lit";
 | 
			
		||||
import { css, html, LitElement } from "lit";
 | 
			
		||||
import { customElement, property, state } from "lit/decorators";
 | 
			
		||||
@@ -8,6 +8,7 @@ import "../../../src/components/ha-alert";
 | 
			
		||||
import "../../../src/components/ha-ansi-to-html";
 | 
			
		||||
import "../../../src/components/ha-card";
 | 
			
		||||
import "../../../src/components/ha-select";
 | 
			
		||||
import "../../../src/components/ha-list-item";
 | 
			
		||||
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
 | 
			
		||||
import { fetchHassioLogs } from "../../../src/data/hassio/supervisor";
 | 
			
		||||
import type { Supervisor } from "../../../src/data/supervisor/supervisor";
 | 
			
		||||
@@ -80,9 +81,9 @@ class HassioSupervisorLog extends LitElement {
 | 
			
		||||
              >
 | 
			
		||||
                ${logProviders.map(
 | 
			
		||||
                  (provider) => html`
 | 
			
		||||
                    <mwc-list-item .value=${provider.key}>
 | 
			
		||||
                    <ha-list-item .value=${provider.key}>
 | 
			
		||||
                      ${provider.name}
 | 
			
		||||
                    </mwc-list-item>
 | 
			
		||||
                    </ha-list-item>
 | 
			
		||||
                  `
 | 
			
		||||
                )}
 | 
			
		||||
              </ha-select>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
import "@material/mwc-list/mwc-list-item";
 | 
			
		||||
import {
 | 
			
		||||
  css,
 | 
			
		||||
  type CSSResultGroup,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,3 @@
 | 
			
		||||
import "./ha-landing-page";
 | 
			
		||||
 | 
			
		||||
import("../../src/resources/ha-style");
 | 
			
		||||
import("../../src/resources/append-ha-style");
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user